1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-05-12 21:11:27 +00:00

Merge branch 'Revert_CellName_Type' into 'master'

Revert the usage of ESM::RefID for cell names.

See merge request OpenMW/openmw!2642
This commit is contained in:
psi29a 2023-01-21 22:32:29 +00:00
commit f5cacad426
80 changed files with 313 additions and 335 deletions

View file

@ -1342,7 +1342,7 @@ namespace EsmTool
template <> template <>
std::string Record<ESM::Cell>::getId() const std::string Record<ESM::Cell>::getId() const
{ {
return mData.mName.getRefIdString(); return mData.mName;
} }
template <> template <>

View file

@ -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 // note if the player is in a nameless exterior cell, we will assign the cellId later based on player position
if (cell.mName == ESM::RefId::stringRefId(mContext->mPlayerCellName)) if (Misc::StringUtils::ciEqual(cell.mName, mContext->mPlayerCellName))
{ {
mContext->mPlayer.mCellId = cell.getCellId(); mContext->mPlayer.mCellId = cell.getCellId();
} }

View file

@ -351,7 +351,7 @@ namespace ESSImport
std::vector<unsigned int> mFogOfWar; std::vector<unsigned int> mFogOfWar;
}; };
std::map<ESM::RefId, Cell> mIntCells; std::map<std::string, Cell, Misc::StringUtils::CiComp> mIntCells;
std::map<std::pair<int, int>, Cell> mExtCells; std::map<std::pair<int, int>, Cell> mExtCells;
std::vector<ESM::CustomMarker> mMarkers; std::vector<ESM::CustomMarker> mMarkers;

View file

@ -70,7 +70,7 @@ namespace ESSImport
// TODO: Figure out a better way to detect interiors. (0, 0) is a valid exterior cell. // TODO: Figure out a better way to detect interiors. (0, 0) is a valid exterior cell.
if (mark.mCellX == 0 && mark.mCellY == 0) if (mark.mCellX == 0 && mark.mCellY == 0)
{ {
cell.mWorldspace = ESM::RefId::stringRefId(pcdt.mMNAM); cell.mWorldspace = pcdt.mMNAM;
cell.mPaged = false; cell.mPaged = false;
} }

View file

@ -49,5 +49,5 @@ QString CellNameLoader::getCellName(ESM::ESMReader& esmReader)
bool isDeleted = false; bool isDeleted = false;
cell.loadNameAndData(esmReader, isDeleted); cell.loadNameAndData(esmReader, isDeleted);
return QString::fromStdString(cell.mName.getRefIdString()); return QString::fromStdString(cell.mName);
} }

View file

@ -8,7 +8,6 @@
#include <components/detournavigator/navmeshdb.hpp> #include <components/detournavigator/navmeshdb.hpp>
#include <components/detournavigator/recastglobalallocator.hpp> #include <components/detournavigator/recastglobalallocator.hpp>
#include <components/detournavigator/settings.hpp> #include <components/detournavigator/settings.hpp>
#include <components/esm/refid.hpp>
#include <components/esm3/readerscache.hpp> #include <components/esm3/readerscache.hpp>
#include <components/esm3/variant.hpp> #include <components/esm3/variant.hpp>
#include <components/esmloader/esmdata.hpp> #include <components/esmloader/esmdata.hpp>

View file

