mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-29 03:36:40 +00:00
Mark only instances from groundcover files as groundcover objects
This commit is contained in:
parent
8874e88ff1
commit
d12a0fdcb3
16 changed files with 51 additions and 77 deletions
|
@ -13,6 +13,17 @@
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
|
std::string getGroundcoverModel(int type, const std::string& id, const MWWorld::ESMStore& store)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case ESM::REC_STAT:
|
||||||
|
return store.get<ESM::Static>().searchStatic(id)->mModel;
|
||||||
|
default:
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GroundcoverUpdater::setWindSpeed(float windSpeed)
|
void GroundcoverUpdater::setWindSpeed(float windSpeed)
|
||||||
{
|
{
|
||||||
mWindSpeed = windSpeed;
|
mWindSpeed = windSpeed;
|
||||||
|
@ -217,15 +228,17 @@ namespace MWRender
|
||||||
while(cell->getNextRef(esm[index], ref, deleted))
|
while(cell->getNextRef(esm[index], ref, deleted))
|
||||||
{
|
{
|
||||||
if (deleted) continue;
|
if (deleted) continue;
|
||||||
Misc::StringUtils::lowerCaseInPlace(ref.mRefID);
|
if (!ref.mRefNum.fromGroundcoverFile()) continue;
|
||||||
std::string model;
|
|
||||||
if (!store.isGroundcover(ref.mRefID, model)) continue;
|
|
||||||
if (model.empty()) continue;
|
|
||||||
|
|
||||||
if (!calculator.isInstanceEnabled()) continue;
|
if (!calculator.isInstanceEnabled()) continue;
|
||||||
if (!isInChunkBorders(ref, minBound, maxBound)) continue;
|
if (!isInChunkBorders(ref, minBound, maxBound)) continue;
|
||||||
|
|
||||||
|
Misc::StringUtils::lowerCaseInPlace(ref.mRefID);
|
||||||
|
int type = store.findStatic(ref.mRefID);
|
||||||
|
std::string model = getGroundcoverModel(type, ref.mRefID, store);
|
||||||
|
if (model.empty()) continue;
|
||||||
model = "meshes/" + model;
|
model = "meshes/" + model;
|
||||||
|
|
||||||
instances[model].emplace_back(ref, model);
|
instances[model].emplace_back(ref, model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,7 +373,6 @@ namespace MWRender
|
||||||
std::map<ESM::RefNum, ESM::CellRef> refs;
|
std::map<ESM::RefNum, ESM::CellRef> refs;
|
||||||
std::vector<ESM::ESMReader> esm;
|
std::vector<ESM::ESMReader> esm;
|
||||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
for (int cellX = startCell.x(); cellX < startCell.x() + size; ++cellX)
|
for (int cellX = startCell.x(); cellX < startCell.x() + size; ++cellX)
|
||||||
{
|
{
|
||||||
for (int cellY = startCell.y(); cellY < startCell.y() + size; ++cellY)
|
for (int cellY = startCell.y(); cellY < startCell.y() + size; ++cellY)
|
||||||
|
@ -398,7 +397,7 @@ namespace MWRender
|
||||||
int type = store.findStatic(ref.mRefID);
|
int type = store.findStatic(ref.mRefID);
|
||||||
if (!typeFilter(type,size>=2)) continue;
|
if (!typeFilter(type,size>=2)) continue;
|
||||||
if (deleted) { refs.erase(ref.mRefNum); continue; }
|
if (deleted) { refs.erase(ref.mRefNum); continue; }
|
||||||
if (store.isGroundcover(ref.mRefID)) continue;
|
if (ref.mRefNum.fromGroundcoverFile()) continue;
|
||||||
refs[ref.mRefNum] = ref;
|
refs[ref.mRefNum] = ref;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "cellpreloader.hpp"
|
#include "cellpreloader.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
@ -36,12 +37,7 @@ namespace MWWorld
|
||||||
|
|
||||||
virtual bool operator()(const MWWorld::Ptr& ptr)
|
virtual bool operator()(const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
if (ptr.getTypeName()==typeid (ESM::Static).name())
|
if (ptr.getCellRef().getRefNum().fromGroundcoverFile()) return true;
|
||||||
{
|
|
||||||
const MWWorld::LiveCellRef<ESM::Static> *ref = ptr.get<ESM::Static>();
|
|
||||||
if (ref->mBase->mIsGroundcover)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr.getClass().getModelsToPreload(ptr, mOut);
|
ptr.getClass().getModelsToPreload(ptr, mOut);
|
||||||
|
|
||||||
|
|
|
@ -169,18 +169,6 @@ namespace
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
template <typename X>
|
|
||||||
bool CellRefList<X>::ignoreInstance (const X* ptr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
bool CellRefList<ESM::Static>::ignoreInstance (const ESM::Static* ptr)
|
|
||||||
{
|
|
||||||
return ptr->mIsGroundcover;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename X>
|
template <typename X>
|
||||||
void CellRefList<X>::load(ESM::CellRef &ref, bool deleted, const MWWorld::ESMStore &esmStore)
|
void CellRefList<X>::load(ESM::CellRef &ref, bool deleted, const MWWorld::ESMStore &esmStore)
|
||||||
{
|
{
|
||||||
|
@ -188,8 +176,6 @@ namespace MWWorld
|
||||||
|
|
||||||
if (const X *ptr = store.search (ref.mRefID))
|
if (const X *ptr = store.search (ref.mRefID))
|
||||||
{
|
{
|
||||||
if (ignoreInstance(ptr)) return;
|
|
||||||
|
|
||||||
typename std::list<LiveRef>::iterator iter =
|
typename std::list<LiveRef>::iterator iter =
|
||||||
std::find(mList.begin(), mList.end(), ref.mRefNum);
|
std::find(mList.begin(), mList.end(), ref.mRefNum);
|
||||||
|
|
||||||
|
@ -700,7 +686,11 @@ namespace MWWorld
|
||||||
case ESM::REC_NPC_: mNpcs.load(ref, deleted, store); break;
|
case ESM::REC_NPC_: mNpcs.load(ref, deleted, store); break;
|
||||||
case ESM::REC_PROB: mProbes.load(ref, deleted, store); break;
|
case ESM::REC_PROB: mProbes.load(ref, deleted, store); break;
|
||||||
case ESM::REC_REPA: mRepairs.load(ref, deleted, store); break;
|
case ESM::REC_REPA: mRepairs.load(ref, deleted, store); break;
|
||||||
case ESM::REC_STAT: mStatics.load(ref, deleted, store); break;
|
case ESM::REC_STAT:
|
||||||
|
{
|
||||||
|
if (ref.mRefNum.fromGroundcoverFile()) return;
|
||||||
|
mStatics.load(ref, deleted, store); break;
|
||||||
|
}
|
||||||
case ESM::REC_WEAP: mWeapons.load(ref, deleted, store); break;
|
case ESM::REC_WEAP: mWeapons.load(ref, deleted, store); break;
|
||||||
case ESM::REC_BODY: mBodyParts.load(ref, deleted, store); break;
|
case ESM::REC_BODY: mBodyParts.load(ref, deleted, store); break;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ struct ContentLoader
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void load(const boost::filesystem::path& filepath, int& index, bool isGroundcover)
|
virtual void load(const boost::filesystem::path& filepath, int& index)
|
||||||
{
|
{
|
||||||
Log(Debug::Info) << "Loading content file " << filepath.string();
|
Log(Debug::Info) << "Loading content file " << filepath.string();
|
||||||
mListener.setLabel(MyGUI::TextIterator::toTagsString(filepath.string()));
|
mListener.setLabel(MyGUI::TextIterator::toTagsString(filepath.string()));
|
||||||
|
|
|
@ -15,15 +15,15 @@ EsmLoader::EsmLoader(MWWorld::ESMStore& store, std::vector<ESM::ESMReader>& read
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void EsmLoader::load(const boost::filesystem::path& filepath, int& index, bool isGroundcover)
|
void EsmLoader::load(const boost::filesystem::path& filepath, int& index)
|
||||||
{
|
{
|
||||||
ContentLoader::load(filepath.filename(), index, isGroundcover);
|
ContentLoader::load(filepath.filename(), index);
|
||||||
|
|
||||||
ESM::ESMReader lEsm;
|
ESM::ESMReader lEsm;
|
||||||
lEsm.setEncoder(mEncoder);
|
lEsm.setEncoder(mEncoder);
|
||||||
lEsm.setIndex(index);
|
lEsm.setIndex(index);
|
||||||
lEsm.setGlobalReaderList(&mEsm);
|
lEsm.setGlobalReaderList(&mEsm);
|
||||||
lEsm.open(filepath.string(), isGroundcover);
|
lEsm.open(filepath.string());
|
||||||
mEsm[index] = lEsm;
|
mEsm[index] = lEsm;
|
||||||
mStore.load(mEsm[index], &mListener);
|
mStore.load(mEsm[index], &mListener);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ struct EsmLoader : public ContentLoader
|
||||||
EsmLoader(MWWorld::ESMStore& store, std::vector<ESM::ESMReader>& readers,
|
EsmLoader(MWWorld::ESMStore& store, std::vector<ESM::ESMReader>& readers,
|
||||||
ToUTF8::Utf8Encoder* encoder, Loading::Listener& listener);
|
ToUTF8::Utf8Encoder* encoder, Loading::Listener& listener);
|
||||||
|
|
||||||
void load(const boost::filesystem::path& filepath, int& index, bool isGroundcover) override;
|
void load(const boost::filesystem::path& filepath, int& index) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<ESM::ESMReader>& mEsm;
|
std::vector<ESM::ESMReader>& mEsm;
|
||||||
|
|
|
@ -190,15 +190,6 @@ void ESMStore::setUp(bool validateRecords)
|
||||||
{
|
{
|
||||||
validate();
|
validate();
|
||||||
countRecords();
|
countRecords();
|
||||||
|
|
||||||
if (mGroundcovers.empty())
|
|
||||||
{
|
|
||||||
for (const ESM::Static& record : mStatics)
|
|
||||||
{
|
|
||||||
if (record.mIsGroundcover)
|
|
||||||
mGroundcovers[record.mId] = record.mModel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,6 @@ namespace MWWorld
|
||||||
// maps the id name to the record type.
|
// maps the id name to the record type.
|
||||||
std::map<std::string, int> mIds;
|
std::map<std::string, int> mIds;
|
||||||
std::map<std::string, int> mStaticIds;
|
std::map<std::string, int> mStaticIds;
|
||||||
std::map<std::string, std::string> mGroundcovers;
|
|
||||||
|
|
||||||
std::map<std::string, int> mRefCount;
|
std::map<std::string, int> mRefCount;
|
||||||
|
|
||||||
|
@ -122,22 +121,6 @@ namespace MWWorld
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isGroundcover(const std::string &id, std::string &model) const
|
|
||||||
{
|
|
||||||
std::map<std::string, std::string>::const_iterator it = mGroundcovers.find(id);
|
|
||||||
if (it == mGroundcovers.end()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
model = it->second;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isGroundcover(const std::string &id) const
|
|
||||||
{
|
|
||||||
std::map<std::string, std::string>::const_iterator it = mGroundcovers.find(id);
|
|
||||||
return (it != mGroundcovers.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
ESMStore()
|
ESMStore()
|
||||||
: mDynamicCount(0)
|
: mDynamicCount(0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -103,12 +103,12 @@ namespace MWWorld
|
||||||
return mLoaders.insert(std::make_pair(extension, loader)).second;
|
return mLoaders.insert(std::make_pair(extension, loader)).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(const boost::filesystem::path& filepath, int& index, bool isGroundcover) override
|
void load(const boost::filesystem::path& filepath, int& index) override
|
||||||
{
|
{
|
||||||
LoadersContainer::iterator it(mLoaders.find(Misc::StringUtils::lowerCase(filepath.extension().string())));
|
LoadersContainer::iterator it(mLoaders.find(Misc::StringUtils::lowerCase(filepath.extension().string())));
|
||||||
if (it != mLoaders.end())
|
if (it != mLoaders.end())
|
||||||
{
|
{
|
||||||
it->second->load(filepath, index, isGroundcover);
|
it->second->load(filepath, index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2951,7 +2951,7 @@ namespace MWWorld
|
||||||
const Files::MultiDirCollection& col = fileCollections.getCollection(filename.extension().string());
|
const Files::MultiDirCollection& col = fileCollections.getCollection(filename.extension().string());
|
||||||
if (col.doesExist(file))
|
if (col.doesExist(file))
|
||||||
{
|
{
|
||||||
contentLoader.load(col.getPath(file), idx, false);
|
contentLoader.load(col.getPath(file), idx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2961,13 +2961,15 @@ namespace MWWorld
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ESM::GroundcoverIndex = idx;
|
||||||
|
|
||||||
for (const std::string &file : groundcover)
|
for (const std::string &file : groundcover)
|
||||||
{
|
{
|
||||||
boost::filesystem::path filename(file);
|
boost::filesystem::path filename(file);
|
||||||
const Files::MultiDirCollection& col = fileCollections.getCollection(filename.extension().string());
|
const Files::MultiDirCollection& col = fileCollections.getCollection(filename.extension().string());
|
||||||
if (col.doesExist(file))
|
if (col.doesExist(file))
|
||||||
{
|
{
|
||||||
contentLoader.load(col.getPath(file), idx, true);
|
contentLoader.load(col.getPath(file), idx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
#include "esmreader.hpp"
|
#include "esmreader.hpp"
|
||||||
#include "esmwriter.hpp"
|
#include "esmwriter.hpp"
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
int GroundcoverIndex = std::numeric_limits<int>::max();
|
||||||
|
}
|
||||||
|
|
||||||
void ESM::RefNum::load (ESMReader& esm, bool wide, const std::string& tag)
|
void ESM::RefNum::load (ESMReader& esm, bool wide, const std::string& tag)
|
||||||
{
|
{
|
||||||
if (wide)
|
if (wide)
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace ESM
|
||||||
class ESMReader;
|
class ESMReader;
|
||||||
|
|
||||||
const int UnbreakableLock = std::numeric_limits<int>::max();
|
const int UnbreakableLock = std::numeric_limits<int>::max();
|
||||||
|
extern int GroundcoverIndex;
|
||||||
|
|
||||||
struct RefNum
|
struct RefNum
|
||||||
{
|
{
|
||||||
|
@ -25,6 +26,10 @@ namespace ESM
|
||||||
enum { RefNum_NoContentFile = -1 };
|
enum { RefNum_NoContentFile = -1 };
|
||||||
inline bool hasContentFile() const { return mContentFile != RefNum_NoContentFile; }
|
inline bool hasContentFile() const { return mContentFile != RefNum_NoContentFile; }
|
||||||
inline void unset() { mIndex = 0; mContentFile = RefNum_NoContentFile; }
|
inline void unset() { mIndex = 0; mContentFile = RefNum_NoContentFile; }
|
||||||
|
|
||||||
|
// Note: this method should not be used for objects with invalid RefNum
|
||||||
|
// (for example, for objects from disabled plugins in savegames).
|
||||||
|
inline bool fromGroundcoverFile() const { return mContentFile >= GroundcoverIndex; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Cell reference. This represents ONE object (of many) inside the
|
/* Cell reference. This represents ONE object (of many) inside the
|
||||||
|
|
|
@ -25,7 +25,6 @@ ESMReader::ESMReader()
|
||||||
, mGlobalReaderList(nullptr)
|
, mGlobalReaderList(nullptr)
|
||||||
, mEncoder(nullptr)
|
, mEncoder(nullptr)
|
||||||
, mFileSize(0)
|
, mFileSize(0)
|
||||||
, mIsGroundcoverFile(false)
|
|
||||||
{
|
{
|
||||||
clearCtx();
|
clearCtx();
|
||||||
}
|
}
|
||||||
|
@ -81,10 +80,8 @@ void ESMReader::openRaw(const std::string& filename)
|
||||||
openRaw(Files::openConstrainedFileStream(filename.c_str()), filename);
|
openRaw(Files::openConstrainedFileStream(filename.c_str()), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESMReader::open(Files::IStreamPtr _esm, const std::string &name, bool isGroundcover)
|
void ESMReader::open(Files::IStreamPtr _esm, const std::string &name)
|
||||||
{
|
{
|
||||||
mIsGroundcoverFile = isGroundcover;
|
|
||||||
|
|
||||||
openRaw(_esm, name);
|
openRaw(_esm, name);
|
||||||
|
|
||||||
if (getRecName() != "TES3")
|
if (getRecName() != "TES3")
|
||||||
|
@ -95,9 +92,9 @@ void ESMReader::open(Files::IStreamPtr _esm, const std::string &name, bool isGro
|
||||||
mHeader.load (*this);
|
mHeader.load (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESMReader::open(const std::string &file, bool isGroundcover)
|
void ESMReader::open(const std::string &file)
|
||||||
{
|
{
|
||||||
open (Files::openConstrainedFileStream (file.c_str ()), file, isGroundcover);
|
open (Files::openConstrainedFileStream (file.c_str ()), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t ESMReader::getHNLong(const char *name)
|
int64_t ESMReader::getHNLong(const char *name)
|
||||||
|
|
|
@ -31,7 +31,6 @@ public:
|
||||||
|
|
||||||
int getVer() const { return mHeader.mData.version; }
|
int getVer() const { return mHeader.mData.version; }
|
||||||
int getRecordCount() const { return mHeader.mData.records; }
|
int getRecordCount() const { return mHeader.mData.records; }
|
||||||
bool isGroundcoverFile() const { return mIsGroundcoverFile; }
|
|
||||||
float getFVer() const { return (mHeader.mData.version == VER_12) ? 1.2f : 1.3f; }
|
float getFVer() const { return (mHeader.mData.version == VER_12) ? 1.2f : 1.3f; }
|
||||||
const std::string getAuthor() const { return mHeader.mData.author; }
|
const std::string getAuthor() const { return mHeader.mData.author; }
|
||||||
const std::string getDesc() const { return mHeader.mData.desc; }
|
const std::string getDesc() const { return mHeader.mData.desc; }
|
||||||
|
@ -67,9 +66,9 @@ public:
|
||||||
|
|
||||||
/// Load ES file from a new stream, parses the header. Closes the
|
/// Load ES file from a new stream, parses the header. Closes the
|
||||||
/// currently open file first, if any.
|
/// currently open file first, if any.
|
||||||
void open(Files::IStreamPtr _esm, const std::string &name, bool isGroundcover = false);
|
void open(Files::IStreamPtr _esm, const std::string &name);
|
||||||
|
|
||||||
void open(const std::string &file, bool isGroundcover = false);
|
void open(const std::string &file);
|
||||||
|
|
||||||
void openRaw(const std::string &filename);
|
void openRaw(const std::string &filename);
|
||||||
|
|
||||||
|
@ -290,8 +289,6 @@ private:
|
||||||
ToUTF8::Utf8Encoder* mEncoder;
|
ToUTF8::Utf8Encoder* mEncoder;
|
||||||
|
|
||||||
size_t mFileSize;
|
size_t mFileSize;
|
||||||
|
|
||||||
bool mIsGroundcoverFile;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,8 +37,6 @@ namespace ESM
|
||||||
|
|
||||||
if (!hasName)
|
if (!hasName)
|
||||||
esm.fail("Missing NAME subrecord");
|
esm.fail("Missing NAME subrecord");
|
||||||
|
|
||||||
mIsGroundcover = esm.isGroundcoverFile();
|
|
||||||
}
|
}
|
||||||
void Static::save(ESMWriter &esm, bool isDeleted) const
|
void Static::save(ESMWriter &esm, bool isDeleted) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,8 +28,6 @@ struct Static
|
||||||
|
|
||||||
std::string mId, mModel;
|
std::string mId, mModel;
|
||||||
|
|
||||||
bool mIsGroundcover = false;
|
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
void save(ESMWriter &esm, bool isDeleted = false) const;
|
void save(ESMWriter &esm, bool isDeleted = false) const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue