int x, int y , ESM::RefId worldspace => ESM::ExteriorCellIndex

also removed the changeToExteriorCell that only took a position as input, didn't work with esm4.
simplify_debugging
florent.teppe 2 years ago
parent 43e247d458
commit 141878f30d

@ -250,10 +250,6 @@ namespace MWBase
///< Move to interior cell.
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
virtual void changeToExteriorCell(const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true)
= 0;
///< Move to exterior cell.
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
virtual void changeToCell(
const ESM::RefId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true)
= 0;

@ -584,7 +584,7 @@ namespace MWGui
{
if (!mInterior)
requestMapRender(&MWBase::Environment::get().getWorldModel()->getExterior(
entry.mCellX, entry.mCellY, ESM::Cell::sDefaultWorldspaceId));
ESM::ExteriorCellIndex(entry.mCellX, entry.mCellY, ESM::Cell::sDefaultWorldspaceId)));
osg::ref_ptr<osg::Texture2D> texture = mLocalMapRender->getMapTexture(entry.mCellX, entry.mCellY);
if (texture)
@ -641,8 +641,9 @@ namespace MWGui
for (MapEntry& entry : mMaps)
{
if (!entry.mMapTexture && !widgetCropped(entry.mMapWidget, mLocalMap))
world->getDoorMarkers(
worldModel->getExterior(entry.mCellX, entry.mCellY, ESM::Cell::sDefaultWorldspaceId), doors);
world->getDoorMarkers(worldModel->getExterior(ESM::ExteriorCellIndex(
entry.mCellX, entry.mCellY, ESM::Cell::sDefaultWorldspaceId)),
doors);
}
if (doors.empty())
return;

@ -131,7 +131,7 @@ namespace MWGui
if (cellname.empty())
{
MWWorld::CellStore& cell = MWBase::Environment::get().getWorldModel()->getExterior(
cellIndex.x(), cellIndex.y(), ESM::Cell::sDefaultWorldspaceId);
ESM::ExteriorCellIndex(cellIndex.x(), cellIndex.y(), ESM::Cell::sDefaultWorldspaceId));
cellname = MWBase::Environment::get().getWorld()->getCellName(&cell);
interior = false;
}