@ -106,7 +106,7 @@ namespace NavMeshTool
return DetourNavigator::resolveMeshSource(mDb, source, mNextShapeId); return DetourNavigator::resolveMeshSource(mDb, source, mNextShapeId);
} }
std::optional<NavMeshTileInfo> find(const ESM::RefId& worldspace, const TilePosition& tilePosition, std::optional<NavMeshTileInfo> find(std::string_view worldspace, const TilePosition& tilePosition,
const std::vector<std::byte>& input) override const std::vector<std::byte>& input) override
{ {
std::optional<NavMeshTileInfo> result; std::optional<NavMeshTileInfo> result;
@ -121,7 +121,7 @@ namespace NavMeshTool
return result; return result;
} }
void ignore(const ESM::RefId& worldspace, const TilePosition& tilePosition) override void ignore(std::string_view worldspace, const TilePosition& tilePosition) override
{ {
if (mRemoveUnusedTiles) if (mRemoveUnusedTiles)
{ {
@ -131,7 +131,7 @@ namespace NavMeshTool
report(); report();
} }
void identity(const ESM::RefId& worldspace, const TilePosition& tilePosition, std::int64_t tileId) override void identity(std::string_view worldspace, const TilePosition& tilePosition, std::int64_t tileId) override
{ {
if (mRemoveUnusedTiles) if (mRemoveUnusedTiles)
{ {
@ -142,7 +142,7 @@ namespace NavMeshTool
report(); report();
} }
void insert(const ESM::RefId& worldspace, const TilePosition& tilePosition, std::int64_t version, void insert(std::string_view worldspace, const TilePosition& tilePosition, std::int64_t version,
const std::vector<std::byte>& input, PreparedNavMeshData& data) override const std::vector<std::byte>& input, PreparedNavMeshData& data) override
{ {
{ {
@ -158,7 +158,7 @@ namespace NavMeshTool
report(); report();
} }
void update(const ESM::RefId& worldspace, const TilePosition& tilePosition, std::int64_t tileId, void update(std::string_view worldspace, const TilePosition& tilePosition, std::int64_t tileId,
std::int64_t version, PreparedNavMeshData& data) override std::int64_t version, PreparedNavMeshData& data) override
{ {
data.mUserId = static_cast<unsigned>(tileId); data.mUserId = static_cast<unsigned>(tileId);
@ -217,7 +217,7 @@ namespace NavMeshTool
mDb.vacuum(); mDb.vacuum();
} }
void removeTilesOutsideRange(const ESM::RefId& worldspace, const TilesPositionsRange& range) void removeTilesOutsideRange(std::string_view worldspace, const TilesPositionsRange& range)
{ {
const std::lock_guard lock(mMutex); const std::lock_guard lock(mMutex);
mTransaction.commit(); mTransaction.commit();

View file

@ -8,7 +8,6 @@
#include <components/detournavigator/recastmesh.hpp> #include <components/detournavigator/recastmesh.hpp>
#include <components/detournavigator/settings.hpp> #include <components/detournavigator/settings.hpp>
#include <components/detournavigator/tilecachedrecastmeshmanager.hpp> #include <components/detournavigator/tilecachedrecastmeshmanager.hpp>
#include <components/esm/refid.hpp>
#include <components/esm3/cellref.hpp> #include <components/esm3/cellref.hpp>
#include <components/esm3/esmreader.hpp> #include <components/esm3/esmreader.hpp>
#include <components/esm3/loadcell.hpp> #include <components/esm3/loadcell.hpp>
@ -30,6 +29,7 @@
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <algorithm> #include <algorithm>
#include <components/esm/refid.hpp>
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
@ -37,7 +37,6 @@
#include <tuple> #include <tuple>
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace NavMeshTool namespace NavMeshTool
{ {
namespace namespace
@ -222,7 +221,7 @@ namespace NavMeshTool
} }
WorldspaceNavMeshInput::WorldspaceNavMeshInput( WorldspaceNavMeshInput::WorldspaceNavMeshInput(
ESM::RefId worldspace, const DetourNavigator::RecastSettings& settings) std::string worldspace, const DetourNavigator::RecastSettings& settings)
: mWorldspace(std::move(worldspace)) : mWorldspace(std::move(worldspace))
, mTileCachedRecastMeshManager(settings) , mTileCachedRecastMeshManager(settings)
{ {
@ -236,7 +235,7 @@ namespace NavMeshTool
{ {
Log(Debug::Info) << "Processing " << esmData.mCells.size() << " cells..."; Log(Debug::Info) << "Processing " << esmData.mCells.size() << " cells...";
std::map<ESM::RefId, std::unique_ptr<WorldspaceNavMeshInput>> navMeshInputs; std::map<std::string_view, std::unique_ptr<WorldspaceNavMeshInput>> navMeshInputs;
WorldspaceData data; WorldspaceData data;
std::size_t objectsCounter = 0; std::size_t objectsCounter = 0;
@ -264,15 +263,16 @@ namespace NavMeshTool
const osg::Vec2i cellPosition(cell.mData.mX, cell.mData.mY); const osg::Vec2i cellPosition(cell.mData.mX, cell.mData.mY);
const std::size_t cellObjectsBegin = data.mObjects.size(); const std::size_t cellObjectsBegin = data.mObjects.size();
const auto cellNameLowerCase = Misc::StringUtils::lowerCase(cell.mCellId.mWorldspace);
WorldspaceNavMeshInput& navMeshInput = [&]() -> WorldspaceNavMeshInput& { WorldspaceNavMeshInput& navMeshInput = [&]() -> WorldspaceNavMeshInput& {
auto it = navMeshInputs.find(cell.mCellId.mWorldspace); auto it = navMeshInputs.find(cellNameLowerCase);
if (it == navMeshInputs.end()) if (it == navMeshInputs.end())
{ {
it = navMeshInputs it = navMeshInputs
.emplace(cell.mCellId.mWorldspace, .emplace(cellNameLowerCase,
std::make_unique<WorldspaceNavMeshInput>(cell.mCellId.mWorldspace, settings.mRecast)) std::make_unique<WorldspaceNavMeshInput>(cellNameLowerCase, settings.mRecast))
.first; .first;
it->second->mTileCachedRecastMeshManager.setWorldspace(cell.mCellId.mWorldspace, nullptr); it->second->mTileCachedRecastMeshManager.setWorldspace(cellNameLowerCase, nullptr);
} }
return *it->second; return *it->second;
}(); }();

View file

@ -3,7 +3,6 @@
#include <components/bullethelpers/collisionobject.hpp> #include <components/bullethelpers/collisionobject.hpp>
#include <components/detournavigator/tilecachedrecastmeshmanager.hpp> #include <components/detournavigator/tilecachedrecastmeshmanager.hpp>
#include <components/esm/refid.hpp>
#include <components/esm3/loadland.hpp> #include <components/esm3/loadland.hpp>
#include <components/misc/convert.hpp> #include <components/misc/convert.hpp>
#include <components/resource/bulletshape.hpp> #include <components/resource/bulletshape.hpp>
@ -49,12 +48,12 @@ namespace NavMeshTool
struct WorldspaceNavMeshInput struct WorldspaceNavMeshInput
{ {
ESM::RefId mWorldspace; std::string mWorldspace;
TileCachedRecastMeshManager mTileCachedRecastMeshManager; TileCachedRecastMeshManager mTileCachedRecastMeshManager;
btAABB mAabb; btAABB mAabb;
bool mAabbInitialized = false; bool mAabbInitialized = false;
explicit WorldspaceNavMeshInput(ESM::RefId worldspace, const DetourNavigator::RecastSettings& settings); explicit WorldspaceNavMeshInput(std::string worldspace, const DetourNavigator::RecastSettings& settings);
}; };
class BulletObject class BulletObject

View file

@ -88,8 +88,8 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages& message
} }
if (!cellRef.mDestCell.empty() && mCells.searchId(cellRef.mDestCell) == -1) if (!cellRef.mDestCell.empty() && mCells.searchId(cellRef.mDestCell) == -1)
messages.add(id, "Destination cell '" + cellRef.mDestCell.getRefIdString() + "' does not exist", "", messages.add(
CSMDoc::Message::Severity_Error); id, "Destination cell '" + cellRef.mDestCell + "' does not exist", "", CSMDoc::Message::Severity_Error);
if (cellRef.mScale < 0) if (cellRef.mScale < 0)
messages.add(id, "Negative scale", "", CSMDoc::Message::Severity_Error); messages.add(id, "Negative scale", "", CSMDoc::Message::Severity_Error);

View file

@ -75,7 +75,7 @@ int CSMTools::TopicInfoCheckStage::setup()
if (regionRecord.isDeleted()) if (regionRecord.isDeleted())
continue; continue;
mCellNames.insert(ESM::RefId::stringRefId(regionRecord.get().mName)); mCellNames.insert(regionRecord.get().mName);
} }
// Default cell name // Default cell name
int index = mGameSettings.searchId("sDefaultCellname"); int index = mGameSettings.searchId("sDefaultCellname");
@ -85,7 +85,7 @@ int CSMTools::TopicInfoCheckStage::setup()
if (!gmstRecord.isDeleted() && gmstRecord.get().mValue.getType() == ESM::VT_String) if (!gmstRecord.isDeleted() && gmstRecord.get().mValue.getType() == ESM::VT_String)
{ {
mCellNames.insert(ESM::RefId::stringRefId(gmstRecord.get().mValue.getString())); mCellNames.insert(gmstRecord.get().mValue.getString());
} }
} }
@ -130,7 +130,7 @@ void CSMTools::TopicInfoCheckStage::perform(int stage, CSMDoc::Messages& message
if (!topicInfo.mCell.empty()) if (!topicInfo.mCell.empty())
{ {
verifyCell(topicInfo.mCell, id, messages); verifyCell(topicInfo.mCell.getRefIdString(), id, messages);
} }
if (!topicInfo.mFaction.empty() && !topicInfo.mFactionLess) if (!topicInfo.mFaction.empty() && !topicInfo.mFactionLess)
@ -211,11 +211,11 @@ bool CSMTools::TopicInfoCheckStage::verifyActor(
} }
bool CSMTools::TopicInfoCheckStage::verifyCell( bool CSMTools::TopicInfoCheckStage::verifyCell(
const ESM::RefId& cell, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) const std::string& cell, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages)
{ {
if (mCellNames.find(cell) == mCellNames.end()) if (mCellNames.find(cell) == mCellNames.end())
{ {
messages.add(id, "Cell '" + cell.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error); messages.add(id, "Cell '" + cell + "' does not exist", "", CSMDoc::Message::Severity_Error);
return false; return false;
} }
@ -406,7 +406,7 @@ bool CSMTools::TopicInfoCheckStage::verifySelectStruct(
return false; return false;
} }
else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotCell else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotCell
&& !verifyCell(ESM::RefId::stringRefId(infoCondition.getVariableName()), id, messages)) && !verifyCell(infoCondition.getVariableName(), id, messages))
{ {
return false; return false;
} }

View file

@ -7,6 +7,7 @@
#include <apps/opencs/model/world/universalid.hpp> #include <apps/opencs/model/world/universalid.hpp>
#include <components/esm3/loadinfo.hpp> #include <components/esm3/loadinfo.hpp>
#include <components/misc/algorithm.hpp>
#include "../world/idcollection.hpp" #include "../world/idcollection.hpp"
@ -72,13 +73,13 @@ namespace CSMTools
const CSMWorld::RefIdData& mReferencables; const CSMWorld::RefIdData& mReferencables;
const CSMWorld::Resources& mSoundFiles; const CSMWorld::Resources& mSoundFiles;
std::set<ESM::RefId> mCellNames; std::set<std::string, Misc::StringUtils::CiComp> mCellNames;
bool mIgnoreBaseRecords; bool mIgnoreBaseRecords;
// These return false when not successful and write an error // These return false when not successful and write an error
bool verifyActor(const ESM::RefId& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); bool verifyActor(const ESM::RefId& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
bool verifyCell(const ESM::RefId& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); bool verifyCell(const std::string& cell, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
bool verifyFactionRank( bool verifyFactionRank(
const ESM::RefId& name, int rank, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); const ESM::RefId& name, int rank, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
bool verifyItem(const ESM::RefId& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); bool verifyItem(const ESM::RefId& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);

View file

@ -6,7 +6,7 @@ void CSMWorld::Cell::load(ESM::ESMReader& esm, bool& isDeleted)
{ {
ESM::Cell::load(esm, isDeleted, false); ESM::Cell::load(esm, isDeleted, false);
mId = mName; mId = ESM::RefId::stringRefId(mName);
if (isExterior()) if (isExterior())
{ {
std::ostringstream stream; std::ostringstream stream;

View file

@ -344,14 +344,14 @@ namespace CSMWorld
QVariant get(const Record<CSMWorld::Cell>& record) const override QVariant get(const Record<CSMWorld::Cell>& record) const override
{ {
return QString::fromUtf8(record.get().mName.getRefIdString().c_str()); return QString::fromUtf8(record.get().mName.c_str());
} }
void set(Record<CSMWorld::Cell>& record, const QVariant& data) override void set(Record<CSMWorld::Cell>& record, const QVariant& data) override
{ {
CSMWorld::Cell record2 = record.get(); CSMWorld::Cell record2 = record.get();
record2.mName = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record2.mName = data.toString().toUtf8().constData();
record.setModified(record2); record.setModified(record2);
} }
@ -1147,14 +1147,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override QVariant get(const Record<ESXRecordT>& record) const override
{ {
return QString::fromUtf8(record.get().mDestCell.getRefIdString().c_str()); return QString::fromUtf8(record.get().mDestCell.c_str());
} }
void set(Record<ESXRecordT>& record, const QVariant& data) override void set(Record<ESXRecordT>& record, const QVariant& data) override
{ {
ESXRecordT record2 = record.get(); ESXRecordT record2 = record.get();
record2.mDestCell = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record2.mDestCell = data.toString().toUtf8().constData();
record.setModified(record2); record.setModified(record2);
} }

View file

@ -333,7 +333,7 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view(int row) c
return std::make_pair(UniversalId::Type_None, ""); return std::make_pair(UniversalId::Type_None, "");
if (id[0] == '#') if (id[0] == '#')
id = ESM::CellId::sDefaultWorldspace.getRefIdString(); id = ESM::CellId::sDefaultWorldspace;
return std::make_pair(UniversalId(UniversalId::Type_Scene, id), hint); return std::make_pair(UniversalId(UniversalId::Type_Scene, id), hint);
} }

View file

@ -1468,7 +1468,7 @@ namespace CSMWorld
ESM::Transport::Dest newRow; ESM::Transport::Dest newRow;
newRow.mPos = newPos; newRow.mPos = newPos;
newRow.mCellName = ESM::RefId::sEmpty; newRow.mCellName.clear();
if (position >= (int)list.size()) if (position >= (int)list.size())
list.push_back(newRow); list.push_back(newRow);
@ -1533,7 +1533,7 @@ namespace CSMWorld
switch (subColIndex) switch (subColIndex)
{ {
case 0: case 0:
return QString::fromUtf8(content.mCellName.getRefIdString().c_str()); return QString::fromUtf8(content.mCellName.c_str());
case 1: case 1:
return content.mPos.pos[0]; return content.mPos.pos[0];
case 2: case 2:
@ -1565,7 +1565,7 @@ namespace CSMWorld
switch (subColIndex) switch (subColIndex)
{ {
case 0: case 0:
list.at(subRowIndex).mCellName = ESM::RefId::stringRefId(value.toString().toUtf8().constData()); list.at(subRowIndex).mCellName = value.toString().toUtf8().constData();
break; break;
case 1: case 1:
list.at(subRowIndex).mPos.pos[0] = value.toFloat(); list.at(subRowIndex).mPos.pos[0] = value.toFloat();

View file

@ -42,7 +42,7 @@ namespace CSMWorld
{ {
bool mDeleted; bool mDeleted;
ESM::RefId mRegion; ESM::RefId mRegion;
ESM::RefId mName; std::string mName;
CellDescription(); CellDescription();

View file

@ -49,7 +49,7 @@ CSVWorld::SceneSubView::SceneSubView(const CSMWorld::UniversalId& id, CSMDoc::Do
CSVRender::WorldspaceWidget* worldspaceWidget = nullptr; CSVRender::WorldspaceWidget* worldspaceWidget = nullptr;
widgetType whatWidget; widgetType whatWidget;
if (ESM::RefId::stringRefId(id.getId()) == ESM::CellId::sDefaultWorldspace) if (Misc::StringUtils::ciEqual(id.getId(), ESM::CellId::sDefaultWorldspace))
{ {
whatWidget = widget_Paged; whatWidget = widget_Paged;

View file

@ -444,7 +444,7 @@ void OMW::Engine::setResourceDir(const std::filesystem::path& parResDir)
// Set start cell name // Set start cell name
void OMW::Engine::setCell(const std::string& cellName) void OMW::Engine::setCell(const std::string& cellName)
{ {
mCellName = ESM::RefId::stringRefId(cellName); mCellName = cellName;
} }
void OMW::Engine::addContentFile(const std::string& file) void OMW::Engine::addContentFile(const std::string& file)

View file

@ -152,7 +152,7 @@ namespace OMW
osg::ref_ptr<SceneUtil::AsyncScreenCaptureOperation> mScreenCaptureOperation; osg::ref_ptr<SceneUtil::AsyncScreenCaptureOperation> mScreenCaptureOperation;
osg::ref_ptr<SceneUtil::SelectDepthFormatOperation> mSelectDepthFormatOperation; osg::ref_ptr<SceneUtil::SelectDepthFormatOperation> mSelectDepthFormatOperation;
osg::ref_ptr<SceneUtil::Color::SelectColorFormatOperation> mSelectColorFormatOperation; osg::ref_ptr<SceneUtil::Color::SelectColorFormatOperation> mSelectColorFormatOperation;
ESM::RefId mCellName; std::string mCellName;
std::vector<std::string> mContentFiles; std::vector<std::string> mContentFiles;
std::vector<std::string> mGroundcoverFiles; std::vector<std::string> mGroundcoverFiles;

View file

@ -245,7 +245,7 @@ namespace MWBase
virtual void setSimulationTimeScale(float scale) = 0; virtual void setSimulationTimeScale(float scale) = 0;
virtual void changeToInteriorCell( virtual void changeToInteriorCell(
const ESM::RefId& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true) std::string_view cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true)
= 0; = 0;
///< Move to interior cell. ///< Move to interior cell.
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes ///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
@ -513,11 +513,11 @@ namespace MWBase
/// Find default position inside exterior cell specified by name /// Find default position inside exterior cell specified by name
/// \return false if exterior with given name not exists, true otherwise /// \return false if exterior with given name not exists, true otherwise
virtual bool findExteriorPosition(const ESM::RefId& name, ESM::Position& pos) = 0; virtual bool findExteriorPosition(std::string_view name, ESM::Position& pos) = 0;
/// Find default position inside interior cell specified by name /// Find default position inside interior cell specified by name
/// \return false if interior with given name not exists, true otherwise /// \return false if interior with given name not exists, true otherwise
virtual bool findInteriorPosition(const ESM::RefId& name, ESM::Position& pos) = 0; virtual bool findInteriorPosition(std::string_view name, ESM::Position& pos) = 0;
/// Enables or disables use of teleport spell effects (recall, intervention, etc). /// Enables or disables use of teleport spell effects (recall, intervention, etc).
virtual void enableTeleporting(bool enable) = 0; virtual void enableTeleporting(bool enable) = 0;

View file

@ -299,7 +299,7 @@ namespace MWClass
std::string Door::getDestination(const MWWorld::LiveCellRef<ESM::Door>& door) std::string Door::getDestination(const MWWorld::LiveCellRef<ESM::Door>& door)
{ {
std::string_view dest = door.mRef.getDestCell().getRefIdString(); std::string_view dest = door.mRef.getDestCell();
if (dest.empty()) if (dest.empty())
{ {
// door leads to exterior, use cell name (if any), otherwise translated region name // door leads to exterior, use cell name (if any), otherwise translated region name

View file

@ -122,7 +122,7 @@ namespace MWGui
it != store.get<ESM::Cell>().extEnd(); ++it) it != store.get<ESM::Cell>().extEnd(); ++it)
{ {
if (!it->mName.empty()) if (!it->mName.empty())
mNames.push_back(it->mName.getRefIdString()); mNames.push_back(it->mName);
} }
// sort // sort

View file

@ -353,7 +353,7 @@ namespace MWGui
{ {
ESM::CellId cellId; ESM::CellId cellId;
cellId.mPaged = !mInterior; cellId.mPaged = !mInterior;
cellId.mWorldspace = (mInterior ? ESM::RefId::stringRefId(mPrefix) : ESM::CellId::sDefaultWorldspace); cellId.mWorldspace = (mInterior ? mPrefix : ESM::CellId::sDefaultWorldspace);
cellId.mIndex.mX = mCurX + dX; cellId.mIndex.mX = mCurX + dX;
cellId.mIndex.mY = mCurY + dY; cellId.mIndex.mY = mCurY + dY;
@ -637,7 +637,7 @@ namespace MWGui
for (MyGUI::Widget* widget : mExteriorDoorMarkerWidgets) for (MyGUI::Widget* widget : mExteriorDoorMarkerWidgets)
widget->setVisible(false); widget->setVisible(false);
MWWorld::CellStore* cell = worldModel->getInterior(ESM::RefId::stringRefId(mPrefix)); MWWorld::CellStore* cell = worldModel->getInterior(mPrefix);
world->getDoorMarkers(cell, doors); world->getDoorMarkers(cell, doors);
} }
else else
@ -705,7 +705,7 @@ namespace MWGui
ESM::Position markedPosition; ESM::Position markedPosition;
MWBase::Environment::get().getWorld()->getPlayer().getMarkedPosition(markedCell, markedPosition); MWBase::Environment::get().getWorld()->getPlayer().getMarkedPosition(markedCell, markedPosition);
if (markedCell && markedCell->isExterior() == !mInterior if (markedCell && markedCell->isExterior() == !mInterior
&& (!mInterior || Misc::StringUtils::ciEqual(markedCell->getCell()->mName.getRefIdString(), mPrefix))) && (!mInterior || Misc::StringUtils::ciEqual(markedCell->getCell()->mName, mPrefix)))
{ {
MarkerUserData markerPos(mLocalMapRender); MarkerUserData markerPos(mLocalMapRender);
MyGUI::ImageBox* markerWidget = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::ImageBox* markerWidget = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
@ -888,7 +888,7 @@ namespace MWGui
mEditingMarker.mCell.mPaged = !mInterior; mEditingMarker.mCell.mPaged = !mInterior;
if (mInterior) if (mInterior)
mEditingMarker.mCell.mWorldspace = ESM::RefId::stringRefId(LocalMapBase::mPrefix); mEditingMarker.mCell.mWorldspace = LocalMapBase::mPrefix;
else else
{ {
mEditingMarker.mCell.mWorldspace = ESM::CellId::sDefaultWorldspace; mEditingMarker.mCell.mWorldspace = ESM::CellId::sDefaultWorldspace;
@ -1333,7 +1333,7 @@ namespace MWGui
const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Cell>().search( const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Cell>().search(
cellId.first, cellId.second); cellId.first, cellId.second);
if (cell && !cell->mName.empty()) if (cell && !cell->mName.empty())
addVisitedLocation(cell->mName.getRefIdString(), cellId.first, cellId.second); addVisitedLocation(cell->mName, cellId.first, cellId.second);
} }
} }
} }

View file

@ -123,7 +123,7 @@ namespace MWGui
for (unsigned int i = 0; i < transport.size(); i++) for (unsigned int i = 0; i < transport.size(); i++)
{ {
std::string_view cellname = transport[i].mCellName.getRefIdString(); std::string_view cellname = transport[i].mCellName;
bool interior = true; bool interior = true;
const osg::Vec2i cellIndex const osg::Vec2i cellIndex
= MWWorld::positionToCellIndex(transport[i].mPos.pos[0], transport[i].mPos.pos[1]); = MWWorld::positionToCellIndex(transport[i].mPos.pos[0], transport[i].mPos.pos[1]);
@ -174,7 +174,7 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->fadeScreenOut(1); MWBase::Environment::get().getWindowManager()->fadeScreenOut(1);
ESM::Position pos = *_sender->getUserData<ESM::Position>(); ESM::Position pos = *_sender->getUserData<ESM::Position>();
const ESM::RefId& cellname = ESM::RefId::stringRefId(_sender->getUserString("Destination")); const std::string& cellname = _sender->getUserString("Destination");
bool interior = _sender->getUserString("interior") == "y"; bool interior = _sender->getUserString("interior") == "y";
if (mPtr.getCell()->isExterior()) if (mPtr.getCell()->isExterior())
{ {
@ -198,7 +198,7 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->fadeScreenOut(1); MWBase::Environment::get().getWindowManager()->fadeScreenOut(1);
// Teleports any followers, too. // Teleports any followers, too.
MWWorld::ActionTeleport action(interior ? cellname : ESM::RefId::sEmpty, pos, true); MWWorld::ActionTeleport action(interior ? cellname : "", pos, true);
action.execute(player); action.execute(player);
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0); MWBase::Environment::get().getWindowManager()->fadeScreenOut(0);

View file

@ -966,8 +966,8 @@ namespace MWGui
} }
else else
{ {
mMap->setCellPrefix(cell->getCell()->mName.getRefIdString()); mMap->setCellPrefix(cell->getCell()->mName);
mHud->setCellPrefix(cell->getCell()->mName.getRefIdString()); mHud->setCellPrefix(cell->getCell()->mName);
osg::Vec3f worldPos; osg::Vec3f worldPos;
if (!MWBase::Environment::get().getWorld()->findInteriorPositionInWorldSpace(cell, worldPos)) if (!MWBase::Environment::get().getWorld()->findInteriorPositionInWorldSpace(cell, worldPos))

View file

@ -38,8 +38,7 @@ namespace MWLua
return res.str(); return res.str();
}; };
cellT["name"] cellT["name"] = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->mName; });
= sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->mName.getRefIdString(); });
cellT["region"] cellT["region"]
= sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->mRegion.getRefIdString(); }); = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->mRegion.getRefIdString(); });
cellT["gridX"] = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->getGridX(); }); cellT["gridX"] = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->getGridX(); });

View file

@ -78,9 +78,8 @@ namespace MWLua
sol::table api(context.mLua->sol(), sol::create); sol::table api(context.mLua->sol(), sol::create);
WorldView* worldView = context.mWorldView; WorldView* worldView = context.mWorldView;
addTimeBindings(api, context, true); addTimeBindings(api, context, true);
api["getCellByName"] = [](std::string_view name) { api["getCellByName"]
return GCell{ MWBase::Environment::get().getWorldModel()->getCell(ESM::RefId::stringRefId(name)) }; = [](std::string_view name) { return GCell{ MWBase::Environment::get().getWorldModel()->getCell(name) }; };
};
api["getExteriorCell"] api["getExteriorCell"]
= [](int x, int y) { return GCell{ MWBase::Environment::get().getWorldModel()->getExterior(x, y) }; }; = [](int x, int y) { return GCell{ MWBase::Environment::get().getWorldModel()->getExterior(x, y) }; };
api["activeActors"] = GObjectList{ worldView->getActorsInScene() }; api["activeActors"] = GObjectList{ worldView->getActorsInScene() };

View file

@ -51,11 +51,11 @@ namespace MWLua
class TeleportAction final : public LuaManager::Action class TeleportAction final : public LuaManager::Action
{ {
public: public:
TeleportAction(LuaUtil::LuaState* state, ObjectId object, ESM::RefId cell, const osg::Vec3f& pos, TeleportAction(LuaUtil::LuaState* state, ObjectId object, std::string_view cell, const osg::Vec3f& pos,
const osg::Vec3f& rot) const osg::Vec3f& rot)
: Action(state) : Action(state)
, mObject(object) , mObject(object)
, mCell(std::move(cell)) , mCell(std::string(cell))
, mPos(pos) , mPos(pos)
, mRot(rot) , mRot(rot)
{ {
@ -94,7 +94,7 @@ namespace MWLua
private: private:
ObjectId mObject; ObjectId mObject;
ESM::RefId mCell; std::string mCell;
osg::Vec3f mPos; osg::Vec3f mPos;
osg::Vec3f mRot; osg::Vec3f mRot;
}; };
@ -247,8 +247,7 @@ namespace MWLua
const sol::optional<osg::Vec3f>& optRot) { const sol::optional<osg::Vec3f>& optRot) {
MWWorld::Ptr ptr = object.ptr(); MWWorld::Ptr ptr = object.ptr();
osg::Vec3f rot = optRot ? *optRot : ptr.getRefData().getPosition().asRotationVec3(); osg::Vec3f rot = optRot ? *optRot : ptr.getRefData().getPosition().asRotationVec3();
auto action = std::make_unique<TeleportAction>( auto action = std::make_unique<TeleportAction>(context.mLua, object.id(), cell, pos, rot);
context.mLua, object.id(), ESM::RefId::stringRefId(cell), pos, rot);
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
context.mLuaManager->addTeleportPlayerAction(std::move(action)); context.mLuaManager->addTeleportPlayerAction(std::move(action));
else else

View file

@ -34,7 +34,7 @@ namespace MWMechanics
} }
AiEscort::AiEscort( AiEscort::AiEscort(
const ESM::RefId& actorId, const ESM::RefId& cellId, int duration, float x, float y, float z, bool repeat) const ESM::RefId& actorId, std::string_view cellId, int duration, float x, float y, float z, bool repeat)
: TypedAiPackage<AiEscort>(repeat) : TypedAiPackage<AiEscort>(repeat)
, mCellId(cellId) , mCellId(cellId)
, mX(x) , mX(x)

View file

@ -28,7 +28,7 @@ namespace MWMechanics
/** The Actor will escort the specified actor to the cell position x, y, z until they reach their position, or /** The Actor will escort the specified actor to the cell position x, y, z until they reach their position, or
they run out of time \implement AiEscortCell **/ they run out of time \implement AiEscortCell **/
AiEscort( AiEscort(
const ESM::RefId& actorId, const ESM::RefId& cellId, int duration, float x, float y, float z, bool repeat); const ESM::RefId& actorId, std::string_view cellId, int duration, float x, float y, float z, bool repeat);
AiEscort(const ESM::AiSequence::AiEscort* escort); AiEscort(const ESM::AiSequence::AiEscort* escort);
@ -52,7 +52,7 @@ namespace MWMechanics
osg::Vec3f getDestination() const override { return osg::Vec3f(mX, mY, mZ); } osg::Vec3f getDestination() const override { return osg::Vec3f(mX, mY, mZ); }
private: private:
const ESM::RefId mCellId; const std::string mCellId;
const float mX; const float mX;
const float mY; const float mY;
const float mZ; const float mZ;

View file

@ -2,6 +2,7 @@
#include <components/esm3/aisequence.hpp> #include <components/esm3/aisequence.hpp>
#include <components/esm3/loadcell.hpp> #include <components/esm3/loadcell.hpp>
#include <components/misc/algorithm.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
@ -35,7 +36,6 @@ namespace MWMechanics
, mX(x) , mX(x)
, mY(y) , mY(y)
, mZ(z) , mZ(z)
, mCellId(ESM::RefId::sEmpty)
, mActive(false) , mActive(false)
, mFollowIndex(mFollowIndexCounter++) , mFollowIndex(mFollowIndexCounter++)
{ {
@ -43,7 +43,7 @@ namespace MWMechanics
} }
AiFollow::AiFollow( AiFollow::AiFollow(
const ESM::RefId& actorId, const ESM::RefId& cellId, float duration, float x, float y, float z, bool repeat) const ESM::RefId& actorId, std::string_view cellId, float duration, float x, float y, float z, bool repeat)
: TypedAiPackage<AiFollow>(repeat) : TypedAiPackage<AiFollow>(repeat)
, mAlwaysFollow(false) , mAlwaysFollow(false)
, mDuration(duration) , mDuration(duration)
@ -66,7 +66,6 @@ namespace MWMechanics
, mX(0) , mX(0)
, mY(0) , mY(0)
, mZ(0) , mZ(0)
, mCellId(ESM::RefId::sEmpty)
, mActive(false) , mActive(false)
, mFollowIndex(mFollowIndexCounter++) , mFollowIndex(mFollowIndexCounter++)
{ {
@ -169,13 +168,13 @@ namespace MWMechanics
{ {
if (actor.getCell()->isExterior()) // Outside? if (actor.getCell()->isExterior()) // Outside?
{ {
if (mCellId == ESM::RefId::sEmpty) // No cell to travel to if (mCellId.empty()) // No cell to travel to
{ {
mRemainingDuration = mDuration; mRemainingDuration = mDuration;
return true; return true;
} }
} }
else if (mCellId == actor.getCell()->getCell()->mName) // Cell to travel to else if (Misc::StringUtils::ciEqual(mCellId, actor.getCell()->getCell()->mName)) // Cell to travel to
{ {
mRemainingDuration = mDuration; mRemainingDuration = mDuration;
return true; return true;

View file

@ -44,8 +44,8 @@ namespace MWMechanics
/// Follow Actor for duration or until you arrive at a world position /// Follow Actor for duration or until you arrive at a world position
AiFollow(const ESM::RefId& actorId, float duration, float x, float y, float z, bool repeat); AiFollow(const ESM::RefId& actorId, float duration, float x, float y, float z, bool repeat);
/// Follow Actor for duration or until you arrive at a position in a cell /// Follow Actor for duration or until you arrive at a position in a cell
AiFollow(const ESM::RefId& actorId, const ESM::RefId& cellId, float duration, float x, float y, float z, AiFollow(
bool repeat); const ESM::RefId& actorId, std::string_view cellId, float duration, float x, float y, float z, bool repeat);
/// Follow Actor indefinitively /// Follow Actor indefinitively
AiFollow(const MWWorld::Ptr& actor, bool commanded = false); AiFollow(const MWWorld::Ptr& actor, bool commanded = false);
@ -94,7 +94,7 @@ namespace MWMechanics
const float mX; const float mX;
const float mY; const float mY;
const float mZ; const float mZ;
const ESM::RefId mCellId; const std::string mCellId;
bool mActive; // have we spotted the target? bool mActive; // have we spotted the target?
const int mFollowIndex; const int mFollowIndex;

View file

@ -487,7 +487,7 @@ namespace MWMechanics
world->getPlayer().getMarkedPosition(markedCell, markedPosition); world->getPlayer().getMarkedPosition(markedCell, markedPosition);
if (markedCell) if (markedCell)
{ {
ESM::RefId dest; std::string_view dest;
if (!markedCell->isExterior()) if (!markedCell->isExterior())
dest = markedCell->getCell()->mName; dest = markedCell->getCell()->mName;
MWWorld::ActionTeleport action(dest, markedPosition, false); MWWorld::ActionTeleport action(dest, markedPosition, false);

View file

@ -141,7 +141,7 @@ namespace MWScript
ESM::RefId actorID = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger)); ESM::RefId actorID = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger));
runtime.pop(); runtime.pop();
ESM::RefId cellID = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger)); std::string_view cellID = runtime.getStringLiteral(runtime[0].mInteger);
runtime.pop(); runtime.pop();
Interpreter::Type_Float duration = runtime[0].mFloat; Interpreter::Type_Float duration = runtime[0].mFloat;
@ -371,7 +371,7 @@ namespace MWScript
ESM::RefId actorID = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger)); ESM::RefId actorID = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger));
runtime.pop(); runtime.pop();
ESM::RefId cellID = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger)); std::string_view cellID = runtime.getStringLiteral(runtime[0].mInteger);
runtime.pop(); runtime.pop();
Interpreter::Type_Float duration = runtime[0].mFloat; Interpreter::Type_Float duration = runtime[0].mFloat;

View file

@ -86,7 +86,7 @@ namespace MWScript
public: public:
void execute(Interpreter::Runtime& runtime) override void execute(Interpreter::Runtime& runtime) override
{ {
const ESM::RefId cell = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger)); std::string_view cell = runtime.getStringLiteral(runtime[0].mInteger);
runtime.pop(); runtime.pop();
ESM::Position pos; ESM::Position pos;

View file

@ -126,7 +126,7 @@ namespace MWScript
for (auto it = cells.extBegin(); it != cells.extEnd(); ++it) for (auto it = cells.extBegin(); it != cells.extEnd(); ++it)
{ {
const auto& cellName = it->mName.getRefIdString(); const auto& cellName = it->mName;
if (Misc::StringUtils::ciStartsWith(cellName, cell)) if (Misc::StringUtils::ciStartsWith(cellName, cell))
winMgr->addVisitedLocation(cellName, it->getGridX(), it->getGridY()); winMgr->addVisitedLocation(cellName, it->getGridX(), it->getGridY());
} }
@ -143,7 +143,7 @@ namespace MWScript
for (auto it = cells.extBegin(); it != cells.extEnd(); ++it) for (auto it = cells.extBegin(); it != cells.extEnd(); ++it)
{ {
const std::string& name = it->mName.getRefIdString(); const std::string& name = it->mName;
if (!name.empty()) if (!name.empty())
MWBase::Environment::get().getWindowManager()->addVisitedLocation( MWBase::Environment::get().getWindowManager()->addVisitedLocation(
name, it->getGridX(), it->getGridY()); name, it->getGridX(), it->getGridY());

View file

@ -382,7 +382,7 @@ namespace MWScript
runtime.pop(); runtime.pop();
Interpreter::Type_Float zRot = runtime[0].mFloat; Interpreter::Type_Float zRot = runtime[0].mFloat;
runtime.pop(); runtime.pop();
const ESM::RefId cellID = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger)); std::string_view cellID = runtime.getStringLiteral(runtime[0].mInteger);
runtime.pop(); runtime.pop();
if (ptr.getContainerStore()) if (ptr.getContainerStore())
@ -405,8 +405,7 @@ namespace MWScript
{ {
// cell not found, move to exterior instead if moving the player (vanilla PositionCell // cell not found, move to exterior instead if moving the player (vanilla PositionCell
// compatibility) // compatibility)
std::string error std::string error = "Warning: PositionCell: unknown interior cell (" + std::string(cellID) + ")";
= "Warning: PositionCell: unknown interior cell (" + cellID.getRefIdString() + ")";
if (isPlayer) if (isPlayer)
error += ", moving to exterior instead"; error += ", moving to exterior instead";
runtime.getContext().report(error); runtime.getContext().report(error);
@ -500,7 +499,7 @@ namespace MWScript
{ {
const ESM::RefId itemID = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger)); const ESM::RefId itemID = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger));
runtime.pop(); runtime.pop();
auto cellID = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger)); std::string_view cellName = runtime.getStringLiteral(runtime[0].mInteger);
runtime.pop(); runtime.pop();
Interpreter::Type_Float x = runtime[0].mFloat; Interpreter::Type_Float x = runtime[0].mFloat;
@ -515,12 +514,12 @@ namespace MWScript
MWWorld::CellStore* store = nullptr; MWWorld::CellStore* store = nullptr;
try try
{ {
store = MWBase::Environment::get().getWorldModel()->getCell(cellID); store = MWBase::Environment::get().getWorldModel()->getCell(cellName);
} }
catch (std::exception&) catch (std::exception&)
{ {
runtime.getContext().report("unknown cell (" + cellID.getRefIdString() + ")"); runtime.getContext().report("unknown cell (" + std::string(cellName) + ")");
Log(Debug::Error) << "Error: unknown cell (" << cellID << ")"; Log(Debug::Error) << "Error: unknown cell (" << cellName << ")";
} }
if (store) if (store)
{ {

View file

@ -17,7 +17,7 @@
namespace MWWorld namespace MWWorld
{ {
ActionTeleport::ActionTeleport(const ESM::RefId& cellName, const ESM::Position& position, bool teleportFollowers) ActionTeleport::ActionTeleport(std::string_view cellName, const ESM::Position& position, bool teleportFollowers)
: Action(true) : Action(true)
, mCellName(cellName) , mCellName(cellName)
, mPosition(position) , mPosition(position)

View file

@ -13,7 +13,7 @@ namespace MWWorld
{ {
class ActionTeleport : public Action class ActionTeleport : public Action
{ {
ESM::RefId mCellName; std::string mCellName;
ESM::Position mPosition; ESM::Position mPosition;
bool mTeleportFollowers; bool mTeleportFollowers;
@ -26,7 +26,7 @@ namespace MWWorld
public: public:
/// If cellName is empty, an exterior cell is assumed. /// If cellName is empty, an exterior cell is assumed.
/// @param teleportFollowers Whether to teleport any following actors of the target actor as well. /// @param teleportFollowers Whether to teleport any following actors of the target actor as well.
ActionTeleport(const ESM::RefId& cellName, const ESM::Position& position, bool teleportFollowers); ActionTeleport(std::string_view cellName, const ESM::Position& position, bool teleportFollowers);
/// @param includeHostiles If true, include hostile followers (which won't actually be teleported) in the /// @param includeHostiles If true, include hostile followers (which won't actually be teleported) in the
/// output, /// output,

View file

@ -47,7 +47,7 @@ namespace MWWorld
const ESM::Position& getDoorDest() const { return mCellRef.mDoorDest; } const ESM::Position& getDoorDest() const { return mCellRef.mDoorDest; }
// Destination cell for doors (optional) // Destination cell for doors (optional)
const ESM::RefId& getDestCell() const { return mCellRef.mDestCell; } const std::string& getDestCell() const { return mCellRef.mDestCell; }
// Scale applied to mesh // Scale applied to mesh
float getScale() const { return mCellRef.mScale; } float getScale() const { return mCellRef.mScale; }

View file

@ -541,7 +541,8 @@ namespace MWWorld
} }
mNavigator.setWorldspace( mNavigator.setWorldspace(
mWorld.getWorldModel().getExterior(playerCellX, playerCellY)->getCell()->mCellId.mWorldspace, Misc::StringUtils::lowerCase(
mWorld.getWorldModel().getExterior(playerCellX, playerCellY)->getCell()->mCellId.mWorldspace),
navigatorUpdateGuard.get()); navigatorUpdateGuard.get());
mNavigator.updateBounds(pos, navigatorUpdateGuard.get()); mNavigator.updateBounds(pos, navigatorUpdateGuard.get());
@ -663,7 +664,8 @@ namespace MWWorld
"Testing exterior cells (" + std::to_string(i) + "/" + std::to_string(cells.getExtSize()) + ")..."); "Testing exterior cells (" + std::to_string(i) + "/" + std::to_string(cells.getExtSize()) + ")...");
CellStore* cell = mWorld.getWorldModel().getExterior(it->mData.mX, it->mData.mY); CellStore* cell = mWorld.getWorldModel().getExterior(it->mData.mX, it->mData.mY);
mNavigator.setWorldspace(cell->getCell()->mCellId.mWorldspace, navigatorUpdateGuard.get()); mNavigator.setWorldspace(
Misc::StringUtils::lowerCase(cell->getCell()->mCellId.mWorldspace), navigatorUpdateGuard.get());
const osg::Vec3f position const osg::Vec3f position
= osg::Vec3f(it->mData.mX + 0.5f, it->mData.mY + 0.5f, 0) * Constants::CellSizeInUnits; = osg::Vec3f(it->mData.mX + 0.5f, it->mData.mY + 0.5f, 0) * Constants::CellSizeInUnits;
mNavigator.updateBounds(position, navigatorUpdateGuard.get()); mNavigator.updateBounds(position, navigatorUpdateGuard.get());
@ -720,7 +722,8 @@ namespace MWWorld
"Testing interior cells (" + std::to_string(i) + "/" + std::to_string(cells.getIntSize()) + ")..."); "Testing interior cells (" + std::to_string(i) + "/" + std::to_string(cells.getIntSize()) + ")...");
CellStore* cell = mWorld.getWorldModel().getInterior(it->mName); CellStore* cell = mWorld.getWorldModel().getInterior(it->mName);
mNavigator.setWorldspace(cell->getCell()->mCellId.mWorldspace, navigatorUpdateGuard.get()); mNavigator.setWorldspace(
Misc::StringUtils::lowerCase(cell->getCell()->mCellId.mWorldspace), navigatorUpdateGuard.get());
ESM::Position position; ESM::Position position;
mWorld.findInteriorPosition(it->mName, position); mWorld.findInteriorPosition(it->mName, position);
mNavigator.updateBounds(position.asVec3(), navigatorUpdateGuard.get()); mNavigator.updateBounds(position.asVec3(), navigatorUpdateGuard.get());
@ -839,7 +842,7 @@ namespace MWWorld
} }
void Scene::changeToInteriorCell( void Scene::changeToInteriorCell(
const ESM::RefId& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent) std::string_view cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
{ {
CellStore* cell = mWorld.getWorldModel().getInterior(cellName); CellStore* cell = mWorld.getWorldModel().getInterior(cellName);
bool useFading = (mCurrentCell != nullptr); bool useFading = (mCurrentCell != nullptr);
@ -876,7 +879,8 @@ namespace MWWorld
loadingListener->setProgressRange(cell->count()); loadingListener->setProgressRange(cell->count());
mNavigator.setWorldspace(cell->getCell()->mCellId.mWorldspace, navigatorUpdateGuard.get()); mNavigator.setWorldspace(
Misc::StringUtils::lowerCase(cell->getCell()->mCellId.mWorldspace), navigatorUpdateGuard.get());
mNavigator.updateBounds(position.asVec3(), navigatorUpdateGuard.get()); mNavigator.updateBounds(position.asVec3(), navigatorUpdateGuard.get());
// Load cell. // Load cell.

View file

@ -163,7 +163,7 @@ namespace MWWorld
void resetCellLoaded() { mCellLoaded = false; } void resetCellLoaded() { mCellLoaded = false; }
void changeToInteriorCell( void changeToInteriorCell(
const ESM::RefId& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true); std::string_view cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true);
///< Move to interior cell. ///< Move to interior cell.
/// @param changeEvent Set cellChanged flag? /// @param changeEvent Set cellChanged flag?

View file

@ -513,15 +513,15 @@ namespace MWWorld
esm.restoreContext(ctx); esm.restoreContext(ctx);
} }
const ESM::Cell* Store<ESM::Cell>::search(const ESM::RefId& id) const const ESM::Cell* Store<ESM::Cell>::search(std::string_view name) const
{ {
DynamicInt::const_iterator it = mInt.find(id); DynamicInt::const_iterator it = mInt.find(name);
if (it != mInt.end()) if (it != mInt.end())
{ {
return &(it->second); return &(it->second);
} }
DynamicInt::const_iterator dit = mDynamicInt.find(id); DynamicInt::const_iterator dit = mDynamicInt.find(name);
if (dit != mDynamicInt.end()) if (dit != mDynamicInt.end())
{ {
return &dit->second; return &dit->second;
@ -574,12 +574,12 @@ namespace MWWorld
return &mExt.insert(std::make_pair(key, newCell)).first->second; return &mExt.insert(std::make_pair(key, newCell)).first->second;
} }
const ESM::Cell* Store<ESM::Cell>::find(const ESM::RefId& id) const const ESM::Cell* Store<ESM::Cell>::find(std::string_view id) const
{ {
const ESM::Cell* ptr = search(id); const ESM::Cell* ptr = search(id);
if (ptr == nullptr) if (ptr == nullptr)
{ {
const std::string msg = "Cell '" + id.getRefIdString() + "' not found"; const std::string msg = "Cell '" + std::string(id) + "' not found";
throw std::runtime_error(msg); throw std::runtime_error(msg);
} }
return ptr; return ptr;
@ -709,7 +709,7 @@ namespace MWWorld
} }
} }
return RecordId(cell.mName, isDeleted); return RecordId(ESM::RefId::stringRefId(cell.mName), isDeleted);
} }
Store<ESM::Cell>::iterator Store<ESM::Cell>::intBegin() const Store<ESM::Cell>::iterator Store<ESM::Cell>::intBegin() const
{ {
@ -727,12 +727,12 @@ namespace MWWorld
{ {
return iterator(mSharedExt.end()); return iterator(mSharedExt.end());
} }
const ESM::Cell* Store<ESM::Cell>::searchExtByName(const ESM::RefId& id) const const ESM::Cell* Store<ESM::Cell>::searchExtByName(std::string_view name) const
{ {
const ESM::Cell* cell = nullptr; const ESM::Cell* cell = nullptr;
for (const ESM::Cell* sharedCell : mSharedExt) for (const ESM::Cell* sharedCell : mSharedExt)
{ {
if (sharedCell->mName == id) if (sharedCell->mName == name)
{ {
if (cell == nullptr || (sharedCell->mData.mX > cell->mData.mX) if (cell == nullptr || (sharedCell->mData.mX > cell->mData.mX)
|| (sharedCell->mData.mX == cell->mData.mX && sharedCell->mData.mY > cell->mData.mY)) || (sharedCell->mData.mX == cell->mData.mX && sharedCell->mData.mY > cell->mData.mY))
@ -777,7 +777,7 @@ namespace MWWorld
for (const ESM::Cell* sharedCell : mSharedInt) for (const ESM::Cell* sharedCell : mSharedInt)
{ {
list.push_back(sharedCell->mName); list.push_back(ESM::RefId::stringRefId(sharedCell->mName));
} }
} }
ESM::Cell* Store<ESM::Cell>::insert(const ESM::Cell& cell) ESM::Cell* Store<ESM::Cell>::insert(const ESM::Cell& cell)
@ -812,9 +812,9 @@ namespace MWWorld
} }
return erase(cell.mName); return erase(cell.mName);
} }
bool Store<ESM::Cell>::erase(const ESM::RefId& id) bool Store<ESM::Cell>::erase(std::string_view name)
{ {
DynamicInt::iterator it = mDynamicInt.find(id); auto it = mDynamicInt.find(name);
if (it == mDynamicInt.end()) if (it == mDynamicInt.end())
{ {
@ -875,7 +875,8 @@ namespace MWWorld
// also an exterior cell with the coordinates of (0,0), so that doesn't help. Check whether mCell is an interior // also an exterior cell with the coordinates of (0,0), so that doesn't help. Check whether mCell is an interior
// cell. This isn't perfect, will break if a Region with the same name as an interior cell is created. A proper // cell. This isn't perfect, will break if a Region with the same name as an interior cell is created. A proper
// fix should be made for future versions of the file format. // fix should be made for future versions of the file format.
bool interior = pathgrid.mData.mX == 0 && pathgrid.mData.mY == 0 && mCells->search(pathgrid.mCell) != nullptr; bool interior = pathgrid.mData.mX == 0 && pathgrid.mData.mY == 0
&& mCells->search(pathgrid.mCell.getRefIdString()) != nullptr;
// deal with mods that have empty pathgrid records (Issue #6209) // deal with mods that have empty pathgrid records (Issue #6209)
// we assume that these records are empty on purpose (i.e. to remove old pathgrid on an updated cell) // we assume that these records are empty on purpose (i.e. to remove old pathgrid on an updated cell)
@ -928,7 +929,7 @@ namespace MWWorld
} }
const ESM::Pathgrid* Store<ESM::Pathgrid>::search(const ESM::RefId& name) const const ESM::Pathgrid* Store<ESM::Pathgrid>::search(const ESM::RefId& name) const
{ {
Interior::const_iterator it = mInt.find(name); Interior::const_iterator it = mInt.find(ESM::RefId(name));
if (it != mInt.end()) if (it != mInt.end())
return &(it->second); return &(it->second);
return nullptr; return nullptr;
@ -958,14 +959,14 @@ namespace MWWorld
if (!(cell.mData.mFlags & ESM::Cell::Interior)) if (!(cell.mData.mFlags & ESM::Cell::Interior))
return search(cell.mData.mX, cell.mData.mY); return search(cell.mData.mX, cell.mData.mY);
else else
return search(cell.mName); return search(ESM::RefId::stringRefId(cell.mName));
} }
const ESM::Pathgrid* Store<ESM::Pathgrid>::find(const ESM::Cell& cell) const const ESM::Pathgrid* Store<ESM::Pathgrid>::find(const ESM::Cell& cell) const
{ {
if (!(cell.mData.mFlags & ESM::Cell::Interior)) if (!(cell.mData.mFlags & ESM::Cell::Interior))
return find(cell.mData.mX, cell.mData.mY); return find(cell.mData.mX, cell.mData.mY);
else else
return find(cell.mName); return find(ESM::RefId::stringRefId(cell.mName));
} }
// Skill // Skill

View file

@ -332,7 +332,9 @@ namespace MWWorld
} }
}; };
typedef std::unordered_map<ESM::RefId, ESM::Cell> DynamicInt; typedef std::unordered_map<std::string, ESM::Cell, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual>
DynamicInt;
typedef std::map<std::pair<int, int>, ESM::Cell, DynamicExtCmp> DynamicExt; typedef std::map<std::pair<int, int>, ESM::Cell, DynamicExtCmp> DynamicExt;
DynamicInt mInt; DynamicInt mInt;
@ -350,12 +352,12 @@ namespace MWWorld
public: public:
typedef SharedIterator<ESM::Cell> iterator; typedef SharedIterator<ESM::Cell> iterator;
const ESM::Cell* search(const ESM::RefId& id) const; const ESM::Cell* search(std::string_view id) const;
const ESM::Cell* search(int x, int y) const; const ESM::Cell* search(int x, int y) const;
const ESM::Cell* searchStatic(int x, int y) const; const ESM::Cell* searchStatic(int x, int y) const;
const ESM::Cell* searchOrCreate(int x, int y); const ESM::Cell* searchOrCreate(int x, int y);
const ESM::Cell* find(const ESM::RefId& id) const; const ESM::Cell* find(std::string_view id) const;
const ESM::Cell* find(int x, int y) const; const ESM::Cell* find(int x, int y) const;
void clearDynamic() override; void clearDynamic() override;
@ -369,7 +371,7 @@ namespace MWWorld
iterator extEnd() const; iterator extEnd() const;
// Return the northernmost cell in the easternmost column. // Return the northernmost cell in the easternmost column.
const ESM::Cell* searchExtByName(const ESM::RefId& id) const; const ESM::Cell* searchExtByName(std::string_view id) const;
// Return the northernmost cell in the easternmost column. // Return the northernmost cell in the easternmost column.
const ESM::Cell* searchExtByRegion(const ESM::RefId& id) const; const ESM::Cell* searchExtByRegion(const ESM::RefId& id) const;
@ -383,7 +385,7 @@ namespace MWWorld
ESM::Cell* insert(const ESM::Cell& cell); ESM::Cell* insert(const ESM::Cell& cell);
bool erase(const ESM::Cell& cell); bool erase(const ESM::Cell& cell);
bool erase(const ESM::RefId& id); bool erase(std::string_view id);
bool erase(int x, int y); bool erase(int x, int y);
}; };

