mirror of
https://github.com/OpenMW/openmw.git
synced 2025-04-01 10:36:39 +00:00
Fixes a crash on launch and some compile issue
also uses std::visit in cellstore comparison to avoid missing combinasion split loadrefs in loadref of ESM4 and ESM3.
This commit is contained in:
parent
cb8cdd8831
commit
5037dcf9bc
7 changed files with 92 additions and 85 deletions
|
@ -104,9 +104,10 @@ namespace MWMechanics
|
||||||
if (mIsGraphConstructed)
|
if (mIsGraphConstructed)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
mCell = cell->getCell()->isEsm4() ? nullptr : &cell->getCell()->getEsm3();
|
if (cell->getCell()->isEsm4())
|
||||||
if (!mCell)
|
|
||||||
return false;
|
return false;
|
||||||
|
mCell = &cell->getCell()->getEsm3();
|
||||||
|
|
||||||
mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*mCell);
|
mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*mCell);
|
||||||
if (!mPathgrid)
|
if (!mPathgrid)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -37,7 +37,6 @@ namespace MWWorld
|
||||||
Cell::Cell(const ESM::Cell& cell)
|
Cell::Cell(const ESM::Cell& cell)
|
||||||
: ESM::CellVariant(cell)
|
: ESM::CellVariant(cell)
|
||||||
{
|
{
|
||||||
assert(cell != nullptr);
|
|
||||||
mNameID = cell.mName;
|
mNameID = cell.mName;
|
||||||
mDisplayname = cell.mName;
|
mDisplayname = cell.mName;
|
||||||
mGridPos.x() = cell.getGridX();
|
mGridPos.x() = cell.getGridX();
|
||||||
|
|
|
@ -18,9 +18,11 @@ namespace ESM4
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
class CellStore;
|
||||||
|
|
||||||
struct Cell : public ESM::CellVariant
|
struct Cell : public ESM::CellVariant
|
||||||
{
|
{
|
||||||
|
friend MWWorld::CellStore;
|
||||||
struct MoodData
|
struct MoodData
|
||||||
{
|
{
|
||||||
uint32_t mAmbiantColor;
|
uint32_t mAmbiantColor;
|
||||||
|
@ -39,7 +41,7 @@ namespace MWWorld
|
||||||
bool isQuasiExterior() const { return mFlags.isQuasiExterior; }
|
bool isQuasiExterior() const { return mFlags.isQuasiExterior; }
|
||||||
bool hasWater() const { return mFlags.hasWater; }
|
bool hasWater() const { return mFlags.hasWater; }
|
||||||
bool noSleep() const { return mFlags.noSleep; }
|
bool noSleep() const { return mFlags.noSleep; }
|
||||||
const ESM::CellId& getCellId() const { return mCellId; };
|
const ESM::CellId& getCellId() const { return mCellId; }
|
||||||
const ESM::RefId& getRegion() const { return mRegion; }
|
const ESM::RefId& getRegion() const { return mRegion; }
|
||||||
std::string_view getEditorName() const { return mNameID; }
|
std::string_view getEditorName() const { return mNameID; }
|
||||||
std::string getDescription() const;
|
std::string getDescription() const;
|
||||||
|
|
|
@ -772,41 +772,20 @@ namespace MWWorld
|
||||||
std::sort(mIds.begin(), mIds.end());
|
std::sort(mIds.begin(), mIds.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CellStore::loadRefs()
|
void CellStore::loadRefs(const ESM::Cell& cell, std::map<ESM::RefNum, ESM::RefId>& refNumToID)
|
||||||
{
|
{
|
||||||
assert(mCellVariant.isValid());
|
if (cell.mContextList.empty())
|
||||||
std::map<ESM::RefNum, ESM::RefId> refNumToID; // used to detect refID modifications
|
|
||||||
|
|
||||||
if (mCellVariant.isEsm4())
|
|
||||||
{
|
|
||||||
auto cell4 = mCellVariant.getEsm4();
|
|
||||||
auto& refs = MWBase::Environment::get().getWorld()->getStore().get<ESM4::Reference>();
|
|
||||||
auto it = refs.begin();
|
|
||||||
|
|
||||||
while (it != refs.end())
|
|
||||||
{
|
|
||||||
if (it->mParent == cell4.mId)
|
|
||||||
{
|
|
||||||
loadRef(*it, false);
|
|
||||||
}
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto cell3 = mCellVariant.getEsm3();
|
|
||||||
if (cell3.mContextList.empty())
|
|
||||||
return; // this is a dynamically generated cell -> skipping.
|
return; // this is a dynamically generated cell -> skipping.
|
||||||
|
|
||||||
// Load references from all plugins that do something with this cell.
|
// Load references from all plugins that do something with this cell.
|
||||||
for (size_t i = 0; i < cell3.mContextList.size(); i++)
|
for (size_t i = 0; i < cell.mContextList.size(); i++)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Reopen the ESM reader and seek to the right position.
|
// Reopen the ESM reader and seek to the right position.
|
||||||
const std::size_t index = static_cast<std::size_t>(cell3.mContextList[i].index);
|
const std::size_t index = static_cast<std::size_t>(cell.mContextList[i].index);
|
||||||
const ESM::ReadersCache::BusyItem reader = mReaders.get(index);
|
const ESM::ReadersCache::BusyItem reader = mReaders.get(index);
|
||||||
cell3.restore(*reader, i);
|
cell.restore(*reader, i);
|
||||||
|
|
||||||
ESM::CellRef ref;
|
ESM::CellRef ref;
|
||||||
// Get each reference in turn
|
// Get each reference in turn
|
||||||
|
@ -821,8 +800,8 @@ namespace MWWorld
|
||||||
|
|
||||||
// Don't load reference if it was moved to a different cell.
|
// Don't load reference if it was moved to a different cell.
|
||||||
ESM::MovedCellRefTracker::const_iterator iter
|
ESM::MovedCellRefTracker::const_iterator iter
|
||||||
= std::find(cell3.mMovedRefs.begin(), cell3.mMovedRefs.end(), ref.mRefNum);
|
= std::find(cell.mMovedRefs.begin(), cell.mMovedRefs.end(), ref.mRefNum);
|
||||||
if (iter != cell3.mMovedRefs.end())
|
if (iter != cell.mMovedRefs.end())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -837,7 +816,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Load moved references, from separately tracked list.
|
// Load moved references, from separately tracked list.
|
||||||
for (const auto& leasedRef : cell3.mLeasedRefs)
|
for (const auto& leasedRef : cell.mLeasedRefs)
|
||||||
{
|
{
|
||||||
ESM::CellRef& ref = const_cast<ESM::CellRef&>(leasedRef.first);
|
ESM::CellRef& ref = const_cast<ESM::CellRef&>(leasedRef.first);
|
||||||
bool deleted = leasedRef.second;
|
bool deleted = leasedRef.second;
|
||||||
|
@ -846,6 +825,26 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CellStore::loadRefs(const ESM4::Cell& cell, std::map<ESM::RefNum, ESM::RefId>& refNumToID)
|
||||||
|
{
|
||||||
|
auto& refs = MWBase::Environment::get().getWorld()->getStore().get<ESM4::Reference>();
|
||||||
|
|
||||||
|
for (const auto& ref : refs)
|
||||||
|
{
|
||||||
|
if (ref.mParent == cell.mId)
|
||||||
|
{
|
||||||
|
loadRef(ref, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CellStore::loadRefs()
|
||||||
|
{
|
||||||
|
assert(mCellVariant.isValid());
|
||||||
|
std::map<ESM::RefNum, ESM::RefId> refNumToID; // used to detect refID modifications
|
||||||
|
|
||||||
|
std::visit([&refNumToID, this](auto&& cell) { this->loadRefs(*cell, refNumToID); }, mCellVariant.mVariant);
|
||||||
|
|
||||||
updateMergedRefs();
|
updateMergedRefs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1087,18 +1086,21 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Visitor
|
||||||
|
{
|
||||||
|
bool operator()(const ESM::Cell* a, const ESM::Cell* b) const { return a->getCellId() == b->getCellId(); };
|
||||||
|
bool operator()(const ESM4::Cell* a, const ESM4::Cell* b) const { return a->mId == b->mId; };
|
||||||
|
|
||||||
|
template <class L, class R>
|
||||||
|
bool operator()(L, R) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
bool CellStore::operator==(const CellStore& right) const
|
bool CellStore::operator==(const CellStore& right) const
|
||||||
{
|
{
|
||||||
|
return std::visit(Visitor{}, this->mCellVariant.mVariant, right.mCellVariant.mVariant);
|
||||||
bool bothCell4 = mCellVariant.isEsm4() && right.mCellVariant.isEsm4();
|
|
||||||
bool bothCell3 = !mCellVariant.isEsm4() && !right.mCellVariant.isEsm4();
|
|
||||||
|
|
||||||
if (bothCell3)
|
|
||||||
return mCellVariant.getEsm3().getCellId() == right.mCellVariant.getEsm3().getCellId();
|
|
||||||
else if (bothCell4)
|
|
||||||
return mCellVariant.getEsm4().mId == right.mCellVariant.getEsm4().mId;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CellStore::setFog(std::unique_ptr<ESM::FogState>&& fog)
|
void CellStore::setFog(std::unique_ptr<ESM::FogState>&& fog)
|
||||||
|
|
|
@ -386,6 +386,9 @@ namespace MWWorld
|
||||||
/// Run through references and store IDs
|
/// Run through references and store IDs
|
||||||
void listRefs();
|
void listRefs();
|
||||||
|
|
||||||
|
void loadRefs(const ESM::Cell& cell, std::map<ESM::RefNum, ESM::RefId>& refNumToID);
|
||||||
|
void loadRefs(const ESM4::Cell& cell, std::map<ESM::RefNum, ESM::RefId>& refNumToID);
|
||||||
|
|
||||||
void loadRefs();
|
void loadRefs();
|
||||||
|
|
||||||
void loadRef(const ESM4::Reference& ref, bool deleted);
|
void loadRef(const ESM4::Reference& ref, bool deleted);
|
||||||
|
|
|
@ -888,7 +888,7 @@ namespace MWWorld
|
||||||
loadingListener->setProgressRange(cell->count());
|
loadingListener->setProgressRange(cell->count());
|
||||||
|
|
||||||
mNavigator.setWorldspace(
|
mNavigator.setWorldspace(
|
||||||
Misc::StringUtils::lowerCase(cell->getCell()->getEditorName()), navigatorUpdateGuard.get());
|
Misc::StringUtils::lowerCase(cell->getCell()->getCellId().mWorldspace), navigatorUpdateGuard.get());
|
||||||
mNavigator.updateBounds(position.asVec3(), navigatorUpdateGuard.get());
|
mNavigator.updateBounds(position.asVec3(), navigatorUpdateGuard.get());
|
||||||
|
|
||||||
// Load cell.
|
// Load cell.
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace ESM
|
||||||
|
|
||||||
struct CellVariant
|
struct CellVariant
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
std::variant<const ESM4::Cell*, const ESM::Cell*> mVariant;
|
std::variant<const ESM4::Cell*, const ESM::Cell*> mVariant;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue