forked from teamnwah/openmw-tes3coop
- Add some updated files missing from last commit.
- Move plugin dependency test from esmreader.cpp to esmstpre.cpp; fixes crash in omwlauncher.
This commit is contained in:
parent
8ea9f00e6f
commit
896ab44d1e
9 changed files with 102 additions and 66 deletions
|
@ -34,7 +34,7 @@ add_openmw_dir (mwgui
|
|||
)
|
||||
|
||||
add_openmw_dir (mwdialogue
|
||||
dialoguemanagerimp journalimp journalentry quest topic
|
||||
dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper
|
||||
)
|
||||
|
||||
add_openmw_dir (mwscript
|
||||
|
@ -50,9 +50,10 @@ add_openmw_dir (mwsound
|
|||
|
||||
add_openmw_dir (mwworld
|
||||
refdata worldimp physicssystem scene globals class action nullaction actionteleport
|
||||
containerstore actiontalk actiontake manualref player cellfunctors
|
||||
containerstore actiontalk actiontake manualref player cellfunctors failedaction
|
||||
cells localscripts customdata weather inventorystore ptr actionopen actionread
|
||||
actionequip timestamp actionalchemy cellstore actionapply actioneat
|
||||
esmstore store recordcmp
|
||||
)
|
||||
|
||||
add_openmw_dir (mwclass
|
||||
|
@ -62,7 +63,7 @@ add_openmw_dir (mwclass
|
|||
|
||||
add_openmw_dir (mwmechanics
|
||||
mechanicsmanagerimp stat creaturestats magiceffects movement actors drawstate spells
|
||||
activespells npcstats aipackage aisequence alchemy
|
||||
activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow aiescort aiactivate
|
||||
)
|
||||
|
||||
add_openmw_dir (mwbase
|
||||
|
|
|
@ -221,7 +221,7 @@ namespace MWRender
|
|||
//
|
||||
//If we don't sort the ltex indexes, the splatting order may differ between
|
||||
//cells which may lead to inconsistent results when shading between cells
|
||||
int num = MWBase::Environment::get().getWorld()->getStore().landTexts.getSizePlugin(plugin);
|
||||
int num = MWBase::Environment::get().getWorld()->getStore().get<ESM::LandTexture>().getSize(plugin);
|
||||
std::set<uint16_t> ltexIndexes;
|
||||
for ( int y = fromY - 1; y < fromY + size + 1; y++ )
|
||||
{
|
||||
|
|
|
@ -49,10 +49,10 @@ namespace MWWorld
|
|||
return; // this is a dynamically generated cell -> skipping.
|
||||
|
||||
// Load references from all plugins that do something with this cell.
|
||||
for (size_t i = 0; i < cell->mContextList.size(); i++)
|
||||
for (size_t i = 0; i < mCell->mContextList.size(); i++)
|
||||
{
|
||||
// Reopen the ESM reader and seek to the right position.
|
||||
int index = cell->mContextList.at(i).index;
|
||||
int index = mCell->mContextList.at(i).index;
|
||||
mCell->restore (esm[index], i);
|
||||
|
||||
ESM::CellRef ref;
|
||||
|
@ -81,10 +81,10 @@ namespace MWWorld
|
|||
return; // this is a dynamically generated cell -> skipping.
|
||||
|
||||
// Load references from all plugins that do something with this cell.
|
||||
for (size_t i = 0; i < cell->mContextList.size(); i++)
|
||||
for (size_t i = 0; i < mCell->mContextList.size(); i++)
|
||||
{
|
||||
// Reopen the ESM reader and seek to the right position.
|
||||
int index = cell->mContextList.at(i).index;
|
||||
int index = mCell->mContextList.at(i).index;
|
||||
mCell->restore (esm[index], i);
|
||||
|
||||
ESM::CellRef ref;
|
||||
|
|
|
@ -49,26 +49,32 @@ namespace MWWorld
|
|||
{
|
||||
typedef LiveCellRef<X> LiveRef;
|
||||
typedef std::map<int,LiveRef> List;
|
||||
List list;
|
||||
List mList;
|
||||
|
||||
// Search for the given reference in the given reclist from
|
||||
// ESMStore. Insert the reference into the list if a match is
|
||||
// found. If not, throw an exception.
|
||||
template <typename Y>
|
||||
void find(ESM::CellRef &ref, const Y& recList)
|
||||
/// Searches for reference of appropriate type in given ESMStore.
|
||||
/// If reference exists, loads it into container, throws an exception
|
||||
/// on miss
|
||||
void load(ESM::CellRef &ref, const MWWorld::ESMStore &esmStore)
|
||||
{
|
||||
const X* obj = recList.find(ref.mRefID);
|
||||
if(obj == NULL)
|
||||
throw std::runtime_error("Error resolving cell reference " + ref.mRefID);
|
||||
// for throwing exception on unhandled record type
|
||||
const MWWorld::Store<X> &store = esmStore.get<X>();
|
||||
const X *ptr = store.find(ref.mRefID);
|
||||
|
||||
list[ref.mRefnum] = LiveRef(ref, obj);
|
||||
/// \note redundant because Store<X>::find() throws exception on miss
|
||||
if (ptr == NULL) {
|
||||
throw std::runtime_error("Error resolving cell reference " + ref.mRefID);
|
||||
}
|
||||
mList[ref.mRefnum] = LiveRef(ref, ptr);
|
||||
}
|
||||
|
||||
LiveRef *find (const std::string& name)
|
||||
{
|
||||
for (typename std::map<int,LiveRef>::iterator iter (list.begin()); iter!=list.end(); ++iter)
|
||||
for (typename std::map<int,LiveRef>::iterator iter (mList.begin()); iter!=mList.end(); ++iter)
|
||||
{
|
||||
if (iter->second.mData.getCount() > 0 && iter->second.ref.mRefID == name)
|
||||
if (iter->second.mData.getCount() > 0 && iter->second.mRef.mRefID == name)
|
||||
return &iter->second;
|
||||
}
|
||||
|
||||
|
@ -76,8 +82,8 @@ namespace MWWorld
|
|||
}
|
||||
|
||||
LiveRef &insert(const LiveRef &item) {
|
||||
list[item.ref.mRefnum] = item;
|
||||
return list[item.ref.mRefnum];
|
||||
mList[item.mRef.mRefnum] = item;
|
||||
return mList[item.mRef.mRefnum];
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include <set>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/filesystem/v3/operations.hpp>
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
|
||||
|
@ -25,6 +27,33 @@ void ESMStore::load(ESM::ESMReader &esm)
|
|||
|
||||
ESM::Dialogue *dialogue = 0;
|
||||
|
||||
// Cache parent esX files by tracking their indices in the global list of
|
||||
// all files/readers used by the engine. This will greaty help to accelerate
|
||||
// parsing of reference IDs.
|
||||
size_t index = ~0;
|
||||
const ESM::ESMReader::MasterList &masters = esm.getMasters();
|
||||
std::vector<ESM::ESMReader> *allPlugins = esm.getGlobalReaderList();
|
||||
for (size_t j = 0; j < masters.size(); j++) {
|
||||
ESM::MasterData &mast = const_cast<ESM::MasterData&>(masters[j]);
|
||||
std::string fname = mast.name;
|
||||
for (size_t 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 == (size_t)~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 " + fname + " 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())
|
||||
{
|
||||
|
|
|
@ -219,24 +219,31 @@ namespace MWWorld
|
|||
template <>
|
||||
class Store<ESM::LandTexture> : public StoreBase
|
||||
{
|
||||
std::vector<ESM::LandTexture> mStatic;
|
||||
// For multiple ESM/ESP files we need one list per file.
|
||||
typedef std::vector<ESM::LandTexture> LandTextureList;
|
||||
std::vector<LandTextureList> mStatic;
|
||||
|
||||
public:
|
||||
Store<ESM::LandTexture>() {
|
||||
mStatic.reserve(128);
|
||||
mStatic.push_back(LandTextureList());
|
||||
LandTextureList <exl = mStatic[0];
|
||||
// More than enough to hold Morrowind.esm. Extra lists for plugins will we
|
||||
// added on-the-fly in a different method.
|
||||
ltexl.reserve(128);
|
||||
}
|
||||
|
||||
typedef std::vector<ESM::LandTexture>::const_iterator iterator;
|
||||
|
||||
const ESM::LandTexture *search(size_t index) const {
|
||||
if (index < mStatic.size()) {
|
||||
return &mStatic.at(index);
|
||||
}
|
||||
return 0;
|
||||
const ESM::LandTexture *search(size_t index, size_t plugin) const {
|
||||
assert(plugin < mStatic.size());
|
||||
const LandTextureList <exl = mStatic[plugin];
|
||||
|
||||
assert(index < ltexl.size());
|
||||
return <exl.at(index);
|
||||
}
|
||||
|
||||
const ESM::LandTexture *find(size_t index) const {
|
||||
const ESM::LandTexture *ptr = search(index);
|
||||
const ESM::LandTexture *find(size_t index, size_t plugin) const {
|
||||
const ESM::LandTexture *ptr = search(index, plugin);
|
||||
if (ptr == 0) {
|
||||
std::ostringstream msg;
|
||||
msg << "Land texture with index " << index << " not found";
|
||||
|
@ -249,23 +256,40 @@ namespace MWWorld
|
|||
return mStatic.size();
|
||||
}
|
||||
|
||||
void load(ESM::ESMReader &esm, const std::string &id) {
|
||||
ESM::LandTexture ltex;
|
||||
ltex.load(esm);
|
||||
int getSize(size_t plugin) const {
|
||||
assert(plugin < mStatic.size());
|
||||
return mStatic[plugin].size();
|
||||
}
|
||||
|
||||
if (ltex.mIndex >= (int) mStatic.size()) {
|
||||
mStatic.resize(ltex.mIndex + 1);
|
||||
void load(ESM::ESMReader &esm, const std::string &id, size_t plugin) {
|
||||
ESM::LandTexture lt;
|
||||
lt.load(esm);
|
||||
lt.mId = id;
|
||||
|
||||
// Make sure we have room for the structure
|
||||
if (plugin >= mStatic.size()) {
|
||||
mStatic.resize(plugin+1);
|
||||
}
|
||||
mStatic[ltex.mIndex] = ltex;
|
||||
mStatic[ltex.mIndex].mId = id;
|
||||
LandTextureList <exl = mStatic[plugin];
|
||||
if(lt.mIndex + 1 > (int)ltexl.size())
|
||||
ltexl.resize(lt.mIndex+1);
|
||||
|
||||
// Store it
|
||||
ltexl[lt.mIndex] = lt;
|
||||
}
|
||||
|
||||
iterator begin() const {
|
||||
return mStatic.begin();
|
||||
void load(ESM::ESMReader &esm, const std::string &id) {
|
||||
load(esm, id, esm.getIndex());
|
||||
}
|
||||
|
||||
iterator end() const {
|
||||
return mStatic.end();
|
||||
iterator begin(size_t plugin) const {
|
||||
assert(plugin < mStatic.size());
|
||||
return mStatic[plugin].begin();
|
||||
}
|
||||
|
||||
iterator end(size_t plugin) const {
|
||||
assert(plugin < mStatic.size());
|
||||
return mStatic[plugin].end();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1081,8 +1081,8 @@ namespace MWWorld
|
|||
std::vector<World::DoorMarker> result;
|
||||
|
||||
MWWorld::CellRefList<ESM::Door>& doors = cell->mDoors;
|
||||
std::map< MWWorld::LiveCellRef<ESM::Door> >& refList = doors.mList;
|
||||
for (std::map<int, MWWorld::LiveCellRef<ESM::Door> >::iterator it = refList.begin(); it != refList.end(); ++it)
|
||||
CellRefList<ESM::Door>::List& refList = doors.mList;
|
||||
for (CellRefList<ESM::Door>::List::iterator it = refList.begin(); it != refList.end(); ++it)
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Door>& ref = it->second;
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "esmreader.hpp"
|
||||
#include <stdexcept>
|
||||
#include <boost/filesystem/v3/operations.hpp>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
@ -62,7 +61,6 @@ void ESMReader::openRaw(Ogre::DataStreamPtr _esm, const std::string &name)
|
|||
void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name)
|
||||
{
|
||||
openRaw(_esm, name);
|
||||
std::string fname = boost::filesystem::path(name).filename().string();
|
||||
|
||||
if (getRecName() != "TES3")
|
||||
fail("Not a valid Morrowind file");
|
||||
|
@ -80,29 +78,6 @@ void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name)
|
|||
MasterData m;
|
||||
m.name = getHString();
|
||||
m.size = getHNLong("DATA");
|
||||
// Cache parent esX files by tracking their indices in the global list of
|
||||
// all files/readers used by the engine. This will greaty help to accelerate
|
||||
// parsing of reference IDs.
|
||||
size_t index = ~0;
|
||||
// TODO: check for case mismatch, it might be required on Windows.
|
||||
size_t i = 0;
|
||||
// FIXME: This is ugly! Make it nicer!
|
||||
for (; i < idx; i++) {
|
||||
const std::string &candidate = mGlobalReaderList->at(i).getContext().filename;
|
||||
std::string fnamecandidate = boost::filesystem::path(candidate).filename().string();
|
||||
if (m.name == fnamecandidate) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == (size_t)~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 " + fname + " asks for parent file " + m.name
|
||||
+ ", but it has not been loaded yet. Please check your load order.";
|
||||
fail(fstring);
|
||||
}
|
||||
m.index = index;
|
||||
mMasters.push_back(m);
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ public:
|
|||
const int getIndex() {return idx;}
|
||||
|
||||
void setGlobalReaderList(std::vector<ESMReader> *list) {mGlobalReaderList = list;}
|
||||
std::vector<ESMReader> *getGlobalReaderList() {return mGlobalReaderList;}
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue