diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 0e8af6eae9..ba1c34545d 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -57,8 +57,6 @@ namespace ESM struct ItemLevList; struct TimeStamp; struct RefId; - class CellVariant; - } namespace MWPhysics @@ -184,6 +182,8 @@ namespace MWBase /// generate a name. virtual std::string_view getCellName(const MWWorld::Cell& cell) const = 0; + virtual std::string_view getCellName(const ESM::Cell* cell) const = 0; + virtual void removeRefScript(MWWorld::RefData* ref) = 0; //< Remove the script attached to ref from mLocalScripts diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 0d27474428..075b2cffa8 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -307,7 +307,7 @@ namespace MWClass const osg::Vec2i index = MWWorld::positionToCellIndex(door.mRef.getDoorDest().pos[0], door.mRef.getDoorDest().pos[1]); const ESM::Cell* cell = world->getStore().get().search(index.x(), index.y()); - dest = world->getCellName(MWWorld::Cell(*cell)); + dest = world->getCellName(cell); } return "#{sCell=" + std::string{ dest } + "}"; diff --git a/apps/openmw/mwmechanics/aiwander.hpp b/apps/openmw/mwmechanics/aiwander.hpp index b4d59bdbe2..9b5a7aed42 100644 --- a/apps/openmw/mwmechanics/aiwander.hpp +++ b/apps/openmw/mwmechanics/aiwander.hpp @@ -12,7 +12,6 @@ namespace ESM { struct Cell; - struct CellCommon; namespace AiSequence { struct AiWander; @@ -159,7 +158,6 @@ namespace MWMechanics GroupIndex_MaxIdle = 9 }; - /// convert point from local (i.e. cell) to world coordinates void setCurrentNodeToClosestAllowedNode(AiWanderStorage& storage); void addNonPathGridAllowedPoints(const ESM::Pathgrid* pathGrid, int pointIndex, AiWanderStorage& storage, diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 62e546bdad..5f2ef350c1 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -43,7 +43,6 @@ namespace ESM { struct Cell; struct RefNum; - class CellVariant; } namespace Terrain diff --git a/apps/openmw/mwworld/cell.cpp b/apps/openmw/mwworld/cell.cpp index 9a345d2ac8..9444e42136 100644 --- a/apps/openmw/mwworld/cell.cpp +++ b/apps/openmw/mwworld/cell.cpp @@ -8,52 +8,44 @@ namespace MWWorld { Cell::Cell(const ESM4::Cell& cell) : ESM::CellVariant(cell) + , mIsExterior(!(cell.mCellFlags & ESM4::CELL_Interior)) + , mIsQuasiExterior(cell.mCellFlags & ESM4::CELL_QuasiExt) + , mHasWater(cell.mCellFlags & ESM4::CELL_HasWater) + , mNoSleep(false) // No such notion in ESM4 + , mGridPos(cell.mX, cell.mY) + , mDisplayname(cell.mFullName) + , mNameID(cell.mEditorId) + , mRegion(ESM::RefId::sEmpty) // Unimplemented for now + , mCellId{ + .mWorldspace{ Misc::StringUtils::lowerCase(cell.mEditorId) }, + .mIndex{ cell.getGridX(), cell.getGridY() }, + .mPaged = isExterior(),} + ,mMood{ + .mAmbiantColor = cell.mLighting.ambient, + .mDirectionalColor = cell.mLighting.directional, + .mFogColor = cell.mLighting.fogColor, + .mFogDensity = cell.mLighting.fogPower,} { - - mNameID = cell.mEditorId; - mDisplayname = cell.mFullName; - mGridPos.x() = cell.mX; - mGridPos.y() = cell.mY; - - mRegion = ESM::RefId::sEmpty; // Unimplemented for now - - mFlags.mHasWater = cell.mCellFlags & ESM4::CELL_HasWater; - mFlags.mIsExterior = !(cell.mCellFlags & ESM4::CELL_Interior); - mFlags.mIsQuasiExterior = cell.mCellFlags & ESM4::CELL_QuasiExt; - mFlags.mNoSleep = false; // No such notion in ESM4 - - mCellId.mWorldspace = Misc::StringUtils::lowerCase(cell.mEditorId); - mCellId.mIndex.mX = cell.getGridX(); - mCellId.mIndex.mX = cell.getGridY(); - mCellId.mPaged = isExterior(); - - mMood.mAmbiantColor = cell.mLighting.ambient; - mMood.mFogColor = cell.mLighting.fogColor; - mMood.mDirectionalColor = cell.mLighting.directional; - mMood.mFogDensity = cell.mLighting.fogPower; } Cell::Cell(const ESM::Cell& cell) : ESM::CellVariant(cell) + , mIsExterior(!(cell.mData.mFlags & ESM::Cell::Interior)) + , mIsQuasiExterior(cell.mData.mFlags & ESM::Cell::QuasiEx) + , mHasWater(cell.mData.mFlags & ESM::Cell::HasWater) + , mNoSleep(cell.mData.mFlags & ESM::Cell::NoSleep) + , mGridPos(cell.getGridX(), cell.getGridY()) + , mDisplayname(cell.mName) + , mNameID(cell.mName) + , mRegion(ESM::RefId::sEmpty) // Unimplemented for now + , mCellId(cell.getCellId()) + , mMood{ + .mAmbiantColor = cell.mAmbi.mAmbient, + .mDirectionalColor = cell.mAmbi.mSunlight, + .mFogColor = cell.mAmbi.mFog, + .mFogDensity = cell.mAmbi.mFogDensity, + } { - mNameID = cell.mName; - mDisplayname = cell.mName; - mGridPos.x() = cell.getGridX(); - mGridPos.y() = cell.getGridY(); - - mRegion = ESM::RefId::sEmpty; // Unimplemented for now - - mFlags.mHasWater = cell.mData.mFlags & ESM::Cell::HasWater; - mFlags.mIsExterior = !(cell.mData.mFlags & ESM::Cell::Interior); - mFlags.mIsQuasiExterior = cell.mData.mFlags & ESM::Cell::QuasiEx; - mFlags.mNoSleep = cell.mData.mFlags & ESM::Cell::NoSleep; - - mCellId = cell.getCellId(); - - mMood.mAmbiantColor = cell.mAmbi.mAmbient; - mMood.mFogColor = cell.mAmbi.mFog; - mMood.mDirectionalColor = cell.mAmbi.mSunlight; - mMood.mFogDensity = cell.mAmbi.mFogDensity; } std::string Cell::getDescription() const diff --git a/apps/openmw/mwworld/cell.hpp b/apps/openmw/mwworld/cell.hpp index 21a53792da..b90fed31f8 100644 --- a/apps/openmw/mwworld/cell.hpp +++ b/apps/openmw/mwworld/cell.hpp @@ -38,10 +38,10 @@ namespace MWWorld int getGridX() const { return mGridPos.x(); } int getGridY() const { return mGridPos.y(); } - bool isExterior() const { return mFlags.mIsExterior; } - bool isQuasiExterior() const { return mFlags.mIsQuasiExterior; } - bool hasWater() const { return mFlags.mHasWater; } - bool noSleep() const { return mFlags.mNoSleep; } + bool isExterior() const { return mIsExterior; } + bool isQuasiExterior() const { return mIsQuasiExterior; } + bool hasWater() const { return mHasWater; } + bool noSleep() const { return mNoSleep; } const ESM::CellId& getCellId() const { return mCellId; } const ESM::RefId& getRegion() const { return mRegion; } std::string_view getNameId() const { return mNameID; } @@ -50,13 +50,10 @@ namespace MWWorld const MoodData& getMood() const { return mMood; } private: - struct - { - bool mIsExterior; - bool mIsQuasiExterior; - bool mHasWater; - bool mNoSleep; - } mFlags; + bool mIsExterior; + bool mIsQuasiExterior; + bool mHasWater; + bool mNoSleep; osg::Vec2i mGridPos; std::string mDisplayname; // How the game displays it diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index d322c183cf..40bd9107a1 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -709,7 +709,7 @@ namespace MWWorld if (mCellVariant.isEsm4()) return; - auto cell3 = mCellVariant.getEsm3(); + const ESM::Cell& cell3 = mCellVariant.getEsm3(); if (cell3.mContextList.empty()) return; // this is a dynamically generated cell -> skipping. @@ -834,7 +834,7 @@ namespace MWWorld { std::map refNumToID; // used to detect refID modifications - std::visit([&refNumToID, this](auto&& cell) { this->loadRefs(*cell, refNumToID); }, mCellVariant); + ESM::visit([&refNumToID, this](auto&& cell) { this->loadRefs(cell, refNumToID); }, mCellVariant); updateMergedRefs(); } @@ -1077,13 +1077,13 @@ namespace MWWorld } } - struct Visitor + struct IsEqualVisitor { - 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; } + 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 - bool operator()(L, R) const + bool operator()(const L&, const R&) const { return false; } @@ -1091,7 +1091,7 @@ namespace MWWorld bool CellStore::operator==(const CellStore& right) const { - return std::visit(Visitor{}, this->mCellVariant, right.mCellVariant); + return ESM::visit(IsEqualVisitor(), this->mCellVariant, right.mCellVariant); } void CellStore::setFog(std::unique_ptr&& fog) diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index 528ec2b902..720aa394b5 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include "cell.hpp" diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 0e285ee30d..c3b1ec1ec6 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -432,7 +432,7 @@ namespace MWWorld if (!cellVariant.isEsm4()) { - auto cell3 = cellVariant.getEsm3(); + const ESM::Cell& cell3 = cellVariant.getEsm3(); if (const auto pathgrid = mWorld.getStore().get().search(cell3)) mNavigator.addPathgrid(cell3, *pathgrid); } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 641619acf6..8f213df71f 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -644,11 +644,21 @@ namespace MWWorld if (!cell.isEsm4()) { - const ESM::Region* region = mStore.get().search(cell.getEsm3().mRegion); - if (region) - return region->mName; + return getCellName(&cell.getEsm3()); } + return mStore.get().find("sDefaultCellname")->mValue.getString(); + } + + std::string_view World::getCellName(const ESM::Cell* cell) const + { + if (cell) + { + if (!cell->isExterior() || !cell->mName.empty()) + return cell->mName; + if (const ESM::Region* region = mStore.get().search(cell->mRegion)) + return region->mName; + } return mStore.get().find("sDefaultCellname")->mValue.getString(); } @@ -3244,7 +3254,7 @@ namespace MWWorld } else { - auto cellVariant = *cell->getCell(); + const MWWorld::Cell& cellVariant = *cell->getCell(); uint32_t ambient = cellVariant.getMood().mAmbiantColor; int ambientTotal = (ambient & 0xff) + ((ambient >> 8) & 0xff) + ((ambient >> 16) & 0xff); return !cell->getCell()->noSleep() && ambientTotal <= 201; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 0d3a45e656..3cdf144d75 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -270,6 +270,7 @@ namespace MWWorld /// \note If cell==0, the cell the player is currently in will be used instead to /// generate a name. std::string_view getCellName(const MWWorld::Cell& cell) const override; + std::string_view getCellName(const ESM::Cell* cell) const override; void removeRefScript(MWWorld::RefData* ref) override; //< Remove the script attached to ref from mLocalScripts diff --git a/components/esm/esmbridge.hpp b/components/esm/esmbridge.hpp index 7912e66cbe..83e858d7b6 100644 --- a/components/esm/esmbridge.hpp +++ b/components/esm/esmbridge.hpp @@ -38,21 +38,8 @@ namespace ESM const ESM4::Cell& getEsm4() const; const ESM::Cell& getEsm3() const; - template - auto visit(F&& f) const - { - return std::visit(f, mVariant); - } - template - auto visit(F&& f) - { - return std::visit(f, mVariant); - } - template - auto visit(F&& f, const CellVariant& v2) const - { - return std::visit(f, mVariant, v2.mVariant); - } + template + friend auto visit(F&& f, T&&... v); }; struct ReferenceVariant @@ -77,24 +64,11 @@ namespace ESM ESM::CellRef& getEsm3() { return std::get(mVariant); } ESM4::Reference& getEsm4() { return std::get(mVariant); } }; -} -namespace std -{ - template - auto visit(F&& f, const ESM::CellVariant& v) - { - return v.visit(f); - } - template - auto visit(F&& f, ESM::CellVariant& v) - { - return v.visit(f); - } - template - auto visit(F&& f, const ESM::CellVariant& v1, const ESM::CellVariant& v2) + template + auto visit(F&& f, T&&... v) { - return v1.visit(f, v2); + return std::visit([&](auto*... ptr) { return std::forward(f)(*ptr...); }, std::forward(v).mVariant...); } } #endif diff --git a/components/esm4/loadcell.cpp b/components/esm4/loadcell.cpp index 09eef41679..0b829d657f 100644 --- a/components/esm4/loadcell.cpp +++ b/components/esm4/loadcell.cpp @@ -39,7 +39,6 @@ // #include "writer.hpp" #include -#include // TODO: Try loading only EDID and XCLC (along with mFormId, mFlags and mParent) //