@ -115,7 +115,7 @@ namespace MWLua
= [](std::string_view name) { return GCell{ &MWBase::Environment::get().getWorldModel()->getCell(name) }; };
api["getExteriorCell"] = [](int x, int y) {
return GCell{ &MWBase::Environment::get().getWorldModel()->getExterior(
x, y, ESM::Cell::sDefaultWorldspaceId) };
ESM::ExteriorCellIndex(x, y, ESM::Cell::sDefaultWorldspaceId)) };
};
api["activeActors"] = GObjectList{ worldView->getActorsInScene() };
api["createObject"] = [](std::string_view recordId, sol::optional<int> count) -> GObject {

@ -483,11 +483,11 @@ namespace MWPhysics
mHeightFields.erase(heightfield);
}
const HeightField* PhysicsSystem::getHeightField(int x, int y, ESM::RefId worldspace) const
const HeightField* PhysicsSystem::getHeightField(ESM::ExteriorCellIndex cellIndex) const
{
if (worldspace != ESM::Cell::sDefaultWorldspaceId)
if (cellIndex.mWorldspace != ESM::Cell::sDefaultWorldspaceId)
return nullptr;
const auto heightField = mHeightFields.find(std::make_pair(x, y));
const auto heightField = mHeightFields.find(std::make_pair(cellIndex.mX, cellIndex.mY));
if (heightField == mHeightFields.end())
return nullptr;
return heightField->second.get();

@ -17,6 +17,7 @@
#include <osg/ref_ptr>
#include <components/detournavigator/collisionshapetype.hpp>
#include <components/esm/util.hpp>
#include "../mwworld/ptr.hpp"
@ -189,7 +190,7 @@ namespace MWPhysics
void removeHeightField(int x, int y);
const HeightField* getHeightField(int x, int y, ESM::RefId worldspace) const;
const HeightField* getHeightField(ESM::ExteriorCellIndex cellIndex) const;
bool toggleCollisionMode();

@ -18,11 +18,12 @@ namespace MWRender
mCache = new CacheType;
}
osg::ref_ptr<ESMTerrain::LandObject> LandManager::getLand(int x, int y, ESM::RefId worldspace)
osg::ref_ptr<ESMTerrain::LandObject> LandManager::getLand(ESM::ExteriorCellIndex cellIndex)
{
if (worldspace != ESM::Cell::sDefaultWorldspaceId)
if (cellIndex.mWorldspace != ESM::Cell::sDefaultWorldspaceId)
return osg::ref_ptr<ESMTerrain::LandObject>(nullptr);
int x = cellIndex.mX;
int y = cellIndex.mY;
osg::ref_ptr<osg::Object> obj = mCache->getRefFromObjectCache(std::make_pair(x, y));
if (obj)
return static_cast<ESMTerrain::LandObject*>(obj.get());

@ -3,6 +3,7 @@
#include <osg/Object>
#include <components/esm/util.hpp>
#include <components/esm3terrain/storage.hpp>
#include <components/resource/resourcemanager.hpp>
@ -20,7 +21,7 @@ namespace MWRender
LandManager(int loadFlags);
/// @note Will return nullptr if not found.
osg::ref_ptr<ESMTerrain::LandObject> getLand(int x, int y, ESM::RefId worldspace);
osg::ref_ptr<ESMTerrain::LandObject> getLand(ESM::ExteriorCellIndex cellIndex);
void reportStats(unsigned int frameNumber, osg::Stats* stats) const override;

@ -68,7 +68,7 @@ namespace MWRender
osg::ref_ptr<const ESMTerrain::LandObject> TerrainStorage::getLand(int cellX, int cellY)
{
return mLandManager->getLand(cellX, cellY, ESM::Cell::sDefaultWorldspaceId);
return mLandManager->getLand(ESM::ExteriorCellIndex(cellX, cellY, ESM::Cell::sDefaultWorldspaceId));
}
const ESM::LandTexture* TerrainStorage::getLandTexture(int index, short plugin)

@ -402,8 +402,8 @@ namespace MWScript
if (store->isExterior())
{
const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(x, y);
store
= &worldModel->getExterior(cellIndex.x(), cellIndex.y(), store->getCell()->getWorldSpace());
store = &worldModel->getExterior(
ESM::ExteriorCellIndex(cellIndex.x(), cellIndex.y(), store->getCell()->getWorldSpace()));
}
}
catch (std::exception&)
@ -418,7 +418,8 @@ namespace MWScript
if (!isPlayer)
return;
const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(x, y);
store = &worldModel->getExterior(cellIndex.x(), cellIndex.y(), store->getCell()->getWorldSpace());
store = &worldModel->getExterior(
ESM::ExteriorCellIndex(cellIndex.x(), cellIndex.y(), store->getCell()->getWorldSpace()));
}
if (store)
{
@ -475,7 +476,7 @@ namespace MWScript
if (isPlayer)
{
MWWorld::CellStore* cell = &MWBase::Environment::get().getWorldModel()->getExterior(
cellIndex.x(), cellIndex.y(), ESM::Cell::sDefaultWorldspaceId);
ESM::ExteriorCellIndex(cellIndex.x(), cellIndex.y(), ESM::Cell::sDefaultWorldspaceId));
ptr = world->moveObject(ptr, cell, osg::Vec3(x, y, z));
}
else
@ -569,8 +570,8 @@ namespace MWScript
if (player.getCell()->isExterior())
{
const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(x, y);
store = &MWBase::Environment::get().getWorldModel()->getExterior(
cellIndex.x(), cellIndex.y(), player.getCell()->getCell()->getWorldSpace());
store = &MWBase::Environment::get().getWorldModel()->getExterior(ESM::ExteriorCellIndex(
cellIndex.x(), cellIndex.y(), player.getCell()->getCell()->getWorldSpace()));
}
else
store = player.getCell();