View file

@ -156,7 +156,7 @@ namespace MWWorld
World::World(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem, World::World(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem,
SceneUtil::WorkQueue* workQueue, SceneUtil::UnrefQueue& unrefQueue, const Files::Collections& fileCollections, SceneUtil::WorkQueue* workQueue, SceneUtil::UnrefQueue& unrefQueue, const Files::Collections& fileCollections,
const std::vector<std::string>& contentFiles, const std::vector<std::string>& groundcoverFiles, const std::vector<std::string>& contentFiles, const std::vector<std::string>& groundcoverFiles,
ToUTF8::Utf8Encoder* encoder, int activationDistanceOverride, const ESM::RefId& startCell, ToUTF8::Utf8Encoder* encoder, int activationDistanceOverride, const std::string& startCell,
const std::string& startupScript, const std::filesystem::path& resourcePath, const std::string& startupScript, const std::filesystem::path& resourcePath,
const std::filesystem::path& userDataPath) const std::filesystem::path& userDataPath)
: mResourceSystem(resourceSystem) : mResourceSystem(resourceSystem)
@ -640,7 +640,7 @@ namespace MWWorld
if (cell) if (cell)
{ {
if (!cell->isExterior() || !cell->mName.empty()) if (!cell->isExterior() || !cell->mName.empty())
return cell->mName.getRefIdString(); return cell->mName;
if (const ESM::Region* region = mStore.get<ESM::Region>().search(cell->mRegion)) if (const ESM::Region* region = mStore.get<ESM::Region>().search(cell->mRegion))
return region->mName; return region->mName;
@ -928,7 +928,7 @@ namespace MWWorld
} }
void World::changeToInteriorCell( void World::changeToInteriorCell(
const ESM::RefId& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent) const std::string_view cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
{ {
mPhysics->clearQueuedMovement(); mPhysics->clearQueuedMovement();
mDiscardMovements = true; mDiscardMovements = true;
@ -1399,10 +1399,10 @@ namespace MWWorld
esmPos.pos[0] = traced.x(); esmPos.pos[0] = traced.x();
esmPos.pos[1] = traced.y(); esmPos.pos[1] = traced.y();
esmPos.pos[2] = traced.z(); esmPos.pos[2] = traced.z();
const ESM::RefId* cell = &ESM::RefId::sEmpty; std::string_view cell;
if (!actor.getCell()->isExterior()) if (!actor.getCell()->isExterior())
cell = &actor.getCell()->getCell()->mName; cell = actor.getCell()->getCell()->mName;
MWWorld::ActionTeleport(*cell, esmPos, false).execute(actor); MWWorld::ActionTeleport(cell, esmPos, false).execute(actor);
} }
} }
@ -2747,7 +2747,7 @@ namespace MWWorld
physicActor->enableCollisionBody(enable); physicActor->enableCollisionBody(enable);
} }
bool World::findInteriorPosition(const ESM::RefId& name, ESM::Position& pos) bool World::findInteriorPosition(std::string_view name, ESM::Position& pos)
{ {
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
pos.pos[0] = pos.pos[1] = pos.pos[2] = 0; pos.pos[0] = pos.pos[1] = pos.pos[2] = 0;
@ -2819,10 +2819,9 @@ namespace MWWorld
return false; return false;
} }
bool World::findExteriorPosition(const ESM::RefId& nameId, ESM::Position& pos) bool World::findExteriorPosition(std::string_view nameId, ESM::Position& pos)
{ {
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
const std::string& name = nameId.getRefIdString();
const ESM::Cell* ext = nullptr; const ESM::Cell* ext = nullptr;
try try
@ -2836,12 +2835,13 @@ namespace MWWorld
} }
if (!ext) if (!ext)
{ {
size_t comma = name.find(','); size_t comma = nameId.find(',');
if (comma != std::string::npos) if (comma != std::string::npos)
{ {
int x, y; int x, y;
std::from_chars_result xResult = std::from_chars(name.data(), name.data() + comma, x); std::from_chars_result xResult = std::from_chars(nameId.data(), nameId.data() + comma, x);
std::from_chars_result yResult = std::from_chars(name.data() + comma + 1, name.data() + name.size(), y); std::from_chars_result yResult
= std::from_chars(nameId.data() + comma + 1, nameId.data() + nameId.size(), y);
if (xResult.ec == std::errc::result_out_of_range || yResult.ec == std::errc::result_out_of_range) if (xResult.ec == std::errc::result_out_of_range || yResult.ec == std::errc::result_out_of_range)
throw std::runtime_error("Cell coordinates out of range."); throw std::runtime_error("Cell coordinates out of range.");
else if (xResult.ec == std::errc{} && yResult.ec == std::errc{}) else if (xResult.ec == std::errc{} && yResult.ec == std::errc{})
@ -3253,9 +3253,9 @@ namespace MWWorld
// Search for a 'nearest' exterior, counting each cell between the starting // 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. // cell and the exterior as a distance of 1. Will fail for isolated interiors.
std::set<ESM::RefId> checkedCells; std::set<std::string_view> checkedCells;
std::set<ESM::RefId> currentCells; std::set<std::string_view> currentCells;
std::set<ESM::RefId> nextCells; std::set<std::string_view> nextCells;
nextCells.insert(cell->getCell()->mName); nextCells.insert(cell->getCell()->mName);
while (!nextCells.empty()) while (!nextCells.empty())
@ -3282,7 +3282,7 @@ namespace MWWorld
} }
else else
{ {
const ESM::RefId& dest = ref.mRef.getDestCell(); const std::string_view dest = ref.mRef.getDestCell();
if (!checkedCells.count(dest) && !currentCells.count(dest)) if (!checkedCells.count(dest) && !currentCells.count(dest))
nextCells.insert(dest); nextCells.insert(dest);
} }
@ -3306,9 +3306,9 @@ namespace MWWorld
// Search for a 'nearest' marker, counting each cell between the starting // 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 // cell and the exterior as a distance of 1. If an exterior is found, jump
// to the nearest exterior marker, without further interior searching. // to the nearest exterior marker, without further interior searching.
std::set<ESM::RefId> checkedCells; std::set<std::string_view> checkedCells;
std::set<ESM::RefId> currentCells; std::set<std::string_view> currentCells;
std::set<ESM::RefId> nextCells; std::set<std::string_view> nextCells;
MWWorld::ConstPtr closestMarker; MWWorld::ConstPtr closestMarker;
nextCells.insert(ptr.getCell()->getCell()->mName); nextCells.insert(ptr.getCell()->getCell()->mName);
@ -3404,11 +3404,11 @@ namespace MWWorld
return; return;
} }
const ESM::RefId* cellName = &ESM::RefId::sEmpty; std::string_view cellName = "";
if (!closestMarker.mCell->isExterior()) 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); action.execute(ptr);
} }
@ -3610,7 +3610,7 @@ namespace MWWorld
Log(Debug::Warning) << "Failed to confiscate items: no closest prison marker found."; Log(Debug::Warning) << "Failed to confiscate items: no closest prison marker found.";
return; return;
} }
const ESM::RefId& prisonName = prisonMarker.getCellRef().getDestCell(); std::string_view prisonName = prisonMarker.getCellRef().getDestCell();
if (prisonName.empty()) if (prisonName.empty())
{ {
Log(Debug::Warning) << "Failed to confiscate items: prison marker not linked to prison interior"; Log(Debug::Warning) << "Failed to confiscate items: prison marker not linked to prison interior";

View file

@ -94,7 +94,7 @@ namespace MWWorld
WorldModel mWorldModel; WorldModel mWorldModel;
std::vector<int> mESMVersions; // the versions of esm files std::vector<int> mESMVersions; // the versions of esm files
ESM::RefId mCurrentWorldSpace; std::string mCurrentWorldSpace;
std::unique_ptr<MWWorld::Player> mPlayer; std::unique_ptr<MWWorld::Player> mPlayer;
std::unique_ptr<MWPhysics::PhysicsSystem> mPhysics; std::unique_ptr<MWPhysics::PhysicsSystem> mPhysics;
@ -118,7 +118,7 @@ namespace MWWorld
int mActivationDistanceOverride; int mActivationDistanceOverride;
ESM::RefId mStartCell; std::string mStartCell;
float mSwimHeightScale; float mSwimHeightScale;
@ -200,7 +200,7 @@ namespace MWWorld
SceneUtil::WorkQueue* workQueue, SceneUtil::UnrefQueue& unrefQueue, SceneUtil::WorkQueue* workQueue, SceneUtil::UnrefQueue& unrefQueue,
const Files::Collections& fileCollections, const std::vector<std::string>& contentFiles, const Files::Collections& fileCollections, const std::vector<std::string>& contentFiles,
const std::vector<std::string>& groundcoverFiles, ToUTF8::Utf8Encoder* encoder, const std::vector<std::string>& groundcoverFiles, ToUTF8::Utf8Encoder* encoder,
int activationDistanceOverride, const ESM::RefId& startCell, const std::string& startupScript, int activationDistanceOverride, const std::string& startCell, const std::string& startupScript,
const std::filesystem::path& resourcePath, const std::filesystem::path& userDataPath); const std::filesystem::path& resourcePath, const std::filesystem::path& userDataPath);
virtual ~World(); virtual ~World();
@ -341,7 +341,7 @@ namespace MWWorld
void setSimulationTimeScale(float scale) override; void setSimulationTimeScale(float scale) override;
void changeToInteriorCell(const ESM::RefId& cellName, const ESM::Position& position, bool adjustPlayerPos, void changeToInteriorCell(const std::string_view cellName, const ESM::Position& position, bool adjustPlayerPos,
bool changeEvent = true) override; bool changeEvent = true) override;
///< Move to interior cell. ///< Move to interior cell.
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes ///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
@ -603,11 +603,11 @@ namespace MWWorld
/// Find center of exterior cell above land surface /// Find center of exterior cell above land surface
/// \return false if exterior with given name not exists, true otherwise /// \return false if exterior with given name not exists, true otherwise
bool findExteriorPosition(const ESM::RefId& name, ESM::Position& pos) override; bool findExteriorPosition(std::string_view nameId, ESM::Position& pos) override;
/// Find position in interior cell near door entrance /// Find position in interior cell near door entrance
/// \return false if interior with given name not exists, true otherwise /// \return false if interior with given name not exists, true otherwise
bool findInteriorPosition(const ESM::RefId& name, ESM::Position& pos) override; bool findInteriorPosition(std::string_view name, ESM::Position& pos) override;
/// Enables or disables use of teleport spell effects (recall, intervention, etc). /// Enables or disables use of teleport spell effects (recall, intervention, etc).
void enableTeleporting(bool enable) override; void enableTeleporting(bool enable) override;

