From 2c30575b3b4bcda9c5d3b742859480d7d70c9e3c Mon Sep 17 00:00:00 2001 From: "florent.teppe" Date: Thu, 1 Dec 2022 19:37:35 +0100 Subject: [PATCH] CellName is now a RefId, makes more sense that way. --- apps/esmtool/record.cpp | 2 +- apps/essimporter/converter.cpp | 2 +- apps/essimporter/converter.hpp | 2 +- apps/essimporter/convertplayer.cpp | 2 +- apps/launcher/utils/cellnameloader.cpp | 2 +- apps/navmeshtool/worldspacedata.cpp | 10 +-- apps/opencs/model/tools/referencecheck.cpp | 2 +- apps/opencs/model/tools/topicinfocheck.cpp | 9 ++- apps/opencs/model/tools/topicinfocheck.hpp | 2 +- apps/opencs/model/world/cell.cpp | 2 +- apps/opencs/model/world/columnimp.hpp | 30 ++++++++- apps/opencs/model/world/idtable.cpp | 2 +- apps/opencs/model/world/regionmap.hpp | 2 +- apps/opencs/view/world/scenesubview.cpp | 2 +- apps/openmw/engine.cpp | 2 +- apps/openmw/engine.hpp | 3 +- apps/openmw/mwbase/world.hpp | 12 ++-- apps/openmw/mwclass/door.cpp | 4 +- apps/openmw/mwdialogue/filter.cpp | 4 +- apps/openmw/mwgui/console.cpp | 2 +- apps/openmw/mwgui/mapwindow.cpp | 10 +-- apps/openmw/mwgui/travelwindow.cpp | 2 +- apps/openmw/mwgui/windowmanagerimp.cpp | 6 +- apps/openmw/mwlua/localscripts.cpp | 2 +- apps/openmw/mwlua/luabindings.cpp | 2 +- apps/openmw/mwlua/objectbindings.cpp | 8 +-- apps/openmw/mwlua/worldview.cpp | 4 +- apps/openmw/mwlua/worldview.hpp | 4 +- apps/openmw/mwmechanics/aiescort.cpp | 2 +- apps/openmw/mwmechanics/aifollow.cpp | 2 +- apps/openmw/mwmechanics/spelleffects.cpp | 4 +- apps/openmw/mwscript/cellextensions.cpp | 4 +- apps/openmw/mwscript/guiextensions.cpp | 7 ++- apps/openmw/mwscript/interpretercontext.cpp | 2 +- .../mwscript/transformationextensions.cpp | 8 +-- apps/openmw/mwstate/statemanagerimp.cpp | 2 +- apps/openmw/mwworld/actionteleport.cpp | 2 +- apps/openmw/mwworld/actionteleport.hpp | 4 +- apps/openmw/mwworld/cellref.hpp | 2 +- apps/openmw/mwworld/player.cpp | 2 +- apps/openmw/mwworld/scene.cpp | 2 +- apps/openmw/mwworld/scene.hpp | 2 +- apps/openmw/mwworld/store.cpp | 20 +++--- apps/openmw/mwworld/worldimp.cpp | 62 +++++++++---------- apps/openmw/mwworld/worldimp.hpp | 18 +++--- apps/openmw/mwworld/worldmodel.cpp | 14 ++--- apps/openmw/mwworld/worldmodel.hpp | 4 +- components/detournavigator/navigator.hpp | 3 + components/detournavigator/navigatorimpl.cpp | 6 ++ components/detournavigator/navigatorimpl.hpp | 3 + components/detournavigator/navigatorstub.hpp | 2 + components/esm3/cellid.cpp | 6 +- components/esm3/cellid.hpp | 5 +- components/esm3/cellref.cpp | 6 +- components/esm3/cellref.hpp | 2 +- components/esm3/loadcell.cpp | 13 ++-- components/esm3/loadcell.hpp | 4 +- components/esmloader/load.cpp | 3 +- 58 files changed, 196 insertions(+), 156 deletions(-) diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index 9cc8fb1ea4..73c75d6d87 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -1342,7 +1342,7 @@ namespace EsmTool template <> std::string Record::getId() const { - return mData.mName; + return mData.mName.getRefIdString(); } template <> diff --git a/apps/essimporter/converter.cpp b/apps/essimporter/converter.cpp index 7520de15f8..5b118edeab 100644 --- a/apps/essimporter/converter.cpp +++ b/apps/essimporter/converter.cpp @@ -202,7 +202,7 @@ namespace ESSImport } // note if the player is in a nameless exterior cell, we will assign the cellId later based on player position - if (cell.mName == mContext->mPlayerCellName) + if (cell.mName == ESM::RefId::stringRefId(mContext->mPlayerCellName)) { mContext->mPlayer.mCellId = cell.getCellId(); } diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index 865faef6df..f9f9c19ce6 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -351,7 +351,7 @@ namespace ESSImport std::vector mFogOfWar; }; - std::map mIntCells; + std::map mIntCells; std::map, Cell> mExtCells; std::vector mMarkers; diff --git a/apps/essimporter/convertplayer.cpp b/apps/essimporter/convertplayer.cpp index 5bb9897487..b7da036e01 100644 --- a/apps/essimporter/convertplayer.cpp +++ b/apps/essimporter/convertplayer.cpp @@ -70,7 +70,7 @@ namespace ESSImport // TODO: Figure out a better way to detect interiors. (0, 0) is a valid exterior cell. if (mark.mCellX == 0 && mark.mCellY == 0) { - cell.mWorldspace = pcdt.mMNAM; + cell.mWorldspace = ESM::RefId::stringRefId(pcdt.mMNAM); cell.mPaged = false; } diff --git a/apps/launcher/utils/cellnameloader.cpp b/apps/launcher/utils/cellnameloader.cpp index 717a61bd2b..fc970690e8 100644 --- a/apps/launcher/utils/cellnameloader.cpp +++ b/apps/launcher/utils/cellnameloader.cpp @@ -48,5 +48,5 @@ QString CellNameLoader::getCellName(ESM::ESMReader& esmReader) bool isDeleted = false; cell.loadNameAndData(esmReader, isDeleted); - return QString::fromStdString(cell.mName); + return QString::fromStdString(cell.mName.getRefIdString()); } diff --git a/apps/navmeshtool/worldspacedata.cpp b/apps/navmeshtool/worldspacedata.cpp index 5e1c94f9cb..4bf915254c 100644 --- a/apps/navmeshtool/worldspacedata.cpp +++ b/apps/navmeshtool/worldspacedata.cpp @@ -263,16 +263,16 @@ namespace NavMeshTool const osg::Vec2i cellPosition(cell.mData.mX, cell.mData.mY); const std::size_t cellObjectsBegin = data.mObjects.size(); - + const auto cellNameLowerCase = Misc::StringUtils::lowerCase(cell.mCellId.mWorldspace.getRefIdString()); WorldspaceNavMeshInput& navMeshInput = [&]() -> WorldspaceNavMeshInput& { - auto it = navMeshInputs.find(cell.mCellId.mWorldspace); + auto it = navMeshInputs.find(cellNameLowerCase); if (it == navMeshInputs.end()) { it = navMeshInputs - .emplace(cell.mCellId.mWorldspace, - std::make_unique(cell.mCellId.mWorldspace, settings.mRecast)) + .emplace(cellNameLowerCase, + std::make_unique(cellNameLowerCase, settings.mRecast)) .first; - it->second->mTileCachedRecastMeshManager.setWorldspace(cell.mCellId.mWorldspace, nullptr); + it->second->mTileCachedRecastMeshManager.setWorldspace(cellNameLowerCase, nullptr); } return *it->second; }(); diff --git a/apps/opencs/model/tools/referencecheck.cpp b/apps/opencs/model/tools/referencecheck.cpp index cf6d0b3a4d..6d5535609b 100644 --- a/apps/opencs/model/tools/referencecheck.cpp +++ b/apps/opencs/model/tools/referencecheck.cpp @@ -89,7 +89,7 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages& message if (!cellRef.mDestCell.empty() && mCells.searchId(cellRef.mDestCell) == -1) messages.add( - id, "Destination cell '" + cellRef.mDestCell + "' does not exist", "", CSMDoc::Message::Severity_Error); + id, "Destination cell '" + cellRef.mDestCell.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error); if (cellRef.mScale < 0) messages.add(id, "Negative scale", "", CSMDoc::Message::Severity_Error); diff --git a/apps/opencs/model/tools/topicinfocheck.cpp b/apps/opencs/model/tools/topicinfocheck.cpp index b8a04cc5a6..7524f79017 100644 --- a/apps/opencs/model/tools/topicinfocheck.cpp +++ b/apps/opencs/model/tools/topicinfocheck.cpp @@ -75,7 +75,7 @@ int CSMTools::TopicInfoCheckStage::setup() if (regionRecord.isDeleted()) continue; - mCellNames.insert(regionRecord.get().mName); + mCellNames.insert(ESM::RefId::stringRefId(regionRecord.get().mName)); } // Default cell name int index = mGameSettings.searchId("sDefaultCellname"); @@ -85,7 +85,7 @@ int CSMTools::TopicInfoCheckStage::setup() if (!gmstRecord.isDeleted() && gmstRecord.get().mValue.getType() == ESM::VT_String) { - mCellNames.insert(gmstRecord.get().mValue.getString()); + mCellNames.insert(ESM::RefId::stringRefId(gmstRecord.get().mValue.getString())); } } @@ -213,10 +213,9 @@ bool CSMTools::TopicInfoCheckStage::verifyActor( bool CSMTools::TopicInfoCheckStage::verifyCell( const ESM::RefId& cell, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) { - const std::string& cellName = cell.getRefIdString(); - if (mCellNames.find(cellName) == mCellNames.end()) + if (mCellNames.find(cell) == mCellNames.end()) { - messages.add(id, "Cell '" + cellName + "' does not exist", "", CSMDoc::Message::Severity_Error); + messages.add(id, "Cell '" + cell.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error); return false; } diff --git a/apps/opencs/model/tools/topicinfocheck.hpp b/apps/opencs/model/tools/topicinfocheck.hpp index c58df98ba9..8fbf84a59e 100644 --- a/apps/opencs/model/tools/topicinfocheck.hpp +++ b/apps/opencs/model/tools/topicinfocheck.hpp @@ -72,7 +72,7 @@ namespace CSMTools const CSMWorld::RefIdData& mReferencables; const CSMWorld::Resources& mSoundFiles; - std::set mCellNames; + std::set mCellNames; bool mIgnoreBaseRecords; diff --git a/apps/opencs/model/world/cell.cpp b/apps/opencs/model/world/cell.cpp index f4b0084ef4..80995776da 100644 --- a/apps/opencs/model/world/cell.cpp +++ b/apps/opencs/model/world/cell.cpp @@ -6,7 +6,7 @@ void CSMWorld::Cell::load(ESM::ESMReader& esm, bool& isDeleted) { ESM::Cell::load(esm, isDeleted, false); - mId = ESM::RefId::stringRefId(mName); + mId = mName; if (isExterior()) { std::ostringstream stream; diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index ccb6371b88..54b8c07afe 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -333,6 +334,31 @@ namespace CSMWorld bool isEditable() const override { return true; } }; + template<> + struct NameColumn : public Column < CSMWorld::Cell> + { + NameColumn(ColumnBase::Display display = ColumnBase::Display_String) + : Column(Columns::ColumnId_Name, display) + { + } + + QVariant get(const Record& record) const override + { + return QString::fromUtf8(record.get().mName.getRefIdString().c_str()); + } + + void set(Record& record, const QVariant& data) override + { + CSMWorld::Cell record2 = record.get(); + + record2.mName = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); + + record.setModified(record2); + } + + bool isEditable() const override { return true; } + }; + template struct AttributesColumn : public Column { @@ -1121,14 +1147,14 @@ namespace CSMWorld QVariant get(const Record& record) const override { - return QString::fromUtf8(record.get().mDestCell.c_str()); + return QString::fromUtf8(record.get().mDestCell.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); - record2.mDestCell = data.toString().toUtf8().constData(); + record2.mDestCell = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index c0da8e7fac..d3be51d552 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -333,7 +333,7 @@ std::pair CSMWorld::IdTable::view(int row) c return std::make_pair(UniversalId::Type_None, ""); if (id[0] == '#') - id = ESM::CellId::sDefaultWorldspace; + id = ESM::CellId::sDefaultWorldspace.getRefIdString(); return std::make_pair(UniversalId(UniversalId::Type_Scene, id), hint); } diff --git a/apps/opencs/model/world/regionmap.hpp b/apps/opencs/model/world/regionmap.hpp index 3f62c7b61d..32c205281c 100644 --- a/apps/opencs/model/world/regionmap.hpp +++ b/apps/opencs/model/world/regionmap.hpp @@ -42,7 +42,7 @@ namespace CSMWorld { bool mDeleted; ESM::RefId mRegion; - std::string mName; + ESM::RefId mName; CellDescription(); diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index a0ff807ba9..a35c9caf84 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -49,7 +49,7 @@ CSVWorld::SceneSubView::SceneSubView(const CSMWorld::UniversalId& id, CSMDoc::Do CSVRender::WorldspaceWidget* worldspaceWidget = nullptr; widgetType whatWidget; - if (id.getId() == ESM::CellId::sDefaultWorldspace) + if (ESM::RefId::stringRefId(id.getId()) == ESM::CellId::sDefaultWorldspace) { whatWidget = widget_Paged; diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index c215b46e09..1528476794 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -444,7 +444,7 @@ void OMW::Engine::setResourceDir(const std::filesystem::path& parResDir) // Set start cell name void OMW::Engine::setCell(const std::string& cellName) { - mCellName = cellName; + mCellName = ESM::RefId::stringRefId(cellName); } void OMW::Engine::addContentFile(const std::string& file) diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 81c3bd009b..d22c3c13f2 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -151,7 +152,7 @@ namespace OMW osg::ref_ptr mScreenCaptureOperation; osg::ref_ptr mSelectDepthFormatOperation; osg::ref_ptr mSelectColorFormatOperation; - std::string mCellName; + ESM::RefId mCellName; std::vector mContentFiles; std::vector mGroundcoverFiles; diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index e3bf06a10f..d9e6536fa2 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -177,12 +177,12 @@ namespace MWBase virtual char getGlobalVariableType(std::string_view name) const = 0; ///< Return ' ', if there is no global variable with this name. - virtual std::string_view getCellName(const MWWorld::CellStore* cell = nullptr) const = 0; + virtual const ESM::RefId& getCellName(const MWWorld::CellStore* cell = nullptr) const = 0; ///< Return name of the cell. /// /// \note If cell==0, the cell the player is currently in will be used instead to /// generate a name. - virtual std::string_view getCellName(const ESM::Cell* cell) const = 0; + virtual const ESM::RefId getCellName(const ESM::Cell* cell) const = 0; virtual void removeRefScript(MWWorld::RefData* ref) = 0; //< Remove the script attached to ref from mLocalScripts @@ -248,7 +248,7 @@ namespace MWBase virtual void setSimulationTimeScale(float scale) = 0; virtual void changeToInteriorCell( - const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true) + const ESM::RefId& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true) = 0; ///< Move to interior cell. ///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes @@ -263,7 +263,7 @@ namespace MWBase = 0; ///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes - virtual const ESM::Cell* getExterior(std::string_view cellName) const = 0; + virtual const ESM::Cell* getExterior(const ESM::RefId& cellName) const = 0; ///< Return a cell matching the given name or a 0-pointer, if there is no such cell. virtual MWWorld::Ptr getFacedObject() = 0; @@ -519,11 +519,11 @@ namespace MWBase /// Find default position inside exterior cell specified by name /// \return false if exterior with given name not exists, true otherwise - virtual bool findExteriorPosition(std::string_view name, ESM::Position& pos) = 0; + virtual bool findExteriorPosition(const ESM::RefId& name, ESM::Position& pos) = 0; /// Find default position inside interior cell specified by name /// \return false if interior with given name not exists, true otherwise - virtual bool findInteriorPosition(std::string_view name, ESM::Position& pos) = 0; + virtual bool findInteriorPosition(const ESM::RefId& name, ESM::Position& pos) = 0; /// Enables or disables use of teleport spell effects (recall, intervention, etc). virtual void enableTeleporting(bool enable) = 0; diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index f5f808514b..884285cd17 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -299,7 +299,7 @@ namespace MWClass std::string Door::getDestination(const MWWorld::LiveCellRef& door) { - std::string dest = door.mRef.getDestCell(); + auto dest = door.mRef.getDestCell(); if (dest.empty()) { // door leads to exterior, use cell name (if any), otherwise translated region name @@ -310,7 +310,7 @@ namespace MWClass dest = world->getCellName(cell); } - return "#{sCell=" + dest + "}"; + return "#{sCell=" + dest.getRefIdString() + "}"; } MWWorld::Ptr Door::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 3821862ecb..35b1f24b75 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -196,7 +196,7 @@ bool MWDialogue::Filter::testPlayer(const ESM::DialInfo& info) const if (!info.mCell.empty()) { // supports partial matches, just like getPcCell - std::string_view playerCell = MWBase::Environment::get().getWorld()->getCellName(player.getCell()); + std::string_view playerCell = MWBase::Environment::get().getWorld()->getCellName(player.getCell()).getRefIdString(); if (!Misc::StringUtils::ciStartsWith(playerCell, info.mCell.getRefIdString())) return false; } @@ -553,7 +553,7 @@ bool MWDialogue::Filter::getSelectStructBoolean(const SelectWrapper& select) con case SelectWrapper::Function_NotCell: { - std::string_view actorCell = MWBase::Environment::get().getWorld()->getCellName(mActor.getCell()); + std::string_view actorCell = MWBase::Environment::get().getWorld()->getCellName(mActor.getCell()).getRefIdString(); return !Misc::StringUtils::ciStartsWith(actorCell, select.getName()); } case SelectWrapper::Function_SameGender: diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index cb8208fd0f..4e7cdd250b 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -122,7 +122,7 @@ namespace MWGui it != store.get().extEnd(); ++it) { if (!it->mName.empty()) - mNames.push_back(it->mName); + mNames.push_back(it->mName.getRefIdString()); } // sort diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index c79059d022..df30363bbb 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -353,7 +353,7 @@ namespace MWGui { ESM::CellId cellId; cellId.mPaged = !mInterior; - cellId.mWorldspace = (mInterior ? mPrefix : ESM::CellId::sDefaultWorldspace); + cellId.mWorldspace = (mInterior ? ESM::RefId::stringRefId(mPrefix) : ESM::CellId::sDefaultWorldspace); cellId.mIndex.mX = mCurX + dX; cellId.mIndex.mY = mCurY + dY; @@ -637,7 +637,7 @@ namespace MWGui for (MyGUI::Widget* widget : mExteriorDoorMarkerWidgets) widget->setVisible(false); - MWWorld::CellStore* cell = worldModel->getInterior(mPrefix); + MWWorld::CellStore* cell = worldModel->getInterior(ESM::RefId::stringRefId(mPrefix)); world->getDoorMarkers(cell, doors); } else @@ -705,7 +705,7 @@ namespace MWGui ESM::Position markedPosition; MWBase::Environment::get().getWorld()->getPlayer().getMarkedPosition(markedCell, markedPosition); if (markedCell && markedCell->isExterior() == !mInterior - && (!mInterior || Misc::StringUtils::ciEqual(markedCell->getCell()->mName, mPrefix))) + && (!mInterior || Misc::StringUtils::ciEqual(markedCell->getCell()->mName.getRefIdString(), mPrefix))) { MarkerUserData markerPos(mLocalMapRender); MyGUI::ImageBox* markerWidget = mLocalMap->createWidget("ImageBox", @@ -888,7 +888,7 @@ namespace MWGui mEditingMarker.mCell.mPaged = !mInterior; if (mInterior) - mEditingMarker.mCell.mWorldspace = LocalMapBase::mPrefix; + mEditingMarker.mCell.mWorldspace = ESM::RefId::stringRefId(LocalMapBase::mPrefix); else { mEditingMarker.mCell.mWorldspace = ESM::CellId::sDefaultWorldspace; @@ -1333,7 +1333,7 @@ namespace MWGui const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getStore().get().search( cellId.first, cellId.second); if (cell && !cell->mName.empty()) - addVisitedLocation(cell->mName, cellId.first, cellId.second); + addVisitedLocation(cell->mName.getRefIdString(), cellId.first, cellId.second); } } } diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 184f1868d1..95832c92bb 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -198,7 +198,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->fadeScreenOut(1); // Teleports any followers, too. - MWWorld::ActionTeleport action(interior ? cellname.getRefIdString() : "", pos, true); + MWWorld::ActionTeleport action(interior ? cellname : ESM::RefId::sEmpty, pos, true); action.execute(player); MWBase::Environment::get().getWindowManager()->fadeScreenOut(0); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 56ad675639..bea74710b4 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -933,7 +933,7 @@ namespace MWGui { mMap->requestMapRender(cell); - std::string name = std::string(MWBase::Environment::get().getWorld()->getCellName(cell)); + std::string name = MWBase::Environment::get().getWorld()->getCellName(cell).getRefIdString(); mMap->setCellName(name); mHud->setCellName(name); @@ -949,8 +949,8 @@ namespace MWGui } else { - mMap->setCellPrefix(cell->getCell()->mName); - mHud->setCellPrefix(cell->getCell()->mName); + mMap->setCellPrefix(cell->getCell()->mName.getRefIdString()); + mHud->setCellPrefix(cell->getCell()->mName.getRefIdString()); osg::Vec3f worldPos; if (!MWBase::Environment::get().getWorld()->findInteriorPositionInWorldSpace(cell, worldPos)) diff --git a/apps/openmw/mwlua/localscripts.cpp b/apps/openmw/mwlua/localscripts.cpp index f4afd83f29..54f8b7e330 100644 --- a/apps/openmw/mwlua/localscripts.cpp +++ b/apps/openmw/mwlua/localscripts.cpp @@ -146,7 +146,7 @@ namespace MWLua if (esmCell->isExterior()) ai.stack(MWMechanics::AiEscort(refId, gameHoursDuration, dest.x(), dest.y(), dest.z(), false), ptr); else - ai.stack(MWMechanics::AiEscort(refId, ESM::RefId::stringRefId(esmCell->mName), gameHoursDuration, + ai.stack(MWMechanics::AiEscort(refId, esmCell->mName, gameHoursDuration, dest.x(), dest.y(), dest.z(), false), ptr); }; diff --git a/apps/openmw/mwlua/luabindings.cpp b/apps/openmw/mwlua/luabindings.cpp index a5600f6f16..452caea9b8 100644 --- a/apps/openmw/mwlua/luabindings.cpp +++ b/apps/openmw/mwlua/luabindings.cpp @@ -79,7 +79,7 @@ namespace MWLua WorldView* worldView = context.mWorldView; addTimeBindings(api, context, true); api["getCellByName"] = [worldView = context.mWorldView](const std::string& name) -> sol::optional { - MWWorld::CellStore* cell = worldView->findNamedCell(name); + MWWorld::CellStore* cell = worldView->findNamedCell(ESM::RefId::stringRefId(name)); if (cell) return GCell{ cell }; else diff --git a/apps/openmw/mwlua/objectbindings.cpp b/apps/openmw/mwlua/objectbindings.cpp index b82338c646..5f8fd62d74 100644 --- a/apps/openmw/mwlua/objectbindings.cpp +++ b/apps/openmw/mwlua/objectbindings.cpp @@ -51,7 +51,7 @@ namespace MWLua class TeleportAction final : public LuaManager::Action { public: - TeleportAction(LuaUtil::LuaState* state, ObjectId object, std::string cell, const osg::Vec3f& pos, + TeleportAction(LuaUtil::LuaState* state, ObjectId object, ESM::RefId cell, const osg::Vec3f& pos, const osg::Vec3f& rot) : Action(state) , mObject(object) @@ -65,7 +65,7 @@ namespace MWLua { MWWorld::CellStore* cell = worldView.findCell(mCell, mPos); if (!cell) - throw std::runtime_error(std::string("cell not found: '") + mCell + "'"); + throw std::runtime_error(std::string("cell not found: '") + mCell.getRefIdString() + "'"); MWBase::World* world = MWBase::Environment::get().getWorld(); MWWorld::Ptr obj = worldView.getObjectRegistry()->getPtr(mObject, false); @@ -96,7 +96,7 @@ namespace MWLua private: ObjectId mObject; - std::string mCell; + ESM::RefId mCell; osg::Vec3f mPos; osg::Vec3f mRot; }; @@ -247,7 +247,7 @@ namespace MWLua MWWorld::Ptr ptr = object.ptr(); osg::Vec3f rot = optRot ? *optRot : ptr.getRefData().getPosition().asRotationVec3(); auto action - = std::make_unique(context.mLua, object.id(), std::string(cell), pos, rot); + = std::make_unique(context.mLua, object.id(), ESM::RefId::stringRefId(cell), pos, rot); if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) context.mLuaManager->addTeleportPlayerAction(std::move(action)); else diff --git a/apps/openmw/mwlua/worldview.cpp b/apps/openmw/mwlua/worldview.cpp index f53741adbb..16dbbb7359 100644 --- a/apps/openmw/mwlua/worldview.cpp +++ b/apps/openmw/mwlua/worldview.cpp @@ -125,7 +125,7 @@ namespace MWLua // TODO: If Lua scripts will use several threads at the same time, then `find*Cell` functions should have critical // sections. - MWWorld::CellStore* WorldView::findCell(const std::string& name, osg::Vec3f position) + MWWorld::CellStore* WorldView::findCell(const ESM::RefId& name, osg::Vec3f position) { MWWorld::WorldModel* worldModel = MWBase::Environment::get().getWorldModel(); bool exterior = name.empty() || MWBase::Environment::get().getWorld()->getExterior(name); @@ -138,7 +138,7 @@ namespace MWLua return worldModel->getInterior(name); } - MWWorld::CellStore* WorldView::findNamedCell(const std::string& name) + MWWorld::CellStore* WorldView::findNamedCell(const ESM::RefId& name) { MWWorld::WorldModel* worldModel = MWBase::Environment::get().getWorldModel(); const ESM::Cell* esmCell = MWBase::Environment::get().getWorld()->getExterior(name); diff --git a/apps/openmw/mwlua/worldview.hpp b/apps/openmw/mwlua/worldview.hpp index 8c5127b6f6..56136d3ee7 100644 --- a/apps/openmw/mwlua/worldview.hpp +++ b/apps/openmw/mwlua/worldview.hpp @@ -54,8 +54,8 @@ namespace MWLua // If onlyActive = true, then search only among the objects that are currently in the scene. // TODO: ObjectIdList selectObjects(const Queries::Query& query, bool onlyActive); - MWWorld::CellStore* findCell(const std::string& name, osg::Vec3f position); - MWWorld::CellStore* findNamedCell(const std::string& name); + MWWorld::CellStore* findCell(const ESM::RefId& name, osg::Vec3f position); + MWWorld::CellStore* findNamedCell(const ESM::RefId& name); MWWorld::CellStore* findExteriorCell(int x, int y); void load(ESM::ESMReader& esm); diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index 4b98d5eebb..5338c55cee 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -78,7 +78,7 @@ namespace MWMechanics } } - if (!mCellId.empty() && mCellId.getRefIdString() != actor.getCell()->getCell()->getCellId().mWorldspace) + if (!mCellId.empty() && mCellId != actor.getCell()->getCell()->getCellId().mWorldspace) return false; // Not in the correct cell, pause and rely on the player to go back through a teleport door actor.getClass().getCreatureStats(actor).setDrawState(DrawState::Nothing); diff --git a/apps/openmw/mwmechanics/aifollow.cpp b/apps/openmw/mwmechanics/aifollow.cpp index a2cf383ab8..99e72e78d2 100644 --- a/apps/openmw/mwmechanics/aifollow.cpp +++ b/apps/openmw/mwmechanics/aifollow.cpp @@ -175,7 +175,7 @@ namespace MWMechanics return true; } } - else if (mCellId.getRefIdString() == actor.getCell()->getCell()->mName) // Cell to travel to + else if (mCellId == actor.getCell()->getCell()->mName) // Cell to travel to { mRemainingDuration = mDuration; return true; diff --git a/apps/openmw/mwmechanics/spelleffects.cpp b/apps/openmw/mwmechanics/spelleffects.cpp index 787eabc5f9..1eed6af575 100644 --- a/apps/openmw/mwmechanics/spelleffects.cpp +++ b/apps/openmw/mwmechanics/spelleffects.cpp @@ -489,8 +489,8 @@ namespace MWMechanics { ESM::RefId dest; if (!markedCell->isExterior()) - dest = ESM::RefId::stringRefId(markedCell->getCell()->mName); - MWWorld::ActionTeleport action(dest.getRefIdString(), markedPosition, false); + dest = markedCell->getCell()->mName; + MWWorld::ActionTeleport action(dest, markedPosition, false); action.execute(target); if (!caster.isEmpty()) { diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index b5a540fd81..55b9641ff1 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -86,7 +86,7 @@ namespace MWScript public: void execute(Interpreter::Runtime& runtime) override { - std::string_view cell = runtime.getStringLiteral(runtime[0].mInteger); + const ESM::RefId cell = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger)); runtime.pop(); ESM::Position pos; @@ -165,7 +165,7 @@ namespace MWScript } const MWWorld::CellStore* cell = MWMechanics::getPlayer().getCell(); - std::string_view current = MWBase::Environment::get().getWorld()->getCellName(cell); + std::string_view current = MWBase::Environment::get().getWorld()->getCellName(cell).getRefIdString(); bool match = Misc::StringUtils::ciCompareLen(name, current, name.length()) == 0; runtime.push(match ? 1 : 0); diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index d183d45915..4266399bd9 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -126,8 +126,9 @@ namespace MWScript for (auto it = cells.extBegin(); it != cells.extEnd(); ++it) { - if (Misc::StringUtils::ciStartsWith(it->mName, cell)) - winMgr->addVisitedLocation(it->mName, it->getGridX(), it->getGridY()); + const auto& cellName = it->mName.getRefIdString(); + if (Misc::StringUtils::ciStartsWith(cellName, cell)) + winMgr->addVisitedLocation(cellName, it->getGridX(), it->getGridY()); } } }; @@ -142,7 +143,7 @@ namespace MWScript for (auto it = cells.extBegin(); it != cells.extEnd(); ++it) { - const std::string& name = it->mName; + const std::string& name = it->mName.getRefIdString(); if (!name.empty()) MWBase::Environment::get().getWindowManager()->addVisitedLocation( name, it->getGridX(), it->getGridY()); diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 7508d4a785..544902805f 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -414,7 +414,7 @@ namespace MWScript std::string_view InterpreterContext::getCurrentCellName() const { - return MWBase::Environment::get().getWorld()->getCellName(); + return MWBase::Environment::get().getWorld()->getCellName().getRefIdString(); } void InterpreterContext::executeActivation(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 4ab329966c..348ff2340b 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -382,7 +382,7 @@ namespace MWScript runtime.pop(); Interpreter::Type_Float zRot = runtime[0].mFloat; runtime.pop(); - std::string_view cellID = runtime.getStringLiteral(runtime[0].mInteger); + const ESM::RefId cellID = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger)); runtime.pop(); if (ptr.getContainerStore()) @@ -409,7 +409,7 @@ namespace MWScript if (!cell) { std::string error - = "Warning: PositionCell: unknown interior cell (" + std::string(cellID) + ")"; + = "Warning: PositionCell: unknown interior cell (" + cellID.getRefIdString() + ")"; if (isPlayer) error += ", moving to exterior instead"; runtime.getContext().report(error); @@ -504,7 +504,7 @@ namespace MWScript { const ESM::RefId itemID = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger)); runtime.pop(); - std::string_view cellID = runtime.getStringLiteral(runtime[0].mInteger); + auto cellID = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger)); runtime.pop(); Interpreter::Type_Float x = runtime[0].mFloat; @@ -528,7 +528,7 @@ namespace MWScript store = MWBase::Environment::get().getWorldModel()->getExterior(cellIndex.x(), cellIndex.y()); if (!cell) { - runtime.getContext().report("unknown cell (" + std::string(cellID) + ")"); + runtime.getContext().report("unknown cell (" + cellID.getRefIdString() + ")"); Log(Debug::Error) << "Error: unknown cell (" << cellID << ")"; } } diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 6f5c63d3a8..89f37eb82f 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -222,7 +222,7 @@ void MWState::StateManager::saveGame(const std::string& description, const Slot* else profile.mPlayerClassId = classId; - profile.mPlayerCell = ESM::RefId::stringRefId(world.getCellName()); + profile.mPlayerCell = world.getCellName(); profile.mInGameTime = world.getEpochTimeStamp(); profile.mTimePlayed = mTimePlayed; profile.mDescription = description; diff --git a/apps/openmw/mwworld/actionteleport.cpp b/apps/openmw/mwworld/actionteleport.cpp index 195eaff43d..29e2687aa4 100644 --- a/apps/openmw/mwworld/actionteleport.cpp +++ b/apps/openmw/mwworld/actionteleport.cpp @@ -17,7 +17,7 @@ namespace MWWorld { - ActionTeleport::ActionTeleport(std::string_view cellName, const ESM::Position& position, bool teleportFollowers) + ActionTeleport::ActionTeleport(const ESM::RefId& cellName, const ESM::Position& position, bool teleportFollowers) : Action(true) , mCellName(cellName) , mPosition(position) diff --git a/apps/openmw/mwworld/actionteleport.hpp b/apps/openmw/mwworld/actionteleport.hpp index cbdd59cc87..ba15e77725 100644 --- a/apps/openmw/mwworld/actionteleport.hpp +++ b/apps/openmw/mwworld/actionteleport.hpp @@ -13,7 +13,7 @@ namespace MWWorld { class ActionTeleport : public Action { - std::string mCellName; + ESM::RefId mCellName; ESM::Position mPosition; bool mTeleportFollowers; @@ -26,7 +26,7 @@ namespace MWWorld public: /// If cellName is empty, an exterior cell is assumed. /// @param teleportFollowers Whether to teleport any following actors of the target actor as well. - ActionTeleport(std::string_view cellName, const ESM::Position& position, bool teleportFollowers); + ActionTeleport(const ESM::RefId& cellName, const ESM::Position& position, bool teleportFollowers); /// @param includeHostiles If true, include hostile followers (which won't actually be teleported) in the /// output, diff --git a/apps/openmw/mwworld/cellref.hpp b/apps/openmw/mwworld/cellref.hpp index e0b589c408..13db1daa66 100644 --- a/apps/openmw/mwworld/cellref.hpp +++ b/apps/openmw/mwworld/cellref.hpp @@ -47,7 +47,7 @@ namespace MWWorld const ESM::Position& getDoorDest() const { return mCellRef.mDoorDest; } // Destination cell for doors (optional) - const std::string& getDestCell() const { return mCellRef.mDestCell; } + const ESM::RefId& getDestCell() const { return mCellRef.mDestCell; } // Scale applied to mesh float getScale() const { return mCellRef.mScale; } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index e0b0783834..b2922b56d3 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -462,7 +462,7 @@ namespace MWWorld // interior cell -> need to check if it exists (exterior cell will be // generated on the fly) - if (!world.getStore().get().search(ESM::RefId::stringRefId(player.mMarkedCell.mWorldspace))) + if (!world.getStore().get().search(player.mMarkedCell.mWorldspace)) player.mHasMark = false; // drop mark silently } diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 8d5672f7ce..e5c28a381b 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -841,7 +841,7 @@ namespace MWWorld } void Scene::changeToInteriorCell( - const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent) + const ESM::RefId& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent) { CellStore* cell = mWorld.getWorldModel().getInterior(cellName); bool useFading = (mCurrentCell != nullptr); diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index 5b2fdca317..6e6607840a 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -163,7 +163,7 @@ namespace MWWorld void resetCellLoaded() { mCellLoaded = false; } void changeToInteriorCell( - const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true); + const ESM::RefId& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true); ///< Move to interior cell. /// @param changeEvent Set cellChanged flag? diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index 6c55d35724..9f4bb8ccaa 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -455,7 +455,7 @@ namespace MWWorld { return search(cell.getGridX(), cell.getGridY()); } - return search(ESM::RefId::stringRefId(cell.mName)); + return search(cell.mName); } // this method *must* be called right after esm3.loadCell() @@ -613,7 +613,7 @@ namespace MWWorld if (cell.mData.mFlags & ESM::Cell::Interior) { // Store interior cell by name, try to merge with existing parent data. - ESM::Cell* oldcell = const_cast(search(ESM::RefId::stringRefId(cell.mName))); + ESM::Cell* oldcell = const_cast(search(cell.mName)); if (oldcell) { // merge new cell into old cell @@ -628,7 +628,7 @@ namespace MWWorld // spawn a new cell cell.loadCell(esm, true); - mInt[ESM::RefId::stringRefId(cell.mName)] = cell; + mInt[cell.mName] = cell; } } else @@ -693,7 +693,7 @@ namespace MWWorld } } - return RecordId(ESM::RefId::stringRefId(cell.mName), isDeleted); + return RecordId(cell.mName, isDeleted); } Store::iterator Store::intBegin() const { @@ -716,7 +716,7 @@ namespace MWWorld const ESM::Cell* cell = nullptr; for (const ESM::Cell* sharedCell : mSharedExt) { - if (ESM::RefId::stringRefId(sharedCell->mName) == id) + if (sharedCell->mName == id) { if (cell == nullptr || (sharedCell->mData.mX > cell->mData.mX) || (sharedCell->mData.mX == cell->mData.mX && sharedCell->mData.mY > cell->mData.mY)) @@ -761,7 +761,7 @@ namespace MWWorld for (const ESM::Cell* sharedCell : mSharedInt) { - list.push_back(ESM::RefId::stringRefId(sharedCell->mName)); + list.push_back(sharedCell->mName); } } ESM::Cell* Store::insert(const ESM::Cell& cell) @@ -783,7 +783,7 @@ namespace MWWorld else { // duplicate insertions are avoided by search(ESM::Cell &) - DynamicInt::iterator result = mDynamicInt.emplace(ESM::RefId::stringRefId(cell.mName), cell).first; + DynamicInt::iterator result = mDynamicInt.emplace(cell.mName, cell).first; mSharedInt.push_back(&result->second); return &result->second; } @@ -794,7 +794,7 @@ namespace MWWorld { return erase(cell.getGridX(), cell.getGridY()); } - return erase(ESM::RefId::stringRefId(cell.mName)); + return erase(cell.mName); } bool Store::erase(const ESM::RefId& id) { @@ -942,14 +942,14 @@ namespace MWWorld if (!(cell.mData.mFlags & ESM::Cell::Interior)) return search(cell.mData.mX, cell.mData.mY); else - return search(ESM::RefId::stringRefId(cell.mName)); + return search(cell.mName); } const ESM::Pathgrid* Store::find(const ESM::Cell& cell) const { if (!(cell.mData.mFlags & ESM::Cell::Interior)) return find(cell.mData.mX, cell.mData.mY); else - return find(ESM::RefId::stringRefId(cell.mName)); + return find(cell.mName); } // Skill diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 6b5203b291..cdb47d0ef6 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -155,7 +155,7 @@ namespace MWWorld World::World(osgViewer::Viewer* viewer, osg::ref_ptr rootNode, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, SceneUtil::UnrefQueue& unrefQueue, const Files::Collections& fileCollections, const std::vector& contentFiles, const std::vector& groundcoverFiles, - ToUTF8::Utf8Encoder* encoder, int activationDistanceOverride, const std::string& startCell, + ToUTF8::Utf8Encoder* encoder, int activationDistanceOverride, const ESM::RefId& startCell, const std::string& startupScript, const std::filesystem::path& resourcePath, const std::filesystem::path& userDataPath) : mResourceSystem(resourceSystem) @@ -565,15 +565,15 @@ namespace MWWorld mRandomSeed = seed; } - const ESM::Cell* World::getExterior(std::string_view cellName) const + const ESM::Cell* World::getExterior(const ESM::RefId& cellName) const { // first try named cells - const ESM::Cell* cell = mStore.get().searchExtByName(ESM::RefId::stringRefId(cellName)); + const ESM::Cell* cell = mStore.get().searchExtByName(cellName); if (cell) return cell; // treat "Wilderness" like an empty string - const std::string defaultName = mStore.get().find("sDefaultCellname")->mValue.getString(); - if (Misc::StringUtils::ciEqual(cellName, defaultName)) + const ESM::RefId defaultName = ESM::RefId::stringRefId(mStore.get().find("sDefaultCellname")->mValue.getString()); + if (cellName == defaultName) { cell = mStore.get().searchExtByName(ESM::RefId::sEmpty); if (cell) @@ -583,7 +583,7 @@ namespace MWWorld // didn't work -> now check for regions for (const ESM::Region& region : mStore.get()) { - if (Misc::StringUtils::ciEqual(cellName, region.mName)) + if (Misc::StringUtils::ciEqual(cellName.getRefIdString(), region.mName)) { return mStore.get().searchExtByRegion(region.mId); } @@ -655,14 +655,14 @@ namespace MWWorld return mCurrentDate->getMonthName(month); } - std::string_view World::getCellName(const MWWorld::CellStore* cell) const + const ESM::RefId& World::getCellName(const MWWorld::CellStore* cell) const { if (!cell) cell = mWorldScene->getCurrentCell(); return getCellName(cell->getCell()); } - std::string_view World::getCellName(const ESM::Cell* cell) const + const ESM::RefId World::getCellName(const ESM::Cell* cell) const { if (cell) { @@ -670,9 +670,9 @@ namespace MWWorld return cell->mName; if (const ESM::Region* region = mStore.get().search(cell->mRegion)) - return region->mName; + return ESM::RefId::stringRefId( region->mName); } - return mStore.get().find("sDefaultCellname")->mValue.getString(); + return ESM::RefId::stringRefId(mStore.get().find("sDefaultCellname")->mValue.getString()); } void World::removeRefScript(MWWorld::RefData* ref) @@ -954,12 +954,12 @@ namespace MWWorld } void World::changeToInteriorCell( - const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent) + const ESM::RefId& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent) { mPhysics->clearQueuedMovement(); mDiscardMovements = true; - if (changeEvent && !Misc::StringUtils::ciEqual(mCurrentWorldSpace, cellName)) + if (changeEvent && mCurrentWorldSpace != cellName) { // changed worldspace mProjectileManager->clear(); @@ -1421,10 +1421,10 @@ namespace MWWorld esmPos.pos[0] = traced.x(); esmPos.pos[1] = traced.y(); esmPos.pos[2] = traced.z(); - std::string_view cell; + const ESM::RefId* cell; if (!actor.getCell()->isExterior()) - cell = actor.getCell()->getCell()->mName; - MWWorld::ActionTeleport(cell, esmPos, false).execute(actor); + cell = &actor.getCell()->getCell()->mName; + MWWorld::ActionTeleport(*cell, esmPos, false).execute(actor); } } @@ -2782,7 +2782,7 @@ namespace MWWorld physicActor->enableCollisionBody(enable); } - bool World::findInteriorPosition(std::string_view name, ESM::Position& pos) + bool World::findInteriorPosition(const ESM::RefId& name, ESM::Position& pos) { pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; pos.pos[0] = pos.pos[1] = pos.pos[2] = 0; @@ -2831,7 +2831,7 @@ namespace MWWorld // and use its destination to position inside cell. for (const MWWorld::LiveCellRef& destDoor : source->getReadOnlyDoors().mList) { - if (Misc::StringUtils::ciEqual(name, destDoor.mRef.getDestCell())) + if (name == destDoor.mRef.getDestCell()) { /// \note Using _any_ door pointed to the interior, /// not the one pointed to current door. @@ -2854,11 +2854,11 @@ namespace MWWorld return false; } - bool World::findExteriorPosition(std::string_view name, ESM::Position& pos) + bool World::findExteriorPosition(const ESM::RefId& nameId, ESM::Position& pos) { pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; - - const ESM::Cell* ext = getExterior(name); + const std::string& name = nameId.getRefIdString(); + const ESM::Cell* ext = getExterior(nameId); if (!ext) { size_t comma = name.find(','); @@ -3278,9 +3278,9 @@ namespace MWWorld // Search for a 'nearest' exterior, counting each cell between the starting // cell and the exterior as a distance of 1. Will fail for isolated interiors. - std::set checkedCells; - std::set currentCells; - std::set nextCells; + std::set checkedCells; + std::set currentCells; + std::set nextCells; nextCells.insert(cell->getCell()->mName); while (!nextCells.empty()) @@ -3307,7 +3307,7 @@ namespace MWWorld } else { - const std::string& dest = ref.mRef.getDestCell(); + const ESM::RefId& dest = ref.mRef.getDestCell(); if (!checkedCells.count(dest) && !currentCells.count(dest)) nextCells.insert(dest); } @@ -3331,9 +3331,9 @@ namespace MWWorld // Search for a 'nearest' marker, counting each cell between the starting // cell and the exterior as a distance of 1. If an exterior is found, jump // to the nearest exterior marker, without further interior searching. - std::set checkedCells; - std::set currentCells; - std::set nextCells; + std::set checkedCells; + std::set currentCells; + std::set nextCells; MWWorld::ConstPtr closestMarker; nextCells.insert(ptr.getCell()->getCell()->mName); @@ -3429,11 +3429,11 @@ namespace MWWorld return; } - std::string_view cellName; + const ESM::RefId* cellName; if (!closestMarker.mCell->isExterior()) - cellName = closestMarker.mCell->getCell()->mName; + cellName = &closestMarker.mCell->getCell()->mName; - MWWorld::ActionTeleport action(cellName, closestMarker.getRefData().getPosition(), false); + MWWorld::ActionTeleport action(*cellName, closestMarker.getRefData().getPosition(), false); action.execute(ptr); } @@ -3635,7 +3635,7 @@ namespace MWWorld Log(Debug::Warning) << "Failed to confiscate items: no closest prison marker found."; return; } - const std::string& prisonName = prisonMarker.getCellRef().getDestCell(); + const ESM::RefId& prisonName = prisonMarker.getCellRef().getDestCell(); if (prisonName.empty()) { Log(Debug::Warning) << "Failed to confiscate items: prison marker not linked to prison interior"; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index cd81c8717c..d833438978 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -94,7 +94,7 @@ namespace MWWorld WorldModel mWorldModel; std::vector mESMVersions; // the versions of esm files - std::string mCurrentWorldSpace; + ESM::RefId mCurrentWorldSpace; std::unique_ptr mPlayer; std::unique_ptr mPhysics; @@ -118,7 +118,7 @@ namespace MWWorld int mActivationDistanceOverride; - std::string mStartCell; + ESM::RefId mStartCell; float mSwimHeightScale; @@ -200,7 +200,7 @@ namespace MWWorld SceneUtil::WorkQueue* workQueue, SceneUtil::UnrefQueue& unrefQueue, const Files::Collections& fileCollections, const std::vector& contentFiles, const std::vector& groundcoverFiles, ToUTF8::Utf8Encoder* encoder, - int activationDistanceOverride, const std::string& startCell, const std::string& startupScript, + int activationDistanceOverride, const ESM::RefId& startCell, const std::string& startupScript, const std::filesystem::path& resourcePath, const std::filesystem::path& userDataPath); virtual ~World(); @@ -267,12 +267,12 @@ namespace MWWorld char getGlobalVariableType(std::string_view name) const override; ///< Return ' ', if there is no global variable with this name. - std::string_view getCellName(const MWWorld::CellStore* cell = nullptr) const override; + const ESM::RefId& getCellName(const MWWorld::CellStore* cell = nullptr) const override; ///< Return name of the cell. /// /// \note If cell==0, the cell the player is currently in will be used instead to /// generate a name. - std::string_view getCellName(const ESM::Cell* cell) const override; + const ESM::RefId getCellName(const ESM::Cell* cell) const override; void removeRefScript(MWWorld::RefData* ref) override; //< Remove the script attached to ref from mLocalScripts @@ -344,7 +344,7 @@ namespace MWWorld void setSimulationTimeScale(float scale) override; - void changeToInteriorCell(const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, + void changeToInteriorCell(const ESM::RefId& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true) override; ///< Move to interior cell. ///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes @@ -358,7 +358,7 @@ namespace MWWorld bool changeEvent = true) override; ///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes - const ESM::Cell* getExterior(std::string_view cellName) const override; + const ESM::Cell* getExterior(const ESM::RefId& cellName) const override; ///< Return a cell matching the given name or a 0-pointer, if there is no such cell. MWWorld::Ptr getFacedObject() override; @@ -609,11 +609,11 @@ namespace MWWorld /// Find center of exterior cell above land surface /// \return false if exterior with given name not exists, true otherwise - bool findExteriorPosition(std::string_view name, ESM::Position& pos) override; + bool findExteriorPosition(const ESM::RefId& name, ESM::Position& pos) override; /// Find position in interior cell near door entrance /// \return false if interior with given name not exists, true otherwise - bool findInteriorPosition(std::string_view name, ESM::Position& pos) override; + bool findInteriorPosition(const ESM::RefId& name, ESM::Position& pos) override; /// Enables or disables use of teleport spell effects (recall, intervention, etc). void enableTeleporting(bool enable) override; diff --git a/apps/openmw/mwworld/worldmodel.cpp b/apps/openmw/mwworld/worldmodel.cpp index 99402c1e35..a39f049c4f 100644 --- a/apps/openmw/mwworld/worldmodel.cpp +++ b/apps/openmw/mwworld/worldmodel.cpp @@ -62,11 +62,10 @@ MWWorld::CellStore* MWWorld::WorldModel::getCellStore(const ESM::Cell* cell) { if (cell->mData.mFlags & ESM::Cell::Interior) { - std::string lowerName(Misc::StringUtils::lowerCase(cell->mName)); - auto result = mInteriors.find(lowerName); + auto result = mInteriors.find(cell->mName); if (result == mInteriors.end()) - result = mInteriors.emplace(std::move(lowerName), CellStore(cell, mStore, mReaders)).first; + result = mInteriors.emplace(std::move(cell->mName), CellStore(cell, mStore, mReaders)).first; return &result->second; } @@ -170,16 +169,15 @@ MWWorld::CellStore* MWWorld::WorldModel::getExterior(int x, int y) return &result->second; } -MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name) +MWWorld::CellStore* MWWorld::WorldModel::getInterior(const ESM::RefId& name) { - std::string lowerName = Misc::StringUtils::lowerCase(name); - auto result = mInteriors.find(lowerName); + auto result = mInteriors.find(name); if (result == mInteriors.end()) { - const ESM::Cell* cell = mStore.get().find(ESM::RefId::stringRefId(name)); + const ESM::Cell* cell = mStore.get().find(name); - result = mInteriors.emplace(lowerName, CellStore(cell, mStore, mReaders)).first; + result = mInteriors.emplace(name, CellStore(cell, mStore, mReaders)).first; } if (result->second.getState() != CellStore::State_Loaded) diff --git a/apps/openmw/mwworld/worldmodel.hpp b/apps/openmw/mwworld/worldmodel.hpp index 96907639bf..2ec569ce90 100644 --- a/apps/openmw/mwworld/worldmodel.hpp +++ b/apps/openmw/mwworld/worldmodel.hpp @@ -32,7 +32,7 @@ namespace MWWorld typedef std::vector> IdCache; const MWWorld::ESMStore& mStore; ESM::ReadersCache& mReaders; - mutable std::map mInteriors; + mutable std::map mInteriors; mutable std::map, CellStore> mExteriors; IdCache mIdCache; std::size_t mIdCacheIndex; @@ -55,7 +55,7 @@ namespace MWWorld CellStore* getExterior(int x, int y); - CellStore* getInterior(std::string_view name); + CellStore* getInterior(const ESM::RefId& name); CellStore* getCell(const ESM::CellId& id); diff --git a/components/detournavigator/navigator.hpp b/components/detournavigator/navigator.hpp index b34ec4e4d0..2015730de4 100644 --- a/components/detournavigator/navigator.hpp +++ b/components/detournavigator/navigator.hpp @@ -16,6 +16,7 @@ namespace ESM { struct Cell; struct Pathgrid; + struct RefId; } namespace Loading @@ -91,6 +92,8 @@ namespace DetourNavigator */ virtual void setWorldspace(std::string_view worldspace, const UpdateGuard* guard) = 0; + virtual void setWorldspace(const ESM::RefId& worldspace, const UpdateGuard* guard) = 0; + /** * @brief updateBounds should be called before adding object from loading cell * @param playerPosition corresponds to the bounds center diff --git a/components/detournavigator/navigatorimpl.cpp b/components/detournavigator/navigatorimpl.cpp index 181e950fdc..eb4871e865 100644 --- a/components/detournavigator/navigatorimpl.cpp +++ b/components/detournavigator/navigatorimpl.cpp @@ -5,6 +5,8 @@ #include #include #include +#include + namespace DetourNavigator { @@ -37,6 +39,10 @@ namespace DetourNavigator mNavMeshManager.setWorldspace(worldspace, getImpl(guard)); } + void NavigatorImpl::setWorldspace(const ESM::RefId& worldspace, const UpdateGuard* guard) { + setWorldspace(Misc::StringUtils::lowerCase(worldspace.getRefIdString()), guard); + } + void NavigatorImpl::updateBounds(const osg::Vec3f& playerPosition, const UpdateGuard* guard) { mNavMeshManager.updateBounds(playerPosition, getImpl(guard)); diff --git a/components/detournavigator/navigatorimpl.hpp b/components/detournavigator/navigatorimpl.hpp index 200c67128a..43a6b1dae6 100644 --- a/components/detournavigator/navigatorimpl.hpp +++ b/components/detournavigator/navigatorimpl.hpp @@ -29,6 +29,9 @@ namespace DetourNavigator void setWorldspace(std::string_view worldspace, const UpdateGuard* guard) override; + void setWorldspace(const ESM::RefId& worldspace, const UpdateGuard* guard) override; + + void updateBounds(const osg::Vec3f& playerPosition, const UpdateGuard* guard) override; void addObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform, diff --git a/components/detournavigator/navigatorstub.hpp b/components/detournavigator/navigatorstub.hpp index b0cd4ec387..8ead5907ab 100644 --- a/components/detournavigator/navigatorstub.hpp +++ b/components/detournavigator/navigatorstub.hpp @@ -24,6 +24,8 @@ namespace DetourNavigator void removeAgent(const AgentBounds& /*agentBounds*/) override {} void setWorldspace(std::string_view /*worldspace*/, const UpdateGuard* /*guard*/) override {} + void setWorldspace(const ESM::RefId& /*worldspace*/, const UpdateGuard* /*guard*/) override {} + void addObject(const ObjectId /*id*/, const ObjectShapes& /*shapes*/, const btTransform& /*transform*/, const UpdateGuard* /*guard*/) override diff --git a/components/esm3/cellid.cpp b/components/esm3/cellid.cpp index a63a1bfad6..64ca4c03ba 100644 --- a/components/esm3/cellid.cpp +++ b/components/esm3/cellid.cpp @@ -6,11 +6,11 @@ namespace ESM { - const std::string CellId::sDefaultWorldspace = "sys::default"; + const ESM::RefId CellId::sDefaultWorldspace = ESM::RefId::stringRefId("sys::default"); void CellId::load(ESMReader& esm) { - mWorldspace = esm.getHNString("SPAC"); + mWorldspace = ESM::RefId::stringRefId(esm.getHNString("SPAC")); if (esm.isNextSub("CIDX")) { @@ -23,7 +23,7 @@ namespace ESM void CellId::save(ESMWriter& esm) const { - esm.writeHNString("SPAC", mWorldspace); + esm.writeHNString("SPAC", mWorldspace.getRefIdString()); if (mPaged) esm.writeHNT("CIDX", mIndex, 8); diff --git a/components/esm3/cellid.hpp b/components/esm3/cellid.hpp index 12479dc2c6..2dbe9167d2 100644 --- a/components/esm3/cellid.hpp +++ b/components/esm3/cellid.hpp @@ -2,6 +2,7 @@ #define OPENMW_ESM_CELLID_H #include +#include namespace ESM { @@ -16,11 +17,11 @@ namespace ESM int mY; }; - std::string mWorldspace; + ESM::RefId mWorldspace; CellIndex mIndex; bool mPaged; - static const std::string sDefaultWorldspace; + static const ESM::RefId sDefaultWorldspace; void load(ESMReader& esm); void save(ESMWriter& esm) const; diff --git a/components/esm3/cellref.cpp b/components/esm3/cellref.cpp index ef03326b9d..d81c355b16 100644 --- a/components/esm3/cellref.cpp +++ b/components/esm3/cellref.cpp @@ -109,7 +109,7 @@ namespace ESM cellRef.mTeleport = true; break; case fourCC("DNAM"): - getHStringOrSkip(cellRef.mDestCell); + getRefIdOrSkip(cellRef.mDestCell); break; case fourCC("FLTV"): getHTOrSkip(cellRef.mLockLevel); @@ -235,7 +235,7 @@ namespace ESM if (!inInventory && mTeleport) { esm.writeHNT("DODT", mDoorDest); - esm.writeHNOCString("DNAM", mDestCell); + esm.writeHNOCString("DNAM", mDestCell.getRefIdString()); } if (!inInventory && mLockLevel != 0) @@ -270,7 +270,7 @@ namespace ESM mChargeIntRemainder = 0.0f; mEnchantmentCharge = -1; mGoldValue = 1; - mDestCell.clear(); + mDestCell = ESM::RefId::sEmpty; mLockLevel = 0; mKey = ESM::RefId::sEmpty; mTrap = ESM::RefId::sEmpty; diff --git a/components/esm3/cellref.hpp b/components/esm3/cellref.hpp index 2d6026b44a..b1b3ebed31 100644 --- a/components/esm3/cellref.hpp +++ b/components/esm3/cellref.hpp @@ -90,7 +90,7 @@ namespace ESM Position mDoorDest; // Destination cell for doors (optional) - std::string mDestCell; + ESM::RefId mDestCell; // Lock level for doors and containers int mLockLevel; diff --git a/components/esm3/loadcell.cpp b/components/esm3/loadcell.cpp index e354f71651..7c1e500ea3 100644 --- a/components/esm3/loadcell.cpp +++ b/components/esm3/loadcell.cpp @@ -71,7 +71,7 @@ namespace ESM switch (esm.retSubName().toInt()) { case SREC_NAME: - mName = esm.getHString(); + mName = esm.getRefId(); break; case fourCC("DATA"): esm.getHTSized<12>(mData); @@ -101,7 +101,7 @@ namespace ESM } else { - mCellId.mWorldspace = Misc::StringUtils::lowerCase(mName); + mCellId.mWorldspace = mName; mCellId.mIndex.mX = 0; mCellId.mIndex.mY = 0; } @@ -173,7 +173,7 @@ namespace ESM void Cell::save(ESMWriter& esm, bool isDeleted) const { - esm.writeHNCString("NAME", mName); + esm.writeHNCString("NAME", mName.getRefIdString()); esm.writeHNT("DATA", mData, 12); if (isDeleted) @@ -225,12 +225,13 @@ namespace ESM std::string Cell::getDescription() const { + const auto& nameString = mName.getRefIdString(); if (mData.mFlags & Interior) - return mName; + return nameString; std::string cellGrid = "(" + std::to_string(mData.mX) + ", " + std::to_string(mData.mY) + ")"; if (!mName.empty()) - return mName + ' ' + cellGrid; + return nameString + ' ' + cellGrid; // FIXME: should use sDefaultCellname GMST instead, but it's not available in this scope std::string region = !mRegion.empty() ? mRegion.getRefIdString() : "Wilderness"; @@ -314,7 +315,7 @@ namespace ESM void Cell::blank() { - mName.clear(); + mName = ESM::RefId::sEmpty; mRegion = ESM::RefId::sEmpty; mWater = 0; mWaterInt = false; diff --git a/components/esm3/loadcell.hpp b/components/esm3/loadcell.hpp index 3cf1834dfa..dd7fedf661 100644 --- a/components/esm3/loadcell.hpp +++ b/components/esm3/loadcell.hpp @@ -101,7 +101,7 @@ namespace ESM }; Cell() - : mName("") + : mName(ESM::RefId::sEmpty) , mRegion(ESM::RefId()) , mHasAmbi(true) , mWater(0) @@ -113,7 +113,7 @@ namespace ESM // Interior cells are indexed by this (it's the 'id'), for exterior // cells it is optional. - std::string mName; + ESM::RefId mName; // Optional region name for exterior and quasi-exterior cells. RefId mRegion; diff --git a/components/esmloader/load.cpp b/components/esmloader/load.cpp index 6b516898ca..6783ec416b 100644 --- a/components/esmloader/load.cpp +++ b/components/esmloader/load.cpp @@ -59,7 +59,7 @@ namespace EsmLoader struct CellRecords { Records mValues; - std::map mByName; + std::map mByName; std::map, std::size_t> mByPosition; }; @@ -101,7 +101,6 @@ namespace EsmLoader ESM::Cell record; bool deleted = false; record.loadNameAndData(reader, deleted); - Misc::StringUtils::lowerCaseInPlace(record.mName); if ((record.mData.mFlags & ESM::Cell::Interior) != 0) {