@ -563,8 +563,8 @@ void MWState::StateManager::loadGame(const Character* character, const std::file
{
// Cell no longer exists (i.e. changed game files), choose a default cell
Log(Debug::Warning) << "Warning: Player character's cell no longer exists, changing to the default cell";
MWWorld::CellStore& cell
= MWBase::Environment::get().getWorldModel()->getExterior(0, 0, ESM::Cell::sDefaultWorldspaceId);
MWWorld::CellStore& cell = MWBase::Environment::get().getWorldModel()->getExterior(
ESM::ExteriorCellIndex(0, 0, ESM::Cell::sDefaultWorldspaceId));
float x, y;
MWBase::Environment::get().getWorld()->indexToPosition(0, 0, x, y, false);
ESM::Position pos;

@ -102,7 +102,8 @@ namespace MWWorld
try
{
mTerrain->cacheCell(mTerrainView.get(), mX, mY);
mPreloadedObjects.insert(mLandManager->getLand(mX, mY, ESM::Cell::sDefaultWorldspaceId));
mPreloadedObjects.insert(
mLandManager->getLand(ESM::ExteriorCellIndex(mX, mY, ESM::Cell::sDefaultWorldspaceId)));
}
catch (std::exception&)
{

@ -248,13 +248,13 @@ namespace
return std::abs(cellPosition.first) + std::abs(cellPosition.second);
}
bool isCellInCollection(int x, int y, ESM::RefId worldspace, MWWorld::Scene::CellStoreCollection& collection)
bool isCellInCollection(ESM::ExteriorCellIndex cellIndex, MWWorld::Scene::CellStoreCollection& collection)
{
for (auto* cell : collection)
{
assert(cell->getCell()->isExterior());
if (x == cell->getCell()->getGridX() && y == cell->getCell()->getGridY()
&& cell->getCell()->getWorldSpace() == worldspace)
if (cellIndex.mX == cell->getCell()->getGridX() && cellIndex.mY == cell->getCell()->getGridY()
&& cell->getCell()->getWorldSpace() == cellIndex.mWorldspace)
return true;
}
return false;
@ -306,8 +306,7 @@ namespace MWWorld
{
if (mChangeCellGridRequest.has_value())
{
changeCellGrid(mChangeCellGridRequest->mPosition, mChangeCellGridRequest->mCell.x(),
mChangeCellGridRequest->mCell.y(), mChangeCellGridRequest->exteriorWorldspace,
changeCellGrid(mChangeCellGridRequest->mPosition, mChangeCellGridRequest->mCellIndex,
mChangeCellGridRequest->mChangeEvent);
mChangeCellGridRequest.reset();
}
@ -348,7 +347,8 @@ namespace MWWorld
if (cell->getCell()->isExterior())
{
if (mPhysics->getHeightField(cellX, cellY, cell->getCell()->getWorldSpace()) != nullptr)
if (mPhysics->getHeightField(ESM::ExteriorCellIndex(cellX, cellY, cell->getCell()->getWorldSpace()))
!= nullptr)
mNavigator.removeHeightfield(osg::Vec2i(cellX, cellY), navigatorUpdateGuard);
mPhysics->removeHeightField(cellX, cellY);
@ -394,11 +394,11 @@ namespace MWWorld
const int cellY = cell.getCell()->getGridY();
const MWWorld::Cell& cellVariant = *cell.getCell();
ESM::RefId worldspace = cellVariant.getWorldSpace();
ESM::ExteriorCellIndex cellIndex(cellX, cellY, worldspace);
if (cellVariant.isExterior())
{
osg::ref_ptr<const ESMTerrain::LandObject> land
= mRendering.getLandManager()->getLand(cellX, cellY, worldspace);
osg::ref_ptr<const ESMTerrain::LandObject> land = mRendering.getLandManager()->getLand(cellIndex);
const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : nullptr;
const int verts = ESM::Land::LAND_SIZE;
const int worldsize = ESM::Land::REAL_SIZE;
@ -414,7 +414,7 @@ namespace MWWorld
mPhysics->addHeightField(defaultHeight.data(), cellX, cellY, worldsize, verts,
ESM::Land::DEFAULT_HEIGHT, ESM::Land::DEFAULT_HEIGHT, land.get());
}
if (const auto heightField = mPhysics->getHeightField(cellX, cellY, worldspace))
if (const auto heightField = mPhysics->getHeightField(cellIndex))
{
const osg::Vec2i cellPosition(cellX, cellY);
const btVector3& origin = heightField->getCollisionObject()->getWorldTransform().getOrigin();
@ -469,7 +469,7 @@ namespace MWWorld
if (cellVariant.isExterior())
{
if (const auto heightField = mPhysics->getHeightField(cellX, cellY, worldspace))
if (const auto heightField = mPhysics->getHeightField(cellIndex))
mNavigator.addWater(
osg::Vec2i(cellX, cellY), ESM::Land::REAL_SIZE, waterLevel, navigatorUpdateGuard);
}
@ -537,14 +537,16 @@ namespace MWWorld
void Scene::requestChangeCellGrid(const osg::Vec3f& position, const osg::Vec2i& cell, bool changeEvent)
{
mChangeCellGridRequest
= ChangeCellGridRequest{ position, cell, mCurrentCell->getCell()->getWorldSpace(), changeEvent };
mChangeCellGridRequest = ChangeCellGridRequest{ position,
ESM::ExteriorCellIndex(cell.x(), cell.y(), mCurrentCell->getCell()->getWorldSpace()), changeEvent };
}
void Scene::changeCellGrid(
const osg::Vec3f& pos, int playerCellX, int playerCellY, ESM::RefId exteriorWorldspace, bool changeEvent)
void Scene::changeCellGrid(const osg::Vec3f& pos, ESM::ExteriorCellIndex playerCellIndex, bool changeEvent)
{
auto navigatorUpdateGuard = mNavigator.makeUpdateGuard();
int playerCellX = playerCellIndex.mX;
int playerCellY = playerCellIndex.mY;
ESM::RefId exteriorWorldspace = playerCellIndex.mWorldspace;
for (auto iter = mActiveCells.begin(); iter != mActiveCells.end();)
{
@ -560,11 +562,8 @@ namespace MWWorld
unloadCell(cell, navigatorUpdateGuard.get());
}
mNavigator.setWorldspace(
Misc::StringUtils::lowerCase(mWorld.getWorldModel()
.getExterior(playerCellX, playerCellY, exteriorWorldspace)
.getCell()
->getWorldSpace()
.serializeText()),
Misc::StringUtils::lowerCase(
mWorld.getWorldModel().getExterior(playerCellIndex).getCell()->getWorldSpace().serializeText()),
navigatorUpdateGuard.get());
mNavigator.updateBounds(pos, navigatorUpdateGuard.get());
@ -586,9 +585,9 @@ namespace MWWorld
{
for (int y = playerCellY - range; y <= playerCellY + range; ++y)
{
if (!isCellInCollection(x, y, exteriorWorldspace, collection))
if (!isCellInCollection(playerCellIndex, collection))
{
refsToLoad += mWorld.getWorldModel().getExterior(x, y, exteriorWorldspace).count();
refsToLoad += mWorld.getWorldModel().getExterior(playerCellIndex).count();
cellsPositionsToLoad.emplace_back(x, y);
}
}
@ -620,9 +619,10 @@ namespace MWWorld
for (const auto& [x, y] : cellsPositionsToLoad)
{
if (!isCellInCollection(x, y, exteriorWorldspace, mActiveCells))
ESM::ExteriorCellIndex indexToLoad = { x, y, exteriorWorldspace };
if (!isCellInCollection(indexToLoad, mActiveCells))
{
CellStore& cell = mWorld.getWorldModel().getExterior(x, y, exteriorWorldspace);
CellStore& cell = mWorld.getWorldModel().getExterior(indexToLoad);
loadCell(cell, loadingListener, changeEvent, pos, navigatorUpdateGuard.get());
}
}
@ -631,7 +631,7 @@ namespace MWWorld
navigatorUpdateGuard.reset();
CellStore& current = mWorld.getWorldModel().getExterior(playerCellX, playerCellY, exteriorWorldspace);
CellStore& current = mWorld.getWorldModel().getExterior(playerCellIndex);
MWBase::Environment::get().getWindowManager()->changeCell(&current);
if (changeEvent)
@ -684,8 +684,8 @@ namespace MWWorld
loadingListener->setLabel("#{OMWEngine:TestingExteriorCells} (" + std::to_string(i) + "/"
+ std::to_string(cells.getExtSize()) + ")...");
CellStore& cell
= mWorld.getWorldModel().getExterior(it->mData.mX, it->mData.mY, ESM::Cell::sDefaultWorldspaceId);
CellStore& cell = mWorld.getWorldModel().getExterior(
ESM::ExteriorCellIndex(it->mData.mX, it->mData.mY, ESM::Cell::sDefaultWorldspaceId));
mNavigator.setWorldspace(Misc::StringUtils::lowerCase(cell.getCell()->getWorldSpace().serializeText()),
navigatorUpdateGuard.get());
const osg::Vec3f position
@ -941,8 +941,8 @@ namespace MWWorld
const osg::Vec2i cellIndex(current.getCell()->getGridX(), current.getCell()->getGridY());
changeCellGrid(
position.asVec3(), cellIndex.x(), cellIndex.y(), current.getCell()->getWorldSpace(), changeEvent);
changeCellGrid(position.asVec3(),
ESM::ExteriorCellIndex(cellIndex.x(), cellIndex.y(), current.getCell()->getWorldSpace()), changeEvent);
changePlayerCell(current, position, adjustPlayerPos);
@ -1187,8 +1187,8 @@ namespace MWWorld
+ mPreloadDistance;
if (dist < loadDist)
preloadCell(
mWorld.getWorldModel().getExterior(cellX + dx, cellY + dy, ESM::Cell::sDefaultWorldspaceId));
preloadCell(mWorld.getWorldModel().getExterior(
ESM::ExteriorCellIndex(cellX + dx, cellY + dy, ESM::Cell::sDefaultWorldspaceId)));
}
}
}
@ -1204,8 +1204,8 @@ namespace MWWorld
{
for (int dy = -mHalfGridSize; dy <= mHalfGridSize; ++dy)
{
mPreloader->preload(
mWorld.getWorldModel().getExterior(x + dx, y + dy, cell.getCell()->getWorldSpace()),
mPreloader->preload(mWorld.getWorldModel().getExterior(
ESM::ExteriorCellIndex(x + dx, y + dy, cell.getCell()->getWorldSpace())),
mRendering.getReferenceTime());
if (++numpreloaded >= mPreloader->getMaxCacheSize())
break;
@ -1269,8 +1269,8 @@ namespace MWWorld
};
void Scene::preloadFastTravelDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& /*predictedPos*/,
std::vector<PositionCellGrid>&
exteriorPositions) // ignore predictedPos here since opening dialogue with travel service takes extra time
std::vector<PositionCellGrid>& exteriorPositions) // ignore predictedPos here since opening dialogue with
// travel service takes extra time
{
const MWWorld::ConstPtr player = mWorld.getPlayerPtr();
ListFastTravelDestinationsVisitor listVisitor(mPreloadDistance, player.getRefData().getPosition().asVec3());
@ -1289,8 +1289,8 @@ namespace MWWorld
{
osg::Vec3f pos = dest.mPos.asVec3();
const osg::Vec2i cellIndex = positionToCellIndex(pos.x(), pos.y());
preloadCell(
mWorld.getWorldModel().getExterior(cellIndex.x(), cellIndex.y(), ESM::Cell::sDefaultWorldspaceId),
preloadCell(mWorld.getWorldModel().getExterior(
ESM::ExteriorCellIndex(cellIndex.x(), cellIndex.y(), ESM::Cell::sDefaultWorldspaceId)),
true);
exteriorPositions.emplace_back(pos, gridCenterToBounds(getNewGridCenter(pos)));
}

@ -13,6 +13,7 @@
#include <unordered_map>
#include <vector>
#include <components/esm/util.hpp>
#include <components/misc/constants.hpp>
namespace osg
@ -79,8 +80,7 @@ namespace MWWorld
struct ChangeCellGridRequest
{
osg::Vec3f mPosition;
osg::Vec2i mCell;
ESM::RefId exteriorWorldspace;
ESM::ExteriorCellIndex mCellIndex;
bool mChangeEvent;
};
@ -118,8 +118,7 @@ namespace MWWorld
osg::Vec2i mCurrentGridCenter;
// Load and unload cells as necessary to create a cell grid with "X" and "Y" in the center
void changeCellGrid(const osg::Vec3f& pos, int playerCellX, int playerCellY, ESM::RefId exteriorWorldspace,
bool changeEvent = true);
void changeCellGrid(const osg::Vec3f& pos, ESM::ExteriorCellIndex playerCellIndex, bool changeEvent = true);
void requestChangeCellGrid(const osg::Vec3f& position, const osg::Vec2i& cell, bool changeEvent = true);

@ -1105,9 +1105,9 @@ namespace MWWorld
return foundCell->second;
}
const ESM4::Cell* Store<ESM4::Cell>::searchExterior(int x, int y, ESM::RefId worldSpace) const
const ESM4::Cell* Store<ESM4::Cell>::searchExterior(ESM::ExteriorCellIndex cellIndex) const
{
const auto foundCell = mExteriors.find({ x, y, worldSpace });
const auto foundCell = mExteriors.find(cellIndex);
if (foundCell == mExteriors.end())
return nullptr;
return foundCell->second;

@ -289,7 +289,7 @@ namespace MWWorld
public:
const ESM4::Cell* searchCellName(std::string_view) const;
const ESM4::Cell* searchExterior(int x, int y, ESM::RefId worldSpace) const;
const ESM4::Cell* searchExterior(ESM::ExteriorCellIndex cellIndex) const;
ESM4::Cell* insert(const ESM4::Cell& item, bool overrideOnly = false);
ESM4::Cell* insertStatic(const ESM4::Cell& item);
void clearDynamic() override;

@ -353,9 +353,10 @@ namespace MWWorld
if (bypass && !mStartCell.empty())
{
ESM::Position pos;
if (!findExteriorPosition(mStartCell, pos).empty())
ESM::RefId cellId = findExteriorPosition(mStartCell, pos);
if (!cellId.empty())
{
changeToExteriorCell(pos, true);
changeToCell(cellId, pos, true);
adjustPosition(getPlayerPtr(), false);
}
else
@ -967,25 +968,6 @@ namespace MWWorld
mRendering->getCamera()->instantTransition();
}
void World::changeToExteriorCell(const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
{
mPhysics->clearQueuedMovement();
mDiscardMovements = true;
if (changeEvent && mCurrentWorldSpace != ESM::Cell::sDefaultWorldspace)
{
// changed worldspace
mProjectileManager->clear();
mRendering->notifyWorldSpaceChanged();
}
removeContainerScripts(getPlayerPtr());
osg::Vec2i exteriorCellPos = positionToCellIndex(position.pos[0], position.pos[1]);
ESM::RefId cellId = ESM::RefId::esm3ExteriorCell(exteriorCellPos.x(), exteriorCellPos.y());
mWorldScene->changeToExteriorCell(cellId, position, adjustPlayerPos, changeEvent);
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
mRendering->getCamera()->instantTransition();
}
void World::changeToCell(
const ESM::RefId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
{
@ -1268,8 +1250,9 @@ namespace MWWorld
CellStore* cell = ptr.getCell();
ESM::RefId worldspaceId
= cell->isExterior() ? cell->getCell()->getWorldSpace() : ESM::Cell::sDefaultWorldspaceId;
CellStore* newCell
= cell->isExterior() ? &mWorldModel.getExterior(index.x(), index.y(), worldspaceId) : nullptr;
CellStore* newCell = cell->isExterior()
? &mWorldModel.getExterior(ESM::ExteriorCellIndex(index.x(), index.y(), worldspaceId))
: nullptr;
bool isCellActive = getPlayerPtr().isInCell() && getPlayerPtr().getCell()->isExterior()
&& (newCell && mWorldScene->isCellActive(*newCell));
@ -2072,7 +2055,8 @@ namespace MWWorld
if (cell->isExterior())
{
const osg::Vec2i index = positionToCellIndex(pos.pos[0], pos.pos[1]);
cell = &mWorldModel.getExterior(index.x(), index.y(), cell->getCell()->getWorldSpace());
cell = &mWorldModel.getExterior(
ESM::ExteriorCellIndex(index.x(), index.y(), cell->getCell()->getWorldSpace()));
}
MWWorld::Ptr dropped = object.getClass().copyToCell(object, *cell, pos, count);
@ -2756,7 +2740,8 @@ namespace MWWorld
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.");
else if (xResult.ec == std::errc{} && yResult.ec == std::errc{})
ext = mWorldModel.getExterior(x, y, ESM::Cell::sDefaultWorldspaceId).getCell();
ext = mWorldModel.getExterior(ESM::ExteriorCellIndex(x, y, ESM::Cell::sDefaultWorldspaceId))
.getCell();
// ignore std::errc::invalid_argument, as this means that name probably refers to a interior cell
// instead of comma separated coordinates
}

@ -345,11 +345,6 @@ namespace MWWorld
///< Move to interior cell.
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
void changeToExteriorCell(
const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true) override;
///< Move to exterior cell.
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
void changeToCell(const ESM::RefId& cellId, const ESM::Position& position, bool adjustPlayerPos,
bool changeEvent = true) override;
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes

@ -161,26 +161,25 @@ MWWorld::WorldModel::WorldModel(const MWWorld::ESMStore& store, ESM::ReadersCach
{
}
MWWorld::CellStore& MWWorld::WorldModel::getExterior(int x, int y, ESM::RefId exteriorWorldspace)
MWWorld::CellStore& MWWorld::WorldModel::getExterior(ESM::ExteriorCellIndex cellIndex)
{
std::map<ESM::ExteriorCellIndex, CellStore*>::iterator result;
ESM::ExteriorCellIndex extIndex = { x, y, exteriorWorldspace };
result = mExteriors.find({ x, y, exteriorWorldspace });
result = mExteriors.find(cellIndex);
if (result == mExteriors.end())
{
if (exteriorWorldspace == ESM::Cell::sDefaultWorldspaceId)
if (cellIndex.mWorldspace == ESM::Cell::sDefaultWorldspaceId)
{
const ESM::Cell* cell = mStore.get<ESM::Cell>().search(x, y);
const ESM::Cell* cell = mStore.get<ESM::Cell>().search(cellIndex.mX, cellIndex.mY);
if (!cell)
{
// Cell isn't predefined. Make one on the fly.
ESM::Cell record;
record.mData.mFlags = ESM::Cell::HasWater;
record.mData.mX = x;
record.mData.mY = y;
record.mData.mX = cellIndex.mX;
record.mData.mY = cellIndex.mY;
record.mWater = 0;
record.mMapColor = 0;
record.updateId();
@ -190,31 +189,31 @@ MWWorld::CellStore& MWWorld::WorldModel::getExterior(int x, int y, ESM::RefId ex
CellStore* cellStore
= &mCells.emplace(cell->mId, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first->second;
result = mExteriors.emplace(extIndex, cellStore).first;
result = mExteriors.emplace(cellIndex, cellStore).first;
}
else
{
const Store<ESM4::Cell>& cell4Store = mStore.get<ESM4::Cell>();
bool exteriorExists = mStore.get<ESM4::World>().search(exteriorWorldspace);
const ESM4::Cell* cell = cell4Store.searchExterior(x, y, exteriorWorldspace);
bool exteriorExists = mStore.get<ESM4::World>().search(cellIndex.mWorldspace);
const ESM4::Cell* cell = cell4Store.searchExterior(cellIndex);
if (exteriorExists)
{
if (!cell)
{
ESM4::Cell record;
record.mParent = exteriorWorldspace;
record.mX = x;
record.mY = y;
record.mParent = cellIndex.mWorldspace;
record.mX = cellIndex.mX;
record.mY = cellIndex.mY;
record.mCellFlags = !ESM4::CELL_Interior;
cell = MWBase::Environment::get().getESMStore()->insert(record);
}
CellStore* cellStore
= &mCells.emplace(cell->mId, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first->second;
result = mExteriors.emplace(extIndex, cellStore).first;
result = mExteriors.emplace(cellIndex, cellStore).first;
}
else
{
throw std::runtime_error("exterior not found: '" + exteriorWorldspace.toDebugString() + "'");
throw std::runtime_error("exterior not found: '" + cellIndex.mWorldspace.toDebugString() + "'");
}
}
}
@ -263,7 +262,8 @@ MWWorld::CellStore& MWWorld::WorldModel::getCell(const ESM::RefId& id)
return result->second;
if (const auto* exteriorId = id.getIf<ESM::ESM3ExteriorCellRefId>())
return getExterior(exteriorId->getX(), exteriorId->getY(), ESM::Cell::sDefaultWorldspaceId);
return getExterior(
ESM::ExteriorCellIndex(exteriorId->getX(), exteriorId->getY(), ESM::Cell::sDefaultWorldspaceId));
const ESM4::Cell* cell4 = mStore.get<ESM4::Cell>().search(id);
CellStore* newCellStore = nullptr;
@ -325,7 +325,7 @@ MWWorld::CellStore& MWWorld::WorldModel::getCell(std::string_view name)
if (!cell)
throw std::runtime_error(std::string("Can't find cell with name ") + std::string(name));
return getExterior(cell->getGridX(), cell->getGridY(), ESM::Cell::sDefaultWorldspaceId);
return getExterior(ESM::ExteriorCellIndex(cell->getGridX(), cell->getGridY(), ESM::Cell::sDefaultWorldspaceId));
}
MWWorld::CellStore& MWWorld::WorldModel::getCellByPosition(
@ -336,7 +336,7 @@ MWWorld::CellStore& MWWorld::WorldModel::getCellByPosition(
const osg::Vec2i cellIndex = positionToCellIndex(pos.x(), pos.y());
ESM::RefId exteriorWorldspace
= cellInSameWorldSpace ? cellInSameWorldSpace->getCell()->getWorldSpace() : ESM::Cell::sDefaultWorldspaceId;
return getExterior(cellIndex.x(), cellIndex.y(), exteriorWorldspace);
return getExterior(ESM::ExteriorCellIndex(cellIndex.x(), cellIndex.y(), exteriorWorldspace));
}
MWWorld::Ptr MWWorld::WorldModel::getPtr(const ESM::RefId& name, CellStore& cell)

@ -65,7 +65,7 @@ namespace MWWorld
void clear();
CellStore& getExterior(int x, int y, ESM::RefId exteriorWorldSpace);
CellStore& getExterior(ESM::ExteriorCellIndex cellIndex);
CellStore& getInterior(std::string_view name);
CellStore& getCell(std::string_view name); // interior or named exterior
CellStore& getCell(const ESM::RefId& Id);

@ -49,6 +49,13 @@ namespace ESM
int mX, mY;
ESM::RefId mWorldspace;
ExteriorCellIndex(int x, int y, ESM::RefId worldspace)
: mX(x)
, mY(y)
, mWorldspace(worldspace)
{
}
bool operator==(const ExteriorCellIndex& other) const
{
return mX == other.mX && mY == other.mY && mWorldspace == other.mWorldspace;

Loading…
Cancel
Save