View file

@ -19,8 +19,8 @@
namespace namespace
{ {
template <class Visitor, class Key> template <class Visitor, class Key, class Comp>
bool forEachInStore(const ESM::RefId& id, Visitor&& visitor, std::map<Key, MWWorld::CellStore>& cellStore) bool forEachInStore(const ESM::RefId& id, Visitor&& visitor, std::map<Key, MWWorld::CellStore, Comp>& cellStore)
{ {
for (auto& cell : cellStore) for (auto& cell : cellStore)
{ {
@ -196,7 +196,7 @@ MWWorld::CellStore* MWWorld::WorldModel::getExterior(int x, int y)
return &result->second; return &result->second;
} }
MWWorld::CellStore* MWWorld::WorldModel::getInterior(const ESM::RefId& name) MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name)
{ {
auto result = mInteriors.find(name); auto result = mInteriors.find(name);
@ -223,7 +223,7 @@ MWWorld::CellStore* MWWorld::WorldModel::getCell(const ESM::CellId& id)
return getInterior(id.mWorldspace); return getInterior(id.mWorldspace);
} }
const ESM::Cell* MWWorld::WorldModel::getESMCellByName(const ESM::RefId& name) const ESM::Cell* MWWorld::WorldModel::getESMCellByName(std::string_view name)
{ {
const ESM::Cell* cell = mStore.get<ESM::Cell>().search(name); // first try interiors const ESM::Cell* cell = mStore.get<ESM::Cell>().search(name); // first try interiors
if (!cell) // try named exteriors if (!cell) // try named exteriors
@ -231,17 +231,17 @@ const ESM::Cell* MWWorld::WorldModel::getESMCellByName(const ESM::RefId& name)
if (!cell) if (!cell)
{ {
// treat "Wilderness" like an empty string // treat "Wilderness" like an empty string
static const ESM::RefId defaultName static const std::string& defaultName
= ESM::RefId::stringRefId(mStore.get<ESM::GameSetting>().find("sDefaultCellname")->mValue.getString()); = mStore.get<ESM::GameSetting>().find("sDefaultCellname")->mValue.getString();
if (name == defaultName) if (name == defaultName)
cell = mStore.get<ESM::Cell>().searchExtByName(ESM::RefId::sEmpty); cell = mStore.get<ESM::Cell>().searchExtByName("");
} }
if (!cell) if (!cell)
{ {
// now check for regions // now check for regions
for (const ESM::Region& region : mStore.get<ESM::Region>()) for (const ESM::Region& region : mStore.get<ESM::Region>())
{ {
if (name == ESM::RefId::stringRefId(region.mName)) if (name == region.mName)
{ {
cell = mStore.get<ESM::Cell>().searchExtByRegion(region.mId); cell = mStore.get<ESM::Cell>().searchExtByRegion(region.mId);
break; break;
@ -249,11 +249,11 @@ const ESM::Cell* MWWorld::WorldModel::getESMCellByName(const ESM::RefId& name)
} }
} }
if (!cell) if (!cell)
throw std::runtime_error(std::string("Can't find cell with name ") + name.getRefIdString()); throw std::runtime_error(std::string("Can't find cell with name ") + std::string(name));
return cell; return cell;
} }
MWWorld::CellStore* MWWorld::WorldModel::getCell(const ESM::RefId& name) MWWorld::CellStore* MWWorld::WorldModel::getCell(std::string_view name)
{ {
const ESM::Cell* cell = getESMCellByName(name); const ESM::Cell* cell = getESMCellByName(name);
if (cell->isExterior()) if (cell->isExterior())
@ -263,7 +263,7 @@ MWWorld::CellStore* MWWorld::WorldModel::getCell(const ESM::RefId& name)
} }
MWWorld::CellStore* MWWorld::WorldModel::getCellByPosition( MWWorld::CellStore* MWWorld::WorldModel::getCellByPosition(
const osg::Vec3f& pos, const ESM::RefId& cellNameInSameWorldSpace) const osg::Vec3f& pos, std::string_view cellNameInSameWorldSpace)
{ {
if (cellNameInSameWorldSpace.empty() || getESMCellByName(cellNameInSameWorldSpace)->isExterior()) if (cellNameInSameWorldSpace.empty() || getESMCellByName(cellNameInSameWorldSpace)->isExterior())
{ {

View file

@ -6,6 +6,8 @@
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <components/misc/algorithm.hpp>
#include "cellstore.hpp" #include "cellstore.hpp"
#include "ptr.hpp" #include "ptr.hpp"
@ -34,7 +36,7 @@ namespace MWWorld
typedef std::vector<std::pair<ESM::RefId, CellStore*>> IdCache; typedef std::vector<std::pair<ESM::RefId, CellStore*>> IdCache;
const MWWorld::ESMStore& mStore; const MWWorld::ESMStore& mStore;
ESM::ReadersCache& mReaders; ESM::ReadersCache& mReaders;
mutable std::map<ESM::RefId, CellStore> mInteriors; mutable std::map<std::string, CellStore, Misc::StringUtils::CiComp> mInteriors;
mutable std::map<std::pair<int, int>, CellStore> mExteriors; mutable std::map<std::pair<int, int>, CellStore> mExteriors;
IdCache mIdCache; IdCache mIdCache;
std::size_t mIdCacheIndex; std::size_t mIdCacheIndex;
@ -42,7 +44,7 @@ namespace MWWorld
WorldModel(const WorldModel&); WorldModel(const WorldModel&);
WorldModel& operator=(const WorldModel&); WorldModel& operator=(const WorldModel&);
const ESM::Cell* getESMCellByName(const ESM::RefId& name); const ESM::Cell* getESMCellByName(std::string_view name);
CellStore* getCellStore(const ESM::Cell* cell); CellStore* getCellStore(const ESM::Cell* cell);
Ptr getPtrAndCache(const ESM::RefId& name, CellStore& cellStore); Ptr getPtrAndCache(const ESM::RefId& name, CellStore& cellStore);
@ -61,14 +63,14 @@ namespace MWWorld
explicit WorldModel(const MWWorld::ESMStore& store, ESM::ReadersCache& reader); explicit WorldModel(const MWWorld::ESMStore& store, ESM::ReadersCache& reader);
CellStore* getExterior(int x, int y); CellStore* getExterior(int x, int y);
CellStore* getInterior(const ESM::RefId& name); CellStore* getInterior(std::string_view name);
CellStore* getCell(const ESM::RefId& name); // interior or named exterior CellStore* getCell(std::string_view name); // interior or named exterior
CellStore* getCell(const ESM::CellId& id); CellStore* getCell(const ESM::CellId& Id);
// If cellNameInSameWorldSpace is an interior - returns this interior. // If cellNameInSameWorldSpace is an interior - returns this interior.
// Otherwise returns exterior cell for given position in the same world space. // Otherwise returns exterior cell for given position in the same world space.
// At the moment multiple world spaces are not supported, so all exteriors are in one world space. // At the moment multiple world spaces are not supported, so all exteriors are in one world space.
CellStore* getCellByPosition(const osg::Vec3f& pos, const ESM::RefId& cellNameInSameWorldSpace); CellStore* getCellByPosition(const osg::Vec3f& pos, std::string_view cellNameInSameWorldSpace);
void registerPtr(const MWWorld::Ptr& ptr); void registerPtr(const MWWorld::Ptr& ptr);
void deregisterPtr(const MWWorld::Ptr& ptr); void deregisterPtr(const MWWorld::Ptr& ptr);

View file

@ -5,7 +5,6 @@
#include <components/detournavigator/makenavmesh.hpp> #include <components/detournavigator/makenavmesh.hpp>
#include <components/detournavigator/navmeshdbutils.hpp> #include <components/detournavigator/navmeshdbutils.hpp>
#include <components/detournavigator/serialization.hpp> #include <components/detournavigator/serialization.hpp>
#include <components/esm/refid.hpp>
#include <components/loadinglistener/loadinglistener.hpp> #include <components/loadinglistener/loadinglistener.hpp>
#include <BulletCollision/CollisionShapes/btBoxShape.h> #include <BulletCollision/CollisionShapes/btBoxShape.h>
@ -53,7 +52,7 @@ namespace
OffMeshConnectionsManager mOffMeshConnectionsManager{ mSettings.mRecast }; OffMeshConnectionsManager mOffMeshConnectionsManager{ mSettings.mRecast };
const AgentBounds mAgentBounds{ CollisionShapeType::Aabb, { 29, 29, 66 } }; const AgentBounds mAgentBounds{ CollisionShapeType::Aabb, { 29, 29, 66 } };
const TilePosition mPlayerTile{ 0, 0 }; const TilePosition mPlayerTile{ 0, 0 };
const ESM::RefId mWorldspace = ESM::RefId::stringRefId("sys::default"); const std::string mWorldspace = "sys::default";
const btBoxShape mBox{ btVector3(100, 100, 20) }; const btBoxShape mBox{ btVector3(100, 100, 20) };
Loading::Listener mListener; Loading::Listener mListener;
}; };

View file

@ -44,6 +44,7 @@ namespace
Settings mSettings = makeSettings(); Settings mSettings = makeSettings();
std::unique_ptr<Navigator> mNavigator; std::unique_ptr<Navigator> mNavigator;
const osg::Vec3f mPlayerPosition; const osg::Vec3f mPlayerPosition;
const std::string mWorldspace;
const AgentBounds mAgentBounds{ CollisionShapeType::Aabb, { 29, 29, 66 } }; const AgentBounds mAgentBounds{ CollisionShapeType::Aabb, { 29, 29, 66 } };
osg::Vec3f mStart; osg::Vec3f mStart;
osg::Vec3f mEnd; osg::Vec3f mEnd;
@ -60,6 +61,7 @@ namespace
DetourNavigatorNavigatorTest() DetourNavigatorNavigatorTest()
: mPlayerPosition(256, 256, 0) : mPlayerPosition(256, 256, 0)
, mWorldspace("sys::default")
, mStart(52, 460, 1) , mStart(52, 460, 1)
, mEnd(460, 52, 1) , mEnd(460, 52, 1)
, mOut(mPath) , mOut(mPath)

View file

@ -1,7 +1,6 @@
#include "generate.hpp" #include "generate.hpp"
#include <components/detournavigator/navmeshdb.hpp> #include <components/detournavigator/navmeshdb.hpp>
#include <components/esm/refid.hpp>
#include <DetourAlloc.h> #include <DetourAlloc.h>
@ -20,7 +19,7 @@ namespace
struct Tile struct Tile
{ {
ESM::RefId mWorldspace; std::string mWorldspace;
TilePosition mTilePosition; TilePosition mTilePosition;
std::vector<std::byte> mInput; std::vector<std::byte> mInput;
std::vector<std::byte> mData; std::vector<std::byte> mData;
@ -40,7 +39,7 @@ namespace
Tile insertTile(TileId tileId, TileVersion version) Tile insertTile(TileId tileId, TileVersion version)
{ {
ESM::RefId worldspace = ESM::RefId::stringRefId("sys::default"); std::string worldspace = "sys::default";
const TilePosition tilePosition{ 3, 4 }; const TilePosition tilePosition{ 3, 4 };
std::vector<std::byte> input = generateData(); std::vector<std::byte> input = generateData();
std::vector<std::byte> data = generateData(); std::vector<std::byte> data = generateData();
@ -90,7 +89,7 @@ namespace
{ {
const TileId tileId{ 53 }; const TileId tileId{ 53 };
const TileVersion version{ 1 }; const TileVersion version{ 1 };
const ESM::RefId worldspace = ESM::RefId::stringRefId("sys::default"); const std::string worldspace = "sys::default";
const TilePosition tilePosition{ 3, 4 }; const TilePosition tilePosition{ 3, 4 };
const std::vector<std::byte> input = generateData(); const std::vector<std::byte> input = generateData();
const std::vector<std::byte> data = generateData(); const std::vector<std::byte> data = generateData();
@ -102,7 +101,7 @@ namespace
{ {
const TileId tileId{ 53 }; const TileId tileId{ 53 };
const TileVersion version{ 1 }; const TileVersion version{ 1 };
const ESM::RefId worldspace = ESM::RefId::stringRefId("sys::default"); const std::string worldspace = "sys::default";
const TilePosition tilePosition{ 3, 4 }; const TilePosition tilePosition{ 3, 4 };
const std::vector<std::byte> input = generateData(); const std::vector<std::byte> input = generateData();
const std::vector<std::byte> data = generateData(); const std::vector<std::byte> data = generateData();
@ -114,7 +113,7 @@ namespace
TEST_F(DetourNavigatorNavMeshDbTest, delete_tiles_at_should_remove_all_tiles_with_given_worldspace_and_position) TEST_F(DetourNavigatorNavMeshDbTest, delete_tiles_at_should_remove_all_tiles_with_given_worldspace_and_position)
{ {
const TileVersion version{ 1 }; const TileVersion version{ 1 };
const ESM::RefId worldspace = ESM::RefId::stringRefId("sys::default"); const std::string worldspace = "sys::default";
const TilePosition tilePosition{ 3, 4 }; const TilePosition tilePosition{ 3, 4 };
const std::vector<std::byte> input1 = generateData(); const std::vector<std::byte> input1 = generateData();
const std::vector<std::byte> input2 = generateData(); const std::vector<std::byte> input2 = generateData();
@ -131,7 +130,7 @@ namespace
const TileId leftTileId{ 53 }; const TileId leftTileId{ 53 };
const TileId removedTileId{ 54 }; const TileId removedTileId{ 54 };
const TileVersion version{ 1 }; const TileVersion version{ 1 };
const ESM::RefId worldspace = ESM::RefId::stringRefId("sys::default"); const std::string worldspace = "sys::default";
const TilePosition tilePosition{ 3, 4 }; const TilePosition tilePosition{ 3, 4 };
const std::vector<std::byte> leftInput = generateData(); const std::vector<std::byte> leftInput = generateData();
const std::vector<std::byte> removedInput = generateData(); const std::vector<std::byte> removedInput = generateData();
@ -149,7 +148,7 @@ namespace
{ {
TileId tileId{ 1 }; TileId tileId{ 1 };
const TileVersion version{ 1 }; const TileVersion version{ 1 };
const ESM::RefId worldspace = ESM::RefId::stringRefId("sys::default"); const std::string worldspace = "sys::default";
const std::vector<std::byte> input = generateData(); const std::vector<std::byte> input = generateData();
const std::vector<std::byte> data = generateData(); const std::vector<std::byte> data = generateData();
for (int x = -2; x <= 2; ++x) for (int x = -2; x <= 2; ++x)

View file

@ -2,7 +2,6 @@
#include <components/detournavigator/debug.hpp> #include <components/detournavigator/debug.hpp>
#include <components/detournavigator/settingsutils.hpp> #include <components/detournavigator/settingsutils.hpp>
#include <components/detournavigator/tilecachedrecastmeshmanager.hpp> #include <components/detournavigator/tilecachedrecastmeshmanager.hpp>
#include <components/esm/refid.hpp>
#include <BulletCollision/CollisionShapes/btBoxShape.h> #include <BulletCollision/CollisionShapes/btBoxShape.h>
@ -22,8 +21,6 @@ namespace
const ObjectTransform mObjectTransform{ ESM::Position{ { 0, 0, 0 }, { 0, 0, 0 } }, 0.0f }; const ObjectTransform mObjectTransform{ ESM::Position{ { 0, 0, 0 }, { 0, 0, 0 } }, 0.0f };
const osg::ref_ptr<const Resource::BulletShape> mShape = new Resource::BulletShape; const osg::ref_ptr<const Resource::BulletShape> mShape = new Resource::BulletShape;
const osg::ref_ptr<const Resource::BulletShapeInstance> mInstance = new Resource::BulletShapeInstance(mShape); const osg::ref_ptr<const Resource::BulletShapeInstance> mInstance = new Resource::BulletShapeInstance(mShape);
const ESM::RefId mWorldspace = ESM::RefId::stringRefId("worldspace");
const ESM::RefId mOtherWorldspace = ESM::RefId::stringRefId("other");
DetourNavigatorTileCachedRecastMeshManagerTest() DetourNavigatorTileCachedRecastMeshManagerTest()
{ {
@ -37,7 +34,7 @@ namespace
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, get_mesh_for_empty_should_return_nullptr) TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, get_mesh_for_empty_should_return_nullptr)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
EXPECT_EQ(manager.getMesh(mWorldspace, TilePosition(0, 0)), nullptr); EXPECT_EQ(manager.getMesh("worldspace", TilePosition(0, 0)), nullptr);
} }
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, get_revision_for_empty_should_return_zero) TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, get_revision_for_empty_should_return_zero)
@ -68,14 +65,14 @@ namespace
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_object_should_add_tiles) TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_object_should_add_tiles)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const btBoxShape boxShape(btVector3(20, 20, 100)); const btBoxShape boxShape(btVector3(20, 20, 100));
const CollisionShape shape(mInstance, boxShape, mObjectTransform); const CollisionShape shape(mInstance, boxShape, mObjectTransform);
ASSERT_TRUE(manager.addObject( ASSERT_TRUE(manager.addObject(
ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr)); ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr));
for (int x = -1; x < 1; ++x) for (int x = -1; x < 1; ++x)
for (int y = -1; y < 1; ++y) for (int y = -1; y < 1; ++y)
ASSERT_NE(manager.getMesh(mWorldspace, TilePosition(x, y)), nullptr); ASSERT_NE(manager.getMesh("worldspace", TilePosition(x, y)), nullptr);
} }
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_object_should_return_add_changed_tiles) TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_object_should_return_add_changed_tiles)
@ -148,25 +145,25 @@ namespace
get_mesh_after_add_object_should_return_recast_mesh_for_each_used_tile) get_mesh_after_add_object_should_return_recast_mesh_for_each_used_tile)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const btBoxShape boxShape(btVector3(20, 20, 100)); const btBoxShape boxShape(btVector3(20, 20, 100));
const CollisionShape shape(mInstance, boxShape, mObjectTransform); const CollisionShape shape(mInstance, boxShape, mObjectTransform);
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr); manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(-1, -1)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(-1, -1)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(-1, 0)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(-1, 0)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(0, -1)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(0, -1)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(0, 0)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(0, 0)), nullptr);
} }
TEST_F( TEST_F(
DetourNavigatorTileCachedRecastMeshManagerTest, get_mesh_after_add_object_should_return_nullptr_for_unused_tile) DetourNavigatorTileCachedRecastMeshManagerTest, get_mesh_after_add_object_should_return_nullptr_for_unused_tile)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const btBoxShape boxShape(btVector3(20, 20, 100)); const btBoxShape boxShape(btVector3(20, 20, 100));
const CollisionShape shape(mInstance, boxShape, mObjectTransform); const CollisionShape shape(mInstance, boxShape, mObjectTransform);
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr); manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr);
EXPECT_EQ(manager.getMesh(mWorldspace, TilePosition(1, 0)), nullptr); EXPECT_EQ(manager.getMesh("worldspace", TilePosition(1, 0)), nullptr);
} }
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest,
@ -178,7 +175,7 @@ namespace
.mEnd = TilePosition(1, 1), .mEnd = TilePosition(1, 1),
}; };
manager.setRange(range, nullptr); manager.setRange(range, nullptr);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const btBoxShape boxShape(btVector3(20, 20, 100)); const btBoxShape boxShape(btVector3(20, 20, 100));
const btTransform transform( const btTransform transform(
@ -186,23 +183,23 @@ namespace
const CollisionShape shape(mInstance, boxShape, mObjectTransform); const CollisionShape shape(mInstance, boxShape, mObjectTransform);
manager.addObject(ObjectId(&boxShape), shape, transform, AreaType::AreaType_ground, nullptr); manager.addObject(ObjectId(&boxShape), shape, transform, AreaType::AreaType_ground, nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(0, -1)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(0, -1)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(0, 0)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(0, 0)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(1, 0)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(1, 0)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(1, -1)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(1, -1)), nullptr);
manager.updateObject(ObjectId(&boxShape), btTransform::getIdentity(), AreaType::AreaType_ground, nullptr); manager.updateObject(ObjectId(&boxShape), btTransform::getIdentity(), AreaType::AreaType_ground, nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(-1, -1)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(-1, -1)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(-1, 0)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(-1, 0)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(0, -1)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(0, -1)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(0, 0)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(0, 0)), nullptr);
} }
TEST_F( TEST_F(
DetourNavigatorTileCachedRecastMeshManagerTest, get_mesh_for_moved_object_should_return_nullptr_for_unused_tile) DetourNavigatorTileCachedRecastMeshManagerTest, get_mesh_for_moved_object_should_return_nullptr_for_unused_tile)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const btBoxShape boxShape(btVector3(20, 20, 100)); const btBoxShape boxShape(btVector3(20, 20, 100));
const btTransform transform( const btTransform transform(
@ -210,48 +207,48 @@ namespace
const CollisionShape shape(mInstance, boxShape, mObjectTransform); const CollisionShape shape(mInstance, boxShape, mObjectTransform);
manager.addObject(ObjectId(&boxShape), shape, transform, AreaType::AreaType_ground, nullptr); manager.addObject(ObjectId(&boxShape), shape, transform, AreaType::AreaType_ground, nullptr);
EXPECT_EQ(manager.getMesh(mWorldspace, TilePosition(-1, -1)), nullptr); EXPECT_EQ(manager.getMesh("worldspace", TilePosition(-1, -1)), nullptr);
EXPECT_EQ(manager.getMesh(mWorldspace, TilePosition(-1, 0)), nullptr); EXPECT_EQ(manager.getMesh("worldspace", TilePosition(-1, 0)), nullptr);
manager.updateObject(ObjectId(&boxShape), btTransform::getIdentity(), AreaType::AreaType_ground, nullptr); manager.updateObject(ObjectId(&boxShape), btTransform::getIdentity(), AreaType::AreaType_ground, nullptr);
EXPECT_EQ(manager.getMesh(mWorldspace, TilePosition(1, 0)), nullptr); EXPECT_EQ(manager.getMesh("worldspace", TilePosition(1, 0)), nullptr);
EXPECT_EQ(manager.getMesh(mWorldspace, TilePosition(1, -1)), nullptr); EXPECT_EQ(manager.getMesh("worldspace", TilePosition(1, -1)), nullptr);
} }
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest,
get_mesh_for_removed_object_should_return_nullptr_for_all_previously_used_tiles) get_mesh_for_removed_object_should_return_nullptr_for_all_previously_used_tiles)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const btBoxShape boxShape(btVector3(20, 20, 100)); const btBoxShape boxShape(btVector3(20, 20, 100));
const CollisionShape shape(mInstance, boxShape, mObjectTransform); const CollisionShape shape(mInstance, boxShape, mObjectTransform);
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr); manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr);
manager.removeObject(ObjectId(&boxShape), nullptr); manager.removeObject(ObjectId(&boxShape), nullptr);
EXPECT_EQ(manager.getMesh(mWorldspace, TilePosition(-1, -1)), nullptr); EXPECT_EQ(manager.getMesh("worldspace", TilePosition(-1, -1)), nullptr);
EXPECT_EQ(manager.getMesh(mWorldspace, TilePosition(-1, 0)), nullptr); EXPECT_EQ(manager.getMesh("worldspace", TilePosition(-1, 0)), nullptr);
EXPECT_EQ(manager.getMesh(mWorldspace, TilePosition(0, -1)), nullptr); EXPECT_EQ(manager.getMesh("worldspace", TilePosition(0, -1)), nullptr);
EXPECT_EQ(manager.getMesh(mWorldspace, TilePosition(0, 0)), nullptr); EXPECT_EQ(manager.getMesh("worldspace", TilePosition(0, 0)), nullptr);
} }
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest,
get_mesh_for_not_changed_object_after_update_should_return_recast_mesh_for_same_tiles) get_mesh_for_not_changed_object_after_update_should_return_recast_mesh_for_same_tiles)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const btBoxShape boxShape(btVector3(20, 20, 100)); const btBoxShape boxShape(btVector3(20, 20, 100));
const CollisionShape shape(mInstance, boxShape, mObjectTransform); const CollisionShape shape(mInstance, boxShape, mObjectTransform);
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr); manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(-1, -1)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(-1, -1)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(-1, 0)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(-1, 0)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(0, -1)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(0, -1)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(0, 0)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(0, 0)), nullptr);
manager.updateObject(ObjectId(&boxShape), btTransform::getIdentity(), AreaType::AreaType_ground, nullptr); manager.updateObject(ObjectId(&boxShape), btTransform::getIdentity(), AreaType::AreaType_ground, nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(-1, -1)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(-1, -1)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(-1, 0)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(-1, 0)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(0, -1)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(0, -1)), nullptr);
EXPECT_NE(manager.getMesh(mWorldspace, TilePosition(0, 0)), nullptr); EXPECT_NE(manager.getMesh("worldspace", TilePosition(0, 0)), nullptr);
} }
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest,
@ -296,7 +293,7 @@ namespace
get_revision_after_update_not_changed_object_should_return_same_value) get_revision_after_update_not_changed_object_should_return_same_value)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const btBoxShape boxShape(btVector3(20, 20, 100)); const btBoxShape boxShape(btVector3(20, 20, 100));
const CollisionShape shape(mInstance, boxShape, mObjectTransform); const CollisionShape shape(mInstance, boxShape, mObjectTransform);
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr); manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr);
@ -342,19 +339,19 @@ namespace
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_water_for_not_max_int_should_add_new_tiles) TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_water_for_not_max_int_should_add_new_tiles)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const osg::Vec2i cellPosition(0, 0); const osg::Vec2i cellPosition(0, 0);
const int cellSize = 8192; const int cellSize = 8192;
manager.addWater(cellPosition, cellSize, 0.0f, nullptr); manager.addWater(cellPosition, cellSize, 0.0f, nullptr);
for (int x = -1; x < 12; ++x) for (int x = -1; x < 12; ++x)
for (int y = -1; y < 12; ++y) for (int y = -1; y < 12; ++y)
ASSERT_NE(manager.getMesh(mWorldspace, TilePosition(x, y)), nullptr); ASSERT_NE(manager.getMesh("worldspace", TilePosition(x, y)), nullptr);
} }
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_water_for_max_int_should_not_add_new_tiles) TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_water_for_max_int_should_not_add_new_tiles)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const btBoxShape boxShape(btVector3(20, 20, 100)); const btBoxShape boxShape(btVector3(20, 20, 100));
const CollisionShape shape(mInstance, boxShape, mObjectTransform); const CollisionShape shape(mInstance, boxShape, mObjectTransform);
ASSERT_TRUE(manager.addObject( ASSERT_TRUE(manager.addObject(
@ -364,7 +361,7 @@ namespace
manager.addWater(cellPosition, cellSize, 0.0f, nullptr); manager.addWater(cellPosition, cellSize, 0.0f, nullptr);
for (int x = -6; x < 6; ++x) for (int x = -6; x < 6; ++x)
for (int y = -6; y < 6; ++y) for (int y = -6; y < 6; ++y)
ASSERT_EQ(manager.getMesh(mWorldspace, TilePosition(x, y)) != nullptr, ASSERT_EQ(manager.getMesh("worldspace", TilePosition(x, y)) != nullptr,
-1 <= x && x <= 0 && -1 <= y && y <= 0); -1 <= x && x <= 0 && -1 <= y && y <= 0);
} }
@ -393,20 +390,20 @@ namespace
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, remove_water_for_existing_cell_should_remove_empty_tiles) TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, remove_water_for_existing_cell_should_remove_empty_tiles)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const osg::Vec2i cellPosition(0, 0); const osg::Vec2i cellPosition(0, 0);
const int cellSize = 8192; const int cellSize = 8192;
manager.addWater(cellPosition, cellSize, 0.0f, nullptr); manager.addWater(cellPosition, cellSize, 0.0f, nullptr);
manager.removeWater(cellPosition, nullptr); manager.removeWater(cellPosition, nullptr);
for (int x = -6; x < 6; ++x) for (int x = -6; x < 6; ++x)
for (int y = -6; y < 6; ++y) for (int y = -6; y < 6; ++y)
ASSERT_EQ(manager.getMesh(mWorldspace, TilePosition(x, y)), nullptr); ASSERT_EQ(manager.getMesh("worldspace", TilePosition(x, y)), nullptr);
} }
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, remove_water_for_existing_cell_should_leave_not_empty_tiles) TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, remove_water_for_existing_cell_should_leave_not_empty_tiles)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const btBoxShape boxShape(btVector3(20, 20, 100)); const btBoxShape boxShape(btVector3(20, 20, 100));
const CollisionShape shape(mInstance, boxShape, mObjectTransform); const CollisionShape shape(mInstance, boxShape, mObjectTransform);
ASSERT_TRUE(manager.addObject( ASSERT_TRUE(manager.addObject(
@ -417,14 +414,14 @@ namespace
manager.removeWater(cellPosition, nullptr); manager.removeWater(cellPosition, nullptr);
for (int x = -6; x < 6; ++x) for (int x = -6; x < 6; ++x)
for (int y = -6; y < 6; ++y) for (int y = -6; y < 6; ++y)
ASSERT_EQ(manager.getMesh(mWorldspace, TilePosition(x, y)) != nullptr, ASSERT_EQ(manager.getMesh("worldspace", TilePosition(x, y)) != nullptr,
-1 <= x && x <= 0 && -1 <= y && y <= 0); -1 <= x && x <= 0 && -1 <= y && y <= 0);
} }
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, remove_object_should_not_remove_tile_with_water) TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, remove_object_should_not_remove_tile_with_water)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const osg::Vec2i cellPosition(0, 0); const osg::Vec2i cellPosition(0, 0);
const int cellSize = 8192; const int cellSize = 8192;
const btBoxShape boxShape(btVector3(20, 20, 100)); const btBoxShape boxShape(btVector3(20, 20, 100));
@ -435,21 +432,21 @@ namespace
manager.removeObject(ObjectId(&boxShape), nullptr); manager.removeObject(ObjectId(&boxShape), nullptr);
for (int x = -1; x < 12; ++x) for (int x = -1; x < 12; ++x)
for (int y = -1; y < 12; ++y) for (int y = -1; y < 12; ++y)
ASSERT_NE(manager.getMesh(mWorldspace, TilePosition(x, y)), nullptr); ASSERT_NE(manager.getMesh("worldspace", TilePosition(x, y)), nullptr);
} }
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, set_new_worldspace_should_remove_tiles) TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, set_new_worldspace_should_remove_tiles)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
manager.setWorldspace(mWorldspace, nullptr); manager.setWorldspace("worldspace", nullptr);
const btBoxShape boxShape(btVector3(20, 20, 100)); const btBoxShape boxShape(btVector3(20, 20, 100));
const CollisionShape shape(nullptr, boxShape, mObjectTransform); const CollisionShape shape(nullptr, boxShape, mObjectTransform);
ASSERT_TRUE(manager.addObject( ASSERT_TRUE(manager.addObject(
ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr)); ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground, nullptr));
manager.setWorldspace(mOtherWorldspace, nullptr); manager.setWorldspace("other", nullptr);
for (int x = -1; x < 1; ++x) for (int x = -1; x < 1; ++x)
for (int y = -1; y < 1; ++y) for (int y = -1; y < 1; ++y)
ASSERT_EQ(manager.getMesh(mOtherWorldspace, TilePosition(x, y)), nullptr); ASSERT_EQ(manager.getMesh("other", TilePosition(x, y)), nullptr);
} }
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, set_bounds_should_add_changed_tiles) TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, set_bounds_should_add_changed_tiles)

View file

@ -8,7 +8,6 @@
#include "version.hpp" #include "version.hpp"
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/esm/refid.hpp>
#include <components/loadinglistener/loadinglistener.hpp> #include <components/loadinglistener/loadinglistener.hpp>
#include <components/misc/thread.hpp> #include <components/misc/thread.hpp>
@ -136,7 +135,7 @@ namespace DetourNavigator
} }
Job::Job(const AgentBounds& agentBounds, std::weak_ptr<GuardedNavMeshCacheItem> navMeshCacheItem, Job::Job(const AgentBounds& agentBounds, std::weak_ptr<GuardedNavMeshCacheItem> navMeshCacheItem,
const ESM::RefId& worldspace, const TilePosition& changedTile, ChangeType changeType, int distanceToPlayer, std::string_view worldspace, const TilePosition& changedTile, ChangeType changeType, int distanceToPlayer,
std::chrono::steady_clock::time_point processTime) std::chrono::steady_clock::time_point processTime)
: mId(getNextJobId()) : mId(getNextJobId())
, mAgentBounds(agentBounds) , mAgentBounds(agentBounds)
@ -169,7 +168,7 @@ namespace DetourNavigator
} }
void AsyncNavMeshUpdater::post(const AgentBounds& agentBounds, const SharedNavMeshCacheItem& navMeshCacheItem, void AsyncNavMeshUpdater::post(const AgentBounds& agentBounds, const SharedNavMeshCacheItem& navMeshCacheItem,
const TilePosition& playerTile, const ESM::RefId& worldspace, const TilePosition& playerTile, std::string_view worldspace,
const std::map<TilePosition, ChangeType>& changedTiles) const std::map<TilePosition, ChangeType>& changedTiles)
{ {
bool playerTileChanged = false; bool playerTileChanged = false;

View file

@ -14,8 +14,6 @@
#include "tileposition.hpp" #include "tileposition.hpp"
#include "waitconditiontype.hpp" #include "waitconditiontype.hpp"
#include <components/esm/refid.hpp>
#include <osg/Vec3f> #include <osg/Vec3f>
#include <atomic> #include <atomic>
@ -51,7 +49,7 @@ namespace DetourNavigator
const std::size_t mId; const std::size_t mId;
const AgentBounds mAgentBounds; const AgentBounds mAgentBounds;
const std::weak_ptr<GuardedNavMeshCacheItem> mNavMeshCacheItem; const std::weak_ptr<GuardedNavMeshCacheItem> mNavMeshCacheItem;
const ESM::RefId mWorldspace; const std::string mWorldspace;
const TilePosition mChangedTile; const TilePosition mChangedTile;
const std::chrono::steady_clock::time_point mProcessTime; const std::chrono::steady_clock::time_point mProcessTime;
unsigned mTryNumber = 0; unsigned mTryNumber = 0;
@ -65,7 +63,7 @@ namespace DetourNavigator
std::unique_ptr<PreparedNavMeshData> mGeneratedNavMeshData; std::unique_ptr<PreparedNavMeshData> mGeneratedNavMeshData;
Job(const AgentBounds& agentBounds, std::weak_ptr<GuardedNavMeshCacheItem> navMeshCacheItem, Job(const AgentBounds& agentBounds, std::weak_ptr<GuardedNavMeshCacheItem> navMeshCacheItem,
const ESM::RefId& worldspace, const TilePosition& changedTile, ChangeType changeType, int distanceToPlayer, std::string_view worldspace, const TilePosition& changedTile, ChangeType changeType, int distanceToPlayer,
std::chrono::steady_clock::time_point processTime); std::chrono::steady_clock::time_point processTime);
}; };
@ -150,7 +148,7 @@ namespace DetourNavigator
~AsyncNavMeshUpdater(); ~AsyncNavMeshUpdater();
void post(const AgentBounds& agentBounds, const SharedNavMeshCacheItem& navMeshCacheItem, void post(const AgentBounds& agentBounds, const SharedNavMeshCacheItem& navMeshCacheItem,
const TilePosition& playerTile, const ESM::RefId& worldspace, const TilePosition& playerTile, std::string_view worldspace,
const std::map<TilePosition, ChangeType>& changedTiles); const std::map<TilePosition, ChangeType>& changedTiles);
void wait(WaitConditionType waitConditionType, Loading::Listener* listener); void wait(WaitConditionType waitConditionType, Loading::Listener* listener);

View file

@ -7,7 +7,6 @@
#include "settings.hpp" #include "settings.hpp"
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/esm/refid.hpp>
#include <osg/Vec3f> #include <osg/Vec3f>
#include <osg/io_utils> #include <osg/io_utils>
@ -24,7 +23,7 @@ namespace DetourNavigator
{ {
struct Ignore struct Ignore
{ {
const ESM::RefId& mWorldspace; std::string_view mWorldspace;
const TilePosition& mTilePosition; const TilePosition& mTilePosition;
std::shared_ptr<NavMeshTileConsumer> mConsumer; std::shared_ptr<NavMeshTileConsumer> mConsumer;
@ -36,7 +35,7 @@ namespace DetourNavigator
}; };
} }
GenerateNavMeshTile::GenerateNavMeshTile(ESM::RefId worldspace, const TilePosition& tilePosition, GenerateNavMeshTile::GenerateNavMeshTile(std::string worldspace, const TilePosition& tilePosition,
RecastMeshProvider recastMeshProvider, const AgentBounds& agentBounds, RecastMeshProvider recastMeshProvider, const AgentBounds& agentBounds,
const DetourNavigator::Settings& settings, std::weak_ptr<NavMeshTileConsumer> consumer) const DetourNavigator::Settings& settings, std::weak_ptr<NavMeshTileConsumer> consumer)
: mWorldspace(std::move(worldspace)) : mWorldspace(std::move(worldspace))

View file

@ -5,7 +5,6 @@
#include "recastmeshprovider.hpp" #include "recastmeshprovider.hpp"
#include "tileposition.hpp" #include "tileposition.hpp"
#include <components/esm/refid.hpp>
#include <components/sceneutil/workqueue.hpp> #include <components/sceneutil/workqueue.hpp>
#include <osg/Vec3f> #include <osg/Vec3f>
@ -39,18 +38,18 @@ namespace DetourNavigator
virtual std::int64_t resolveMeshSource(const MeshSource& source) = 0; virtual std::int64_t resolveMeshSource(const MeshSource& source) = 0;
virtual std::optional<NavMeshTileInfo> find( virtual std::optional<NavMeshTileInfo> find(
const ESM::RefId& worldspace, const TilePosition& tilePosition, const std::vector<std::byte>& input) std::string_view worldspace, const TilePosition& tilePosition, const std::vector<std::byte>& input)
= 0; = 0;
virtual void ignore(const ESM::RefId& worldspace, const TilePosition& tilePosition) = 0; virtual void ignore(std::string_view worldspace, const TilePosition& tilePosition) = 0;
virtual void identity(const ESM::RefId& worldspace, const TilePosition& tilePosition, std::int64_t tileId) = 0; virtual void identity(std::string_view worldspace, const TilePosition& tilePosition, std::int64_t tileId) = 0;
virtual void insert(const ESM::RefId& worldspace, const TilePosition& tilePosition, std::int64_t version, virtual void insert(std::string_view worldspace, const TilePosition& tilePosition, std::int64_t version,
const std::vector<std::byte>& input, PreparedNavMeshData& data) const std::vector<std::byte>& input, PreparedNavMeshData& data)
= 0; = 0;
virtual void update(const ESM::RefId& worldspace, const TilePosition& tilePosition, std::int64_t tileId, virtual void update(std::string_view worldspace, const TilePosition& tilePosition, std::int64_t tileId,
std::int64_t version, PreparedNavMeshData& data) std::int64_t version, PreparedNavMeshData& data)
= 0; = 0;
@ -60,14 +59,14 @@ namespace DetourNavigator
class GenerateNavMeshTile final : public SceneUtil::WorkItem class GenerateNavMeshTile final : public SceneUtil::WorkItem
{ {
public: public:
GenerateNavMeshTile(ESM::RefId worldspace, const TilePosition& tilePosition, GenerateNavMeshTile(std::string worldspace, const TilePosition& tilePosition,
RecastMeshProvider recastMeshProvider, const AgentBounds& agentBounds, const Settings& settings, RecastMeshProvider recastMeshProvider, const AgentBounds& agentBounds, const Settings& settings,
std::weak_ptr<NavMeshTileConsumer> consumer); std::weak_ptr<NavMeshTileConsumer> consumer);
void doWork() final; void doWork() final;
private: private:
const ESM::RefId mWorldspace; const std::string mWorldspace;
const TilePosition mTilePosition; const TilePosition mTilePosition;
const RecastMeshProvider mRecastMeshProvider; const RecastMeshProvider mRecastMeshProvider;
const AgentBounds mAgentBounds; const AgentBounds mAgentBounds;

View file

@ -91,7 +91,7 @@ namespace DetourNavigator
* @brief setWorldspace should be called before adding object from new worldspace * @brief setWorldspace should be called before adding object from new worldspace
* @param worldspace * @param worldspace
*/ */
virtual void setWorldspace(const ESM::RefId& worldspace, const UpdateGuard* guard) = 0; virtual void setWorldspace(std::string_view worldspace, const UpdateGuard* guard) = 0;
/** /**
* @brief updateBounds should be called before adding object from loading cell * @brief updateBounds should be called before adding object from loading cell

View file

@ -34,7 +34,7 @@ namespace DetourNavigator
--it->second; --it->second;
} }
void NavigatorImpl::setWorldspace(const ESM::RefId& worldspace, const UpdateGuard* guard) void NavigatorImpl::setWorldspace(std::string_view worldspace, const UpdateGuard* guard)
{ {
mNavMeshManager.setWorldspace(worldspace, getImpl(guard)); mNavMeshManager.setWorldspace(worldspace, getImpl(guard));
} }

View file

@ -27,7 +27,7 @@ namespace DetourNavigator
void removeAgent(const AgentBounds& agentBounds) override; void removeAgent(const AgentBounds& agentBounds) override;
void setWorldspace(const ESM::RefId& worldspace, const UpdateGuard* guard) override; void setWorldspace(std::string_view worldspace, const UpdateGuard* guard) override;
void updateBounds(const osg::Vec3f& playerPosition, const UpdateGuard* guard) override; void updateBounds(const osg::Vec3f& playerPosition, const UpdateGuard* guard) override;

View file

@ -23,7 +23,7 @@ namespace DetourNavigator
void removeAgent(const AgentBounds& /*agentBounds*/) override {} void removeAgent(const AgentBounds& /*agentBounds*/) override {}
void setWorldspace(const ESM::RefId& /*worldspace*/, const UpdateGuard* /*guard*/) override {} void setWorldspace(std::string_view /*worldspace*/, const UpdateGuard* /*guard*/) override {}
void addObject(const ObjectId /*id*/, const ObjectShapes& /*shapes*/, const btTransform& /*transform*/, void addObject(const ObjectId /*id*/, const ObjectShapes& /*shapes*/, const btTransform& /*transform*/,
const UpdateGuard* /*guard*/) override const UpdateGuard* /*guard*/) override

View file

@ -1,10 +1,8 @@
#include "navmeshdb.hpp" #include "navmeshdb.hpp"
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/esm/refid.hpp>
#include <components/misc/compression.hpp> #include <components/misc/compression.hpp>
#include <components/misc/strings/format.hpp> #include <components/misc/strings/format.hpp>
#include <components/misc/strings/lower.hpp>
#include <components/sqlite3/db.hpp> #include <components/sqlite3/db.hpp>
#include <components/sqlite3/request.hpp> #include <components/sqlite3/request.hpp>
@ -154,11 +152,6 @@ namespace DetourNavigator
if (const int ec = sqlite3_exec(&db, query.c_str(), nullptr, nullptr, nullptr); ec != SQLITE_OK) if (const int ec = sqlite3_exec(&db, query.c_str(), nullptr, nullptr, nullptr); ec != SQLITE_OK)
throw std::runtime_error("Failed set max page count: " + std::string(sqlite3_errmsg(&db))); throw std::runtime_error("Failed set max page count: " + std::string(sqlite3_errmsg(&db)));
} }
std::string toLowerCaseString(const ESM::RefId& refId)
{
return Misc::StringUtils::lowerCase(refId.getRefIdString());
}
} }
std::ostream& operator<<(std::ostream& stream, ShapeType value) std::ostream& operator<<(std::ostream& stream, ShapeType value)
@ -207,35 +200,34 @@ namespace DetourNavigator
} }
std::optional<Tile> NavMeshDb::findTile( std::optional<Tile> NavMeshDb::findTile(
const ESM::RefId& worldspace, const TilePosition& tilePosition, const std::vector<std::byte>& input) std::string_view worldspace, const TilePosition& tilePosition, const std::vector<std::byte>& input)
{ {
Tile result; Tile result;
auto row = std::tie(result.mTileId, result.mVersion); auto row = std::tie(result.mTileId, result.mVersion);
const std::vector<std::byte> compressedInput = Misc::compress(input); const std::vector<std::byte> compressedInput = Misc::compress(input);
if (&row == request(*mDb, mFindTile, &row, 1, toLowerCaseString(worldspace), tilePosition, compressedInput)) if (&row == request(*mDb, mFindTile, &row, 1, worldspace, tilePosition, compressedInput))
return {}; return {};
return result; return result;
} }
std::optional<TileData> NavMeshDb::getTileData( std::optional<TileData> NavMeshDb::getTileData(
const ESM::RefId& worldspace, const TilePosition& tilePosition, const std::vector<std::byte>& input) std::string_view worldspace, const TilePosition& tilePosition, const std::vector<std::byte>& input)
{ {
TileData result; TileData result;
auto row = std::tie(result.mTileId, result.mVersion, result.mData); auto row = std::tie(result.mTileId, result.mVersion, result.mData);
const std::vector<std::byte> compressedInput = Misc::compress(input); const std::vector<std::byte> compressedInput = Misc::compress(input);
if (&row == request(*mDb, mGetTileData, &row, 1, toLowerCaseString(worldspace), tilePosition, compressedInput)) if (&row == request(*mDb, mGetTileData, &row, 1, worldspace, tilePosition, compressedInput))
return {}; return {};
result.mData = Misc::decompress(result.mData); result.mData = Misc::decompress(result.mData);
return result; return result;
} }
int NavMeshDb::insertTile(TileId tileId, const ESM::RefId& worldspace, const TilePosition& tilePosition, int NavMeshDb::insertTile(TileId tileId, std::string_view worldspace, const TilePosition& tilePosition,
TileVersion version, const std::vector<std::byte>& input, const std::vector<std::byte>& data) TileVersion version, const std::vector<std::byte>& input, const std::vector<std::byte>& data)
{ {
const std::vector<std::byte> compressedInput = Misc::compress(input); const std::vector<std::byte> compressedInput = Misc::compress(input);
const std::vector<std::byte> compressedData = Misc::compress(data); const std::vector<std::byte> compressedData = Misc::compress(data);
return execute(*mDb, mInsertTile, tileId, toLowerCaseString(worldspace), tilePosition, version, compressedInput, return execute(*mDb, mInsertTile, tileId, worldspace, tilePosition, version, compressedInput, compressedData);
compressedData);
} }
int NavMeshDb::updateTile(TileId tileId, TileVersion version, const std::vector<std::byte>& data) int NavMeshDb::updateTile(TileId tileId, TileVersion version, const std::vector<std::byte>& data)
@ -244,20 +236,20 @@ namespace DetourNavigator
return execute(*mDb, mUpdateTile, tileId, version, compressedData); return execute(*mDb, mUpdateTile, tileId, version, compressedData);
} }
int NavMeshDb::deleteTilesAt(const ESM::RefId& worldspace, const TilePosition& tilePosition) int NavMeshDb::deleteTilesAt(std::string_view worldspace, const TilePosition& tilePosition)
{ {
return execute(*mDb, mDeleteTilesAt, toLowerCaseString(worldspace), tilePosition); return execute(*mDb, mDeleteTilesAt, worldspace, tilePosition);
} }
int NavMeshDb::deleteTilesAtExcept( int NavMeshDb::deleteTilesAtExcept(
const ESM::RefId& worldspace, const TilePosition& tilePosition, TileId excludeTileId) std::string_view worldspace, const TilePosition& tilePosition, TileId excludeTileId)
{ {
return execute(*mDb, mDeleteTilesAtExcept, toLowerCaseString(worldspace), tilePosition, excludeTileId); return execute(*mDb, mDeleteTilesAtExcept, worldspace, tilePosition, excludeTileId);
} }
int NavMeshDb::deleteTilesOutsideRange(const ESM::RefId& worldspace, const TilesPositionsRange& range) int NavMeshDb::deleteTilesOutsideRange(std::string_view worldspace, const TilesPositionsRange& range)
{ {
return execute(*mDb, mDeleteTilesOutsideRange, toLowerCaseString(worldspace), range); return execute(*mDb, mDeleteTilesOutsideRange, worldspace, range);
} }
ShapeId NavMeshDb::getMaxShapeId() ShapeId NavMeshDb::getMaxShapeId()

View file

@ -25,11 +25,6 @@
struct sqlite3; struct sqlite3;
struct sqlite3_stmt; struct sqlite3_stmt;
namespace ESM
{
struct RefId;
}
namespace DetourNavigator namespace DetourNavigator
{ {
using TileId = Misc::StrongTypedef<std::int64_t, struct TiledIdTag>; using TileId = Misc::StrongTypedef<std::int64_t, struct TiledIdTag>;
@ -153,21 +148,21 @@ namespace DetourNavigator
TileId getMaxTileId(); TileId getMaxTileId();
std::optional<Tile> findTile( std::optional<Tile> findTile(
const ESM::RefId& worldspace, const TilePosition& tilePosition, const std::vector<std::byte>& input); std::string_view worldspace, const TilePosition& tilePosition, const std::vector<std::byte>& input);
std::optional<TileData> getTileData( std::optional<TileData> getTileData(
const ESM::RefId& worldspace, const TilePosition& tilePosition, const std::vector<std::byte>& input); std::string_view worldspace, const TilePosition& tilePosition, const std::vector<std::byte>& input);
int insertTile(TileId tileId, const ESM::RefId& worldspace, const TilePosition& tilePosition, int insertTile(TileId tileId, std::string_view worldspace, const TilePosition& tilePosition,
TileVersion version, const std::vector<std::byte>& input, const std::vector<std::byte>& data); TileVersion version, const std::vector<std::byte>& input, const std::vector<std::byte>& data);
int updateTile(TileId tileId, TileVersion version, const std::vector<std::byte>& data); int updateTile(TileId tileId, TileVersion version, const std::vector<std::byte>& data);
int deleteTilesAt(const ESM::RefId& worldspace, const TilePosition& tilePosition); int deleteTilesAt(std::string_view worldspace, const TilePosition& tilePosition);
int deleteTilesAtExcept(const ESM::RefId& worldspace, const TilePosition& tilePosition, TileId excludeTileId); int deleteTilesAtExcept(std::string_view worldspace, const TilePosition& tilePosition, TileId excludeTileId);
int deleteTilesOutsideRange(const ESM::RefId& worldspace, const TilesPositionsRange& range); int deleteTilesOutsideRange(std::string_view worldspace, const TilesPositionsRange& range);
ShapeId getMaxShapeId(); ShapeId getMaxShapeId();

View file

@ -10,7 +10,6 @@
#include <components/bullethelpers/heightfield.hpp> #include <components/bullethelpers/heightfield.hpp>
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/esm/refid.hpp>
#include <components/misc/convert.hpp> #include <components/misc/convert.hpp>
#include <osg/io_utils> #include <osg/io_utils>
@ -64,7 +63,7 @@ namespace DetourNavigator
{ {
} }
void NavMeshManager::setWorldspace(const ESM::RefId& worldspace, const UpdateGuard* guard) void NavMeshManager::setWorldspace(std::string_view worldspace, const UpdateGuard* guard)
{ {
if (worldspace == mWorldspace) if (worldspace == mWorldspace)
return; return;

View file

@ -8,8 +8,6 @@
#include "recastmeshtiles.hpp" #include "recastmeshtiles.hpp"
#include "waitconditiontype.hpp" #include "waitconditiontype.hpp"
#include <components/esm/refid.hpp>
#include <osg/Vec3f> #include <osg/Vec3f>
#include <map> #include <map>
@ -41,7 +39,7 @@ namespace DetourNavigator
explicit NavMeshManager(const Settings& settings, std::unique_ptr<NavMeshDb>&& db); explicit NavMeshManager(const Settings& settings, std::unique_ptr<NavMeshDb>&& db);
void setWorldspace(const ESM::RefId& worldspace, const UpdateGuard* guard); void setWorldspace(std::string_view worldspace, const UpdateGuard* guard);
void updateBounds(const osg::Vec3f& playerPosition, const UpdateGuard* guard); void updateBounds(const osg::Vec3f& playerPosition, const UpdateGuard* guard);
@ -84,7 +82,7 @@ namespace DetourNavigator
private: private:
const Settings& mSettings; const Settings& mSettings;
ESM::RefId mWorldspace; std::string mWorldspace;
TileCachedRecastMeshManager mRecastMeshManager; TileCachedRecastMeshManager mRecastMeshManager;
OffMeshConnectionsManager mOffMeshConnectionsManager; OffMeshConnectionsManager mOffMeshConnectionsManager;
AsyncNavMeshUpdater mAsyncNavMeshUpdater; AsyncNavMeshUpdater mAsyncNavMeshUpdater;

View file

@ -20,7 +20,7 @@ namespace DetourNavigator
{ {
} }
std::shared_ptr<RecastMesh> getMesh(const ESM::RefId& worldspace, const TilePosition& tilePosition) const std::shared_ptr<RecastMesh> getMesh(std::string_view worldspace, const TilePosition& tilePosition) const
{ {
return mImpl.get().getNewMesh(worldspace, tilePosition); return mImpl.get().getNewMesh(worldspace, tilePosition);
} }

View file

@ -5,7 +5,6 @@
#include "settingsutils.hpp" #include "settingsutils.hpp"
#include <components/bullethelpers/aabb.hpp> #include <components/bullethelpers/aabb.hpp>
#include <components/esm/refid.hpp>
#include <components/misc/convert.hpp> #include <components/misc/convert.hpp>
#include <boost/geometry/geometry.hpp> #include <boost/geometry/geometry.hpp>
@ -114,7 +113,7 @@ namespace DetourNavigator
return getIntersection(mRange, objectsRange); return getIntersection(mRange, objectsRange);
} }
void TileCachedRecastMeshManager::setWorldspace(const ESM::RefId& worldspace, const UpdateGuard* guard) void TileCachedRecastMeshManager::setWorldspace(std::string_view worldspace, const UpdateGuard* guard)
{ {
const MaybeLockGuard lock(mMutex, guard); const MaybeLockGuard lock(mMutex, guard);
if (mWorldspace == worldspace) if (mWorldspace == worldspace)
@ -323,7 +322,7 @@ namespace DetourNavigator
} }
std::shared_ptr<RecastMesh> TileCachedRecastMeshManager::getMesh( std::shared_ptr<RecastMesh> TileCachedRecastMeshManager::getMesh(
const ESM::RefId& worldspace, const TilePosition& tilePosition) std::string_view worldspace, const TilePosition& tilePosition)
{ {
{ {
const std::lock_guard lock(mMutex); const std::lock_guard lock(mMutex);
@ -347,7 +346,7 @@ namespace DetourNavigator
} }
std::shared_ptr<RecastMesh> TileCachedRecastMeshManager::getCachedMesh( std::shared_ptr<RecastMesh> TileCachedRecastMeshManager::getCachedMesh(
const ESM::RefId& worldspace, const TilePosition& tilePosition) const std::string_view worldspace, const TilePosition& tilePosition) const
{ {
const std::lock_guard lock(mMutex); const std::lock_guard lock(mMutex);
if (mWorldspace != worldspace) if (mWorldspace != worldspace)
@ -359,7 +358,7 @@ namespace DetourNavigator
} }
std::shared_ptr<RecastMesh> TileCachedRecastMeshManager::getNewMesh( std::shared_ptr<RecastMesh> TileCachedRecastMeshManager::getNewMesh(
const ESM::RefId& worldspace, const TilePosition& tilePosition) const std::string_view worldspace, const TilePosition& tilePosition) const
{ {
{ {
const std::lock_guard lock(mMutex); const std::lock_guard lock(mMutex);

View file

@ -12,8 +12,6 @@
#include "tileposition.hpp" #include "tileposition.hpp"
#include "version.hpp" #include "version.hpp"
#include <components/esm/refid.hpp>
#include <boost/geometry/geometries/box.hpp> #include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/point.hpp> #include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/index/rtree.hpp> #include <boost/geometry/index/rtree.hpp>
@ -48,7 +46,7 @@ namespace DetourNavigator
TilesPositionsRange getLimitedObjectsRange() const; TilesPositionsRange getLimitedObjectsRange() const;
void setWorldspace(const ESM::RefId& worldspace, const UpdateGuard* guard); void setWorldspace(std::string_view worldspace, const UpdateGuard* guard);
bool addObject(ObjectId id, const CollisionShape& shape, const btTransform& transform, AreaType areaType, bool addObject(ObjectId id, const CollisionShape& shape, const btTransform& transform, AreaType areaType,
const UpdateGuard* guard); const UpdateGuard* guard);
@ -66,11 +64,11 @@ namespace DetourNavigator
void removeHeightfield(const osg::Vec2i& cellPosition, const UpdateGuard* guard); void removeHeightfield(const osg::Vec2i& cellPosition, const UpdateGuard* guard);
std::shared_ptr<RecastMesh> getMesh(const ESM::RefId& worldspace, const TilePosition& tilePosition); std::shared_ptr<RecastMesh> getMesh(std::string_view worldspace, const TilePosition& tilePosition);
std::shared_ptr<RecastMesh> getCachedMesh(const ESM::RefId& worldspace, const TilePosition& tilePosition) const; std::shared_ptr<RecastMesh> getCachedMesh(std::string_view worldspace, const TilePosition& tilePosition) const;
std::shared_ptr<RecastMesh> getNewMesh(const ESM::RefId& worldspace, const TilePosition& tilePosition) const; std::shared_ptr<RecastMesh> getNewMesh(std::string_view worldspace, const TilePosition& tilePosition) const;
std::size_t getRevision() const { return mRevision; } std::size_t getRevision() const { return mRevision; }
@ -127,7 +125,7 @@ namespace DetourNavigator
const RecastSettings& mSettings; const RecastSettings& mSettings;
TilesPositionsRange mRange; TilesPositionsRange mRange;
ESM::RefId mWorldspace; std::string mWorldspace;
std::unordered_map<ObjectId, std::unique_ptr<ObjectData>> mObjects; std::unordered_map<ObjectId, std::unique_ptr<ObjectData>> mObjects;
boost::geometry::index::rtree<ObjectIndexValue, boost::geometry::index::quadratic<16>> mObjectIndex; boost::geometry::index::rtree<ObjectIndexValue, boost::geometry::index::quadratic<16>> mObjectIndex;
std::map<osg::Vec2i, WaterData> mWater; std::map<osg::Vec2i, WaterData> mWater;

View file

@ -54,7 +54,7 @@ namespace ESM
mTargetActorId = -1; mTargetActorId = -1;
esm.getHNOT(mTargetActorId, "TAID"); esm.getHNOT(mTargetActorId, "TAID");
esm.getHNT(mRemainingDuration, "DURA"); esm.getHNT(mRemainingDuration, "DURA");
mCellId = ESM::RefId::stringRefId(esm.getHNOString("CELL")); mCellId = esm.getHNOString("CELL");
mRepeat = false; mRepeat = false;
esm.getHNOT(mRepeat, "REPT"); esm.getHNOT(mRepeat, "REPT");
if (esm.getFormat() < 18) if (esm.getFormat() < 18)
@ -74,7 +74,7 @@ namespace ESM
esm.writeHNT("TAID", mTargetActorId); esm.writeHNT("TAID", mTargetActorId);
esm.writeHNT("DURA", mRemainingDuration); esm.writeHNT("DURA", mRemainingDuration);
if (!mCellId.empty()) if (!mCellId.empty())
esm.writeHNString("CELL", mCellId.getRefIdString()); esm.writeHNString("CELL", mCellId);
if (mRepeat) if (mRepeat)
esm.writeHNT("REPT", mRepeat); esm.writeHNT("REPT", mRepeat);
} }
@ -86,7 +86,7 @@ namespace ESM
mTargetActorId = -1; mTargetActorId = -1;
esm.getHNOT(mTargetActorId, "TAID"); esm.getHNOT(mTargetActorId, "TAID");
esm.getHNT(mRemainingDuration, "DURA"); esm.getHNT(mRemainingDuration, "DURA");
mCellId = ESM::RefId::stringRefId(esm.getHNOString("CELL")); mCellId = esm.getHNOString("CELL");
esm.getHNT(mAlwaysFollow, "ALWY"); esm.getHNT(mAlwaysFollow, "ALWY");
mCommanded = false; mCommanded = false;
esm.getHNOT(mCommanded, "CMND"); esm.getHNOT(mCommanded, "CMND");
@ -111,7 +111,7 @@ namespace ESM
esm.writeHNT("TAID", mTargetActorId); esm.writeHNT("TAID", mTargetActorId);
esm.writeHNT("DURA", mRemainingDuration); esm.writeHNT("DURA", mRemainingDuration);
if (!mCellId.empty()) if (!mCellId.empty())
esm.writeHNString("CELL", mCellId.getRefIdString()); esm.writeHNString("CELL", mCellId);
esm.writeHNT("ALWY", mAlwaysFollow); esm.writeHNT("ALWY", mAlwaysFollow);
esm.writeHNT("CMND", mCommanded); esm.writeHNT("CMND", mCommanded);
if (mActive) if (mActive)

View file

@ -92,7 +92,7 @@ namespace ESM
int mTargetActorId; int mTargetActorId;
ESM::RefId mTargetId; ESM::RefId mTargetId;
ESM::RefId mCellId; std::string mCellId;
float mRemainingDuration; float mRemainingDuration;
bool mRepeat; bool mRepeat;
@ -106,7 +106,7 @@ namespace ESM
int mTargetActorId; int mTargetActorId;
ESM::RefId mTargetId; ESM::RefId mTargetId;
ESM::RefId mCellId; std::string mCellId;
float mRemainingDuration; float mRemainingDuration;
bool mAlwaysFollow; bool mAlwaysFollow;

View file

@ -6,11 +6,11 @@
namespace ESM namespace ESM
{ {
const ESM::RefId CellId::sDefaultWorldspace = ESM::RefId::stringRefId("sys::default"); const std::string CellId::sDefaultWorldspace = "sys::default";
void CellId::load(ESMReader& esm) void CellId::load(ESMReader& esm)
{ {
mWorldspace = ESM::RefId::stringRefId(esm.getHNString("SPAC")); mWorldspace = esm.getHNString("SPAC");
if (esm.isNextSub("CIDX")) if (esm.isNextSub("CIDX"))
{ {
@ -23,7 +23,7 @@ namespace ESM
void CellId::save(ESMWriter& esm) const void CellId::save(ESMWriter& esm) const
{ {
esm.writeHNString("SPAC", mWorldspace.getRefIdString()); esm.writeHNString("SPAC", mWorldspace);
if (mPaged) if (mPaged)
esm.writeHNT("CIDX", mIndex, 8); esm.writeHNT("CIDX", mIndex, 8);

View file

@ -17,11 +17,11 @@ namespace ESM
int mY; int mY;
}; };
ESM::RefId mWorldspace; std::string mWorldspace;
CellIndex mIndex; CellIndex mIndex;
bool mPaged; bool mPaged;
static const ESM::RefId sDefaultWorldspace; static const std::string sDefaultWorldspace;
void load(ESMReader& esm); void load(ESMReader& esm);
void save(ESMWriter& esm) const; void save(ESMWriter& esm) const;

View file

@ -109,7 +109,7 @@ namespace ESM
cellRef.mTeleport = true; cellRef.mTeleport = true;
break; break;
case fourCC("DNAM"): case fourCC("DNAM"):
getRefIdOrSkip(cellRef.mDestCell); getHStringOrSkip(cellRef.mDestCell);
break; break;
case fourCC("FLTV"): case fourCC("FLTV"):
getHTOrSkip(cellRef.mLockLevel); getHTOrSkip(cellRef.mLockLevel);
@ -235,7 +235,7 @@ namespace ESM
if (!inInventory && mTeleport) if (!inInventory && mTeleport)
{ {
esm.writeHNT("DODT", mDoorDest); esm.writeHNT("DODT", mDoorDest);
esm.writeHNOCString("DNAM", mDestCell.getRefIdString()); esm.writeHNOCString("DNAM", mDestCell);
} }
if (!inInventory && mLockLevel != 0) if (!inInventory && mLockLevel != 0)
@ -270,7 +270,7 @@ namespace ESM
mChargeIntRemainder = 0.0f; mChargeIntRemainder = 0.0f;
mEnchantmentCharge = -1; mEnchantmentCharge = -1;
mGoldValue = 1; mGoldValue = 1;
mDestCell = ESM::RefId::sEmpty; mDestCell.clear();
mLockLevel = 0; mLockLevel = 0;
mKey = ESM::RefId::sEmpty; mKey = ESM::RefId::sEmpty;
mTrap = ESM::RefId::sEmpty; mTrap = ESM::RefId::sEmpty;

View file

@ -89,7 +89,7 @@ namespace ESM
Position mDoorDest; Position mDoorDest;
// Destination cell for doors (optional) // Destination cell for doors (optional)
ESM::RefId mDestCell; std::string mDestCell;
// Lock level for doors and containers // Lock level for doors and containers
int mLockLevel; int mLockLevel;

View file

@ -71,7 +71,7 @@ namespace ESM
switch (esm.retSubName().toInt()) switch (esm.retSubName().toInt())
{ {
case SREC_NAME: case SREC_NAME:
mName = esm.getRefId(); mName = esm.getHString();
break; break;
case fourCC("DATA"): case fourCC("DATA"):
esm.getHTSized<12>(mData); esm.getHTSized<12>(mData);
@ -101,7 +101,7 @@ namespace ESM
} }
else else
{ {
mCellId.mWorldspace = mName; mCellId.mWorldspace = Misc::StringUtils::lowerCase(mName);
mCellId.mIndex.mX = 0; mCellId.mIndex.mX = 0;
mCellId.mIndex.mY = 0; mCellId.mIndex.mY = 0;
} }
@ -173,7 +173,7 @@ namespace ESM
void Cell::save(ESMWriter& esm, bool isDeleted) const void Cell::save(ESMWriter& esm, bool isDeleted) const
{ {
esm.writeHNCString("NAME", mName.getRefIdString()); esm.writeHNCString("NAME", mName);
esm.writeHNT("DATA", mData, 12); esm.writeHNT("DATA", mData, 12);
if (isDeleted) if (isDeleted)
@ -225,7 +225,7 @@ namespace ESM
std::string Cell::getDescription() const std::string Cell::getDescription() const
{ {
const auto& nameString = mName.getRefIdString(); const auto& nameString = mName;
if (mData.mFlags & Interior) if (mData.mFlags & Interior)
return nameString; return nameString;
@ -315,7 +315,7 @@ namespace ESM
void Cell::blank() void Cell::blank()
{ {
mName = ESM::RefId::sEmpty; mName = "";
mRegion = ESM::RefId::sEmpty; mRegion = ESM::RefId::sEmpty;
mWater = 0; mWater = 0;
mWaterInt = false; mWaterInt = false;

View file

@ -101,7 +101,7 @@ namespace ESM
}; };
Cell() Cell()
: mName(ESM::RefId::sEmpty) : mName("")
, mRegion(ESM::RefId()) , mRegion(ESM::RefId())
, mHasAmbi(true) , mHasAmbi(true)
, mWater(0) , mWater(0)
@ -113,7 +113,7 @@ namespace ESM
// Interior cells are indexed by this (it's the 'id'), for exterior // Interior cells are indexed by this (it's the 'id'), for exterior
// cells it is optional. // cells it is optional.
ESM::RefId mName; std::string mName;
// Optional region name for exterior and quasi-exterior cells. // Optional region name for exterior and quasi-exterior cells.
RefId mRegion; RefId mRegion;

View file

@ -18,7 +18,7 @@ namespace ESM
} }
else if (esm.retSubName().toInt() == fourCC("DNAM")) else if (esm.retSubName().toInt() == fourCC("DNAM"))
{ {
const ESM::RefId name = esm.getRefId(); std::string name = esm.getHString();
if (mList.empty()) if (mList.empty())
Log(Debug::Warning) << "Encountered DNAM record without DODT record, skipped."; Log(Debug::Warning) << "Encountered DNAM record without DODT record, skipped.";
else else
@ -32,7 +32,7 @@ namespace ESM
for (DestIter it = mList.begin(); it != mList.end(); ++it) for (DestIter it = mList.begin(); it != mList.end(); ++it)
{ {
esm.writeHNT("DODT", it->mPos, sizeof(it->mPos)); esm.writeHNT("DODT", it->mPos, sizeof(it->mPos));
esm.writeHNOCString("DNAM", it->mCellName.getRefIdString()); esm.writeHNOCString("DNAM", it->mCellName);
} }
} }

View file

@ -20,7 +20,7 @@ namespace ESM
struct Dest struct Dest
{ {
Position mPos; Position mPos;
ESM::RefId mCellName; std::string mCellName;
}; };
std::vector<Dest> mList; std::vector<Dest> mList;

View file

@ -59,7 +59,7 @@ namespace EsmLoader
struct CellRecords struct CellRecords
{ {
Records<ESM::Cell> mValues; Records<ESM::Cell> mValues;
std::map<ESM::RefId, std::size_t> mByName; std::map<std::string, std::size_t> mByName;
std::map<std::pair<int, int>, std::size_t> mByPosition; std::map<std::pair<int, int>, std::size_t> mByPosition;
}; };

View file

@ -94,6 +94,8 @@ namespace Misc::StringUtils
struct CiComp struct CiComp
{ {
using is_transparent = void;
bool operator()(std::string_view left, std::string_view right) const { return ciLess(left, right); } bool operator()(std::string_view left, std::string_view right) const { return ciLess(left, right); }
}; };