Gets rid of most ESM::CellId

depth-refraction
florent.teppe 2 years ago
parent 6895a452ef
commit c39dd576f8

@ -220,7 +220,7 @@ namespace EsmTool
{ {
void CellState::load(ESM::ESMReader& reader, bool& deleted) void CellState::load(ESM::ESMReader& reader, bool& deleted)
{ {
mCellState.mId.load(reader); mCellState.mId = reader.getCellId();
mCellState.load(reader); mCellState.load(reader);
if (mCellState.mHasFogOfWar) if (mCellState.mHasFogOfWar)
mFogState.load(reader); mFogState.load(reader);
@ -1358,11 +1358,8 @@ namespace EsmTool
void Record<CellState>::print() void Record<CellState>::print()
{ {
std::cout << " Id:" << std::endl; std::cout << " Id:" << std::endl;
std::cout << " Worldspace: " << mData.mCellState.mId.mWorldspace << std::endl; std::cout << " CellId: " << mData.mCellState.mId << std::endl;
std::cout << " Index:" << std::endl; std::cout << " Index:" << std::endl;
std::cout << " X: " << mData.mCellState.mId.mIndex.mX << std::endl;
std::cout << " Y: " << mData.mCellState.mId.mIndex.mY << std::endl;
std::cout << " Paged: " << mData.mCellState.mId.mPaged << std::endl;
std::cout << " WaterLevel: " << mData.mCellState.mWaterLevel << std::endl; std::cout << " WaterLevel: " << mData.mCellState.mWaterLevel << std::endl;
std::cout << " HasFogOfWar: " << mData.mCellState.mHasFogOfWar << std::endl; std::cout << " HasFogOfWar: " << mData.mCellState.mHasFogOfWar << std::endl;
std::cout << " LastRespawn:" << std::endl; std::cout << " LastRespawn:" << std::endl;
@ -1420,8 +1417,7 @@ namespace EsmTool
std::string Record<CellState>::getId() const std::string Record<CellState>::getId() const
{ {
std::ostringstream stream; std::ostringstream stream;
stream << mData.mCellState.mId.mWorldspace << " " << mData.mCellState.mId.mIndex.mX << " " stream << mData.mCellState.mId;
<< mData.mCellState.mId.mIndex.mY << " " << mData.mCellState.mId.mPaged;
return stream.str(); return stream.str();
} }

@ -204,7 +204,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 (Misc::StringUtils::ciEqual(cell.mName, mContext->mPlayerCellName)) if (Misc::StringUtils::ciEqual(cell.mName, mContext->mPlayerCellName))
{ {
mContext->mPlayer.mCellId = cell.getCellId(); mContext->mPlayer.mCellId = cell.mId;
} }
Cell newcell; Cell newcell;
@ -301,8 +301,7 @@ namespace ESSImport
marker.mWorldX = notepos[0]; marker.mWorldX = notepos[0];
marker.mWorldY = notepos[1]; marker.mWorldY = notepos[1];
marker.mNote = note; marker.mNote = note;
marker.mCellId = cell.getCellId(); marker.mCell = cell.mId;
marker.mCell = cell.getCellId().getCellRefId();
mMarkers.push_back(marker); mMarkers.push_back(marker);
} }
@ -322,8 +321,9 @@ namespace ESSImport
csta.mHasFogOfWar = 0; csta.mHasFogOfWar = 0;
csta.mLastRespawn.mDay = 0; csta.mLastRespawn.mDay = 0;
csta.mLastRespawn.mHour = 0; csta.mLastRespawn.mHour = 0;
csta.mId = esmcell.getCellId(); csta.mId = esmcell.mId;
csta.mId.save(esm); csta.mIsInterior = !esmcell.isExterior();
esm.writeCellId(csta.mId);
// TODO csta.mLastRespawn; // TODO csta.mLastRespawn;
// shouldn't be needed if we respawn on global schedule like in original MW // shouldn't be needed if we respawn on global schedule like in original MW
csta.mWaterLevel = esmcell.mWater; csta.mWaterLevel = esmcell.mWater;

@ -61,7 +61,6 @@ namespace ESSImport
const PCDT::PNAM::MarkLocation& mark = pcdt.mPNAM.mMarkLocation; const PCDT::PNAM::MarkLocation& mark = pcdt.mPNAM.mMarkLocation;
ESM::CellId cell; ESM::CellId cell;
cell.mWorldspace = ESM::CellId::sDefaultWorldspace;
cell.mPaged = true; cell.mPaged = true;
cell.mIndex.mX = mark.mCellX; cell.mIndex.mX = mark.mCellX;
@ -74,7 +73,7 @@ namespace ESSImport
cell.mPaged = false; cell.mPaged = false;
} }
out.mMarkedCell = cell; out.mMarkedCell = cell.getCellRefId();
out.mMarkedPosition.pos[0] = mark.mX; out.mMarkedPosition.pos[0] = mark.mX;
out.mMarkedPosition.pos[1] = mark.mY; out.mMarkedPosition.pos[1] = mark.mY;
out.mMarkedPosition.pos[2] = mark.mZ; out.mMarkedPosition.pos[2] = mark.mZ;

@ -409,16 +409,18 @@ namespace ESSImport
} }
writer.startRecord(ESM::REC_PLAY); writer.startRecord(ESM::REC_PLAY);
if (context.mPlayer.mCellId.mPaged) ESM::CellId cellId = ESM::CellId::extractFromRefId(context.mPlayer.mCellId);
if (cellId.mPaged)
{ {
// exterior cell -> determine cell coordinates based on position // exterior cell -> determine cell coordinates based on position
int cellX int cellX
= static_cast<int>(std::floor(context.mPlayer.mObject.mPosition.pos[0] / Constants::CellSizeInUnits)); = static_cast<int>(std::floor(context.mPlayer.mObject.mPosition.pos[0] / Constants::CellSizeInUnits));
int cellY int cellY
= static_cast<int>(std::floor(context.mPlayer.mObject.mPosition.pos[1] / Constants::CellSizeInUnits)); = static_cast<int>(std::floor(context.mPlayer.mObject.mPosition.pos[1] / Constants::CellSizeInUnits));
context.mPlayer.mCellId.mIndex.mX = cellX; cellId.mIndex.mX = cellX;
context.mPlayer.mCellId.mIndex.mY = cellY; cellId.mIndex.mY = cellY;
} }
context.mPlayer.mCellId = cellId.getCellRefId();
context.mPlayer.save(writer); context.mPlayer.save(writer);
writer.endRecord(ESM::REC_PLAY); writer.endRecord(ESM::REC_PLAY);

@ -62,7 +62,7 @@ namespace ESSImport
ESM::CellId playerCellId; ESM::CellId playerCellId;
playerCellId.mPaged = true; playerCellId.mPaged = true;
playerCellId.mIndex.mX = playerCellId.mIndex.mY = 0; playerCellId.mIndex.mX = playerCellId.mIndex.mY = 0;
mPlayer.mCellId = playerCellId; mPlayer.mCellId = playerCellId.getCellRefId();
mPlayer.mLastKnownExteriorPosition[0] = mPlayer.mLastKnownExteriorPosition[1] mPlayer.mLastKnownExteriorPosition[0] = mPlayer.mLastKnownExteriorPosition[1]
= mPlayer.mLastKnownExteriorPosition[2] = 0.0f; = mPlayer.mLastKnownExteriorPosition[2] = 0.0f;
mPlayer.mHasMark = 0; mPlayer.mHasMark = 0;

@ -263,7 +263,8 @@ 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); const auto cellNameLowerCase
= Misc::StringUtils::lowerCase(cell.isExterior() ? ESM::CellId::sDefaultWorldspace : cell.mName);
WorldspaceNavMeshInput& navMeshInput = [&]() -> WorldspaceNavMeshInput& { WorldspaceNavMeshInput& navMeshInput = [&]() -> WorldspaceNavMeshInput& {
auto it = navMeshInputs.find(cellNameLowerCase); auto it = navMeshInputs.find(cellNameLowerCase);
if (it == navMeshInputs.end()) if (it == navMeshInputs.end())

@ -40,7 +40,6 @@ namespace ESM
{ {
class ESMReader; class ESMReader;
class ESMWriter; class ESMWriter;
struct CellId;
} }
namespace MWMechanics namespace MWMechanics

@ -256,10 +256,6 @@ namespace MWBase
= 0; = 0;
///< Move to exterior cell. ///< Move to exterior 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
virtual void changeToCell(
const ESM::CellId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true)
= 0;
virtual void changeToCell( virtual void changeToCell(
const ESM::RefId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true) const ESM::RefId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true)
= 0; = 0;

@ -897,7 +897,6 @@ namespace MWGui
clickedId.mIndex.mY = y; clickedId.mIndex.mY = y;
} }
mEditingMarker.mCell = clickedId.getCellRefId(); mEditingMarker.mCell = clickedId.getCellRefId();
mEditingMarker.mCellId = clickedId;
mEditNoteDialog.setVisible(true); mEditNoteDialog.setVisible(true);
mEditNoteDialog.showDeleteButton(false); mEditNoteDialog.showDeleteButton(false);

@ -5,12 +5,10 @@
#include <components/esm/esmbridge.hpp> #include <components/esm/esmbridge.hpp>
#include <components/esm/refid.hpp> #include <components/esm/refid.hpp>
#include <components/esm3/cellid.hpp>
namespace ESM namespace ESM
{ {
struct Cell; struct Cell;
struct CellId;
} }
namespace ESM4 namespace ESM4

@ -90,11 +90,11 @@ namespace MWWorld
else else
{ {
const osg::Vec2i index = positionToCellIndex(ref.mDoorDest.pos[0], ref.mDoorDest.pos[1]); const osg::Vec2i index = positionToCellIndex(ref.mDoorDest.pos[0], ref.mDoorDest.pos[1]);
ESM::CellId CellId; ESM::CellId cellId;
CellId.mPaged = true; cellId.mPaged = true;
CellId.mIndex.mX = index.x(); cellId.mIndex.mX = index.x();
CellId.mIndex.mY = index.y(); cellId.mIndex.mY = index.y();
return CellId.getCellRefId(); return cellId.getCellRefId();
} }
}; };

@ -988,11 +988,11 @@ namespace MWWorld
void CellStore::saveState(ESM::CellState& state) const void CellStore::saveState(ESM::CellState& state) const
{ {
state.mId = ESM::CellId::extractFromRefId(mCellVariant.getId()); state.mId = mCellVariant.getId();
if (!mCellVariant.isExterior() && mCellVariant.hasWater()) if (!mCellVariant.isExterior() && mCellVariant.hasWater())
state.mWaterLevel = mWaterLevel; state.mWaterLevel = mWaterLevel;
state.mIsInterior = !mCellVariant.isExterior();
state.mHasFogOfWar = (mFogState.get() ? 1 : 0); state.mHasFogOfWar = (mFogState.get() ? 1 : 0);
state.mLastRespawn = mLastRespawn.toEsm(); state.mLastRespawn = mLastRespawn.toEsm();
} }
@ -1019,10 +1019,10 @@ namespace MWWorld
for (const auto& [base, store] : mMovedToAnotherCell) for (const auto& [base, store] : mMovedToAnotherCell)
{ {
ESM::RefNum refNum = base->mRef.getRefNum(); ESM::RefNum refNum = base->mRef.getRefNum();
ESM::CellId movedTo = ESM::CellId::extractFromRefId(store->getCell()->getId()); ESM::RefId movedTo = store->getCell()->getId();
refNum.save(writer, true, "MVRF"); refNum.save(writer, true, "MVRF");
movedTo.save(writer); writer.writeCellId(movedTo);
} }
} }
@ -1078,10 +1078,8 @@ namespace MWWorld
{ {
reader.cacheSubName(); reader.cacheSubName();
ESM::RefNum refnum; ESM::RefNum refnum;
ESM::CellId movedTo;
refnum.load(reader, true, "MVRF"); refnum.load(reader, true, "MVRF");
movedTo.load(reader); ESM::RefId movedToId = reader.getCellId();
ESM::RefId movedToId = movedTo.getCellRefId();
if (refnum.hasContentFile()) if (refnum.hasContentFile())
{ {
auto iter = contentFileMap.find(refnum.mContentFile); auto iter = contentFileMap.find(refnum.mContentFile);
@ -1103,7 +1101,7 @@ namespace MWWorld
if (otherCell == nullptr) if (otherCell == nullptr)
{ {
Log(Debug::Warning) << "Warning: Dropping moved ref tag for " << movedRef.getCellRef().getRefId() Log(Debug::Warning) << "Warning: Dropping moved ref tag for " << movedRef.getCellRef().getRefId()
<< " (target cell " << movedTo.mWorldspace << " (target cell " << movedToId
<< " no longer exists). Reference moved back to its original location."; << " no longer exists). Reference moved back to its original location.";
// Note by dropping tag the object will automatically re-appear in its original cell, though // Note by dropping tag the object will automatically re-appear in its original cell, though
// potentially at inapproriate coordinates. Restore original coordinates: // potentially at inapproriate coordinates. Restore original coordinates:

@ -27,7 +27,6 @@ namespace ESM
class ReadersCache; class ReadersCache;
struct Cell; struct Cell;
struct CellState; struct CellState;
struct CellId;
struct RefNum; struct RefNum;
struct Activator; struct Activator;
struct Potion; struct Potion;

@ -51,7 +51,7 @@ namespace MWWorld
{ {
if (!cell.isExterior()) if (!cell.isExterior())
continue; continue;
auto cellIndex = std::make_pair(cell.getCellId().mIndex.mX, cell.getCellId().mIndex.mY); auto cellIndex = std::make_pair(cell.getGridX(), cell.getGridY());
mCellContexts[cellIndex] = std::move(cell.mContextList); mCellContexts[cellIndex] = std::move(cell.mContextList);
} }
} }

@ -283,7 +283,7 @@ namespace MWWorld
ESM::Player player; ESM::Player player;
mPlayer.save(player.mObject); mPlayer.save(player.mObject);
player.mCellId = ESM::CellId::extractFromRefId(mCellStore->getCell()->getId()); player.mCellId = mCellStore->getCell()->getId();
player.mCurrentCrimeId = mCurrentCrimeId; player.mCurrentCrimeId = mCurrentCrimeId;
player.mPaidCrimeId = mPaidCrimeId; player.mPaidCrimeId = mPaidCrimeId;
@ -298,7 +298,7 @@ namespace MWWorld
{ {
player.mHasMark = true; player.mHasMark = true;
player.mMarkedPosition = mMarkedPosition; player.mMarkedPosition = mMarkedPosition;
player.mMarkedCell = ESM::CellId::extractFromRefId(mMarkedCell->getCell()->getId()); player.mMarkedCell = mMarkedCell->getCell()->getId();
} }
else else
player.mHasMark = false; player.mHasMark = false;
@ -367,11 +367,11 @@ namespace MWWorld
try try
{ {
mCellStore = MWBase::Environment::get().getWorldModel()->getCellFromCellId(player.mCellId); mCellStore = MWBase::Environment::get().getWorldModel()->getCell(player.mCellId);
} }
catch (...) catch (...)
{ {
Log(Debug::Warning) << "Warning: Player cell '" << player.mCellId.mWorldspace << "' no longer exists"; Log(Debug::Warning) << "Warning: Player cell '" << player.mCellId << "' no longer exists";
// Cell no longer exists. The loader will have to choose a default cell. // Cell no longer exists. The loader will have to choose a default cell.
mCellStore = nullptr; mCellStore = nullptr;
} }
@ -392,19 +392,20 @@ namespace MWWorld
mLastKnownExteriorPosition.y() = player.mLastKnownExteriorPosition[1]; mLastKnownExteriorPosition.y() = player.mLastKnownExteriorPosition[1];
mLastKnownExteriorPosition.z() = player.mLastKnownExteriorPosition[2]; mLastKnownExteriorPosition.z() = player.mLastKnownExteriorPosition[2];
if (player.mHasMark && !player.mMarkedCell.mPaged) bool exterior = ESM::CellId::extractFromRefId(player.mMarkedCell).mPaged;
if (player.mHasMark && !exterior)
{ {
// interior cell -> need to check if it exists (exterior cell will be // interior cell -> need to check if it exists (exterior cell will be
// generated on the fly) // generated on the fly)
if (!world.getStore().get<ESM::Cell>().search(player.mMarkedCell.mWorldspace)) if (!world.getStore().get<ESM::Cell>().search(player.mMarkedCell))
player.mHasMark = false; // drop mark silently player.mHasMark = false; // drop mark silently
} }
if (player.mHasMark) if (player.mHasMark)
{ {
mMarkedPosition = player.mMarkedPosition; mMarkedPosition = player.mMarkedPosition;
mMarkedCell = MWBase::Environment::get().getWorldModel()->getCellFromCellId(player.mMarkedCell); mMarkedCell = MWBase::Environment::get().getWorldModel()->getCell(player.mMarkedCell);
} }
else else
{ {

@ -575,9 +575,6 @@ namespace MWWorld
newCell.mAmbi.mSunlight = 0; newCell.mAmbi.mSunlight = 0;
newCell.mAmbi.mFog = 0; newCell.mAmbi.mFog = 0;
newCell.mAmbi.mFogDensity = 0; newCell.mAmbi.mFogDensity = 0;
newCell.mCellId.mPaged = true;
newCell.mCellId.mIndex.mX = x;
newCell.mCellId.mIndex.mY = y;
newCell.updateId(); newCell.updateId();
ESM::Cell* newCellInserted = &mCells.insert(std::make_pair(newCell.mId, newCell)).first->second; ESM::Cell* newCellInserted = &mCells.insert(std::make_pair(newCell.mId, newCell)).first->second;

@ -380,10 +380,10 @@ namespace MWWorld
pos.rot[2] = 0; pos.rot[2] = 0;
osg::Vec2i exteriorCellPos = positionToCellIndex(pos.pos[0], pos.pos[1]); osg::Vec2i exteriorCellPos = positionToCellIndex(pos.pos[0], pos.pos[1]);
ESM::CellId CellId; ESM::CellId cellId;
CellId.mPaged = true; cellId.mPaged = true;
CellId.mIndex = { exteriorCellPos.x(), exteriorCellPos.y() }; cellId.mIndex = { exteriorCellPos.x(), exteriorCellPos.y() };
mWorldScene->changeToExteriorCell(CellId.getCellRefId(), pos, true); mWorldScene->changeToExteriorCell(cellId.getCellRefId(), pos, true);
} }
} }
@ -987,28 +987,14 @@ namespace MWWorld
} }
removeContainerScripts(getPlayerPtr()); removeContainerScripts(getPlayerPtr());
osg::Vec2i exteriorCellPos = positionToCellIndex(position.pos[0], position.pos[1]); osg::Vec2i exteriorCellPos = positionToCellIndex(position.pos[0], position.pos[1]);
ESM::CellId CellId; ESM::CellId cellId;
CellId.mPaged = true; cellId.mPaged = true;
CellId.mIndex = { exteriorCellPos.x(), exteriorCellPos.y() }; cellId.mIndex = { exteriorCellPos.x(), exteriorCellPos.y() };
mWorldScene->changeToExteriorCell(CellId.getCellRefId(), position, adjustPlayerPos, changeEvent); mWorldScene->changeToExteriorCell(cellId.getCellRefId(), position, adjustPlayerPos, changeEvent);
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell()); addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
mRendering->getCamera()->instantTransition(); mRendering->getCamera()->instantTransition();
} }
void World::changeToCell(
const ESM::CellId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
{
if (!changeEvent)
mCurrentWorldSpace = cellId.mWorldspace;
if (cellId.mPaged)
changeToExteriorCell(position, adjustPlayerPos, changeEvent);
else
changeToInteriorCell(cellId.mWorldspace, position, adjustPlayerPos, changeEvent);
mCurrentDate->setup(mGlobalVariables);
}
void World::changeToCell( void World::changeToCell(
const ESM::RefId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent) const ESM::RefId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
{ {

@ -349,9 +349,6 @@ namespace MWWorld
///< Move to exterior cell. ///< Move to exterior 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
void changeToCell(const ESM::CellId& cellId, const ESM::Position& position, bool adjustPlayerPos,
bool changeEvent = true) override;
void changeToCell(const ESM::RefId& cellId, const ESM::Position& position, bool adjustPlayerPos, void changeToCell(const ESM::RefId& cellId, const ESM::Position& position, bool adjustPlayerPos,
bool changeEvent = true) override; bool changeEvent = true) override;
///< @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

@ -143,7 +143,8 @@ void MWWorld::WorldModel::writeCell(ESM::ESMWriter& writer, CellStore& cell) con
cell.saveState(cellState); cell.saveState(cellState);
writer.startRecord(ESM::REC_CSTA); writer.startRecord(ESM::REC_CSTA);
cellState.mId.save(writer);
writer.writeCellId(cellState.mId);
cellState.save(writer); cellState.save(writer);
cell.writeFog(writer); cell.writeFog(writer);
cell.writeReferences(writer); cell.writeReferences(writer);
@ -170,11 +171,6 @@ MWWorld::CellStore* MWWorld::WorldModel::getExterior(int x, int y)
{ {
// Cell isn't predefined. Make one on the fly. // Cell isn't predefined. Make one on the fly.
ESM::Cell record; ESM::Cell record;
record.mCellId.mWorldspace = ESM::CellId::sDefaultWorldspace;
record.mCellId.mPaged = true;
record.mCellId.mIndex.mX = x;
record.mCellId.mIndex.mY = y;
record.mData.mFlags = ESM::Cell::HasWater; record.mData.mFlags = ESM::Cell::HasWater;
record.mData.mX = x; record.mData.mX = x;
record.mData.mY = y; record.mData.mY = y;
@ -227,14 +223,6 @@ MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name)
return result->second; return result->second;
} }
MWWorld::CellStore* MWWorld::WorldModel::getCellFromCellId(const ESM::CellId& id)
{
if (id.mPaged)
return getExterior(id.mIndex.mX, id.mIndex.mY);
return getInterior(id.mWorldspace);
}
MWWorld::CellStore* MWWorld::WorldModel::getCell(const ESM::RefId& id) MWWorld::CellStore* MWWorld::WorldModel::getCell(const ESM::RefId& id)
{ {
auto result = mCells.find(id); auto result = mCells.find(id);
@ -489,19 +477,18 @@ bool MWWorld::WorldModel::readRecord(ESM::ESMReader& reader, uint32_t type, cons
if (type == ESM::REC_CSTA) if (type == ESM::REC_CSTA)
{ {
ESM::CellState state; ESM::CellState state;
state.mId.load(reader); state.mId = reader.getCellId();
CellStore* cellStore = nullptr; CellStore* cellStore = nullptr;
try try
{ {
cellStore = getCell(state.mId.getCellRefId()); cellStore = getCell(state.mId);
} }
catch (...) catch (...)
{ {
// silently drop cells that don't exist anymore // silently drop cells that don't exist anymore
Log(Debug::Warning) << "Warning: Dropping state for cell " << state.mId.mWorldspace Log(Debug::Warning) << "Warning: Dropping state for cell " << state.mId << " (cell no longer exists)";
<< " (cell no longer exists)";
reader.skipRecord(); reader.skipRecord();
return true; return true;
} }

@ -17,7 +17,6 @@ namespace ESM
class ESMReader; class ESMReader;
class ESMWriter; class ESMWriter;
class ReadersCache; class ReadersCache;
struct CellId;
struct Cell; struct Cell;
struct RefNum; struct RefNum;
} }
@ -71,7 +70,6 @@ namespace MWWorld
CellStore* getInterior(std::string_view name); CellStore* getInterior(std::string_view name);
CellStore* getCell(std::string_view name); // interior or named exterior CellStore* getCell(std::string_view name); // interior or named exterior
CellStore* getCell(const ESM::RefId& Id); CellStore* getCell(const ESM::RefId& Id);
CellStore* getCellFromCellId(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.

@ -15,7 +15,6 @@ namespace ESM4
namespace ESM namespace ESM
{ {
struct Cell; struct Cell;
struct CellId;
class RefId; class RefId;
class CellVariant; class CellVariant;

@ -21,7 +21,7 @@ namespace ESM
void CellState::save(ESMWriter& esm) const void CellState::save(ESMWriter& esm) const
{ {
if (!mId.mPaged) if (mIsInterior)
esm.writeHNT("WLVL", mWaterLevel); esm.writeHNT("WLVL", mWaterLevel);
esm.writeHNT("HFOW", mHasFogOfWar); esm.writeHNT("HFOW", mHasFogOfWar);

@ -15,8 +15,8 @@ namespace ESM
/// \note Does not include references /// \note Does not include references
struct CellState struct CellState
{ {
CellId mId; RefId mId;
bool mIsInterior;
float mWaterLevel; float mWaterLevel;
int mHasFogOfWar; // Do we have fog of war state (0 or 1)? (see fogstate.hpp) int mHasFogOfWar; // Do we have fog of war state (0 or 1)? (see fogstate.hpp)

@ -10,7 +10,7 @@ namespace ESM
{ {
esm.writeHNT("POSX", mWorldX); esm.writeHNT("POSX", mWorldX);
esm.writeHNT("POSY", mWorldY); esm.writeHNT("POSY", mWorldY);
mCellId.save(esm); esm.writeCellId(mCell);
if (!mNote.empty()) if (!mNote.empty())
esm.writeHNString("NOTE", mNote); esm.writeHNString("NOTE", mNote);
} }
@ -19,8 +19,7 @@ namespace ESM
{ {
esm.getHNT(mWorldX, "POSX"); esm.getHNT(mWorldX, "POSX");
esm.getHNT(mWorldY, "POSY"); esm.getHNT(mWorldY, "POSY");
mCellId.load(esm); mCell = esm.getCellId();
mCell = mCellId.getCellRefId();
mNote = esm.getHNOString("NOTE"); mNote = esm.getHNOString("NOTE");
} }

@ -13,7 +13,6 @@ namespace ESM
float mWorldY; float mWorldY;
RefId mCell; RefId mCell;
CellId mCellId; // The CellId representation for saving/loading
std::string mNote; std::string mNote;

@ -3,6 +3,7 @@
#include "readerscache.hpp" #include "readerscache.hpp"
#include "savedgame.hpp" #include "savedgame.hpp"
#include <components/esm3/cellid.hpp>
#include <components/files/conversion.hpp> #include <components/files/conversion.hpp>
#include <components/files/openfile.hpp> #include <components/files/openfile.hpp>
#include <components/misc/strings/algorithm.hpp> #include <components/misc/strings/algorithm.hpp>
@ -86,6 +87,13 @@ namespace ESM
} }
} }
ESM::RefId ESMReader::getCellId()
{
ESM::CellId cellId;
cellId.load(*this);
return cellId.getCellRefId();
}
void ESMReader::openRaw(std::unique_ptr<std::istream>&& stream, const std::filesystem::path& name) void ESMReader::openRaw(std::unique_ptr<std::istream>&& stream, const std::filesystem::path& name)
{ {
close(); close();

@ -96,6 +96,9 @@ namespace ESM
* *
*************************************************************************/ *************************************************************************/
// Because we want to get rid of CellId, we isolate it's uses.
ESM::RefId getCellId();
// Read data of a given type, stored in a subrecord of a given name // Read data of a given type, stored in a subrecord of a given name
template <typename X> template <typename X>
void getHNT(X& x, NAME name) void getHNT(X& x, NAME name)

@ -4,6 +4,7 @@
#include <fstream> #include <fstream>
#include <stdexcept> #include <stdexcept>
#include <components/esm3/cellid.hpp>
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/misc/notnullptr.hpp> #include <components/misc/notnullptr.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/to_utf8/to_utf8.hpp>
@ -236,6 +237,12 @@ namespace ESM
writeHNRefId(name, value); writeHNRefId(name, value);
} }
void ESMWriter::writeCellId(const ESM::RefId& cellId)
{
ESM::CellId cell = ESM::CellId::extractFromRefId(cellId);
cell.save(*this);
}
void ESMWriter::writeMaybeFixedSizeString(const std::string& data, std::size_t size) void ESMWriter::writeMaybeFixedSizeString(const std::string& data, std::size_t size)
{ {
std::string string; std::string string;

@ -103,6 +103,8 @@ namespace ESM
writeHNCRefId(name, value); writeHNCRefId(name, value);
} }
void writeCellId(const ESM::RefId& cellId);
template <typename T> template <typename T>
void writeHNT(NAME name, const T& data) void writeHNT(NAME name, const T& data)
{ {

@ -59,7 +59,23 @@ namespace ESM
const ESM::RefId& Cell::updateId() const ESM::RefId& Cell::updateId()
{ {
mId = mCellId.getCellRefId(); CellId cellid;
cellid.mPaged = !(mData.mFlags & Interior);
if (cellid.mPaged)
{
cellid.mWorldspace = CellId::sDefaultWorldspace;
cellid.mIndex.mX = mData.mX;
cellid.mIndex.mY = mData.mY;
}
else
{
cellid.mWorldspace = Misc::StringUtils::lowerCase(mName);
cellid.mIndex.mX = 0;
cellid.mIndex.mY = 0;
}
mId = cellid.getCellRefId();
return mId; return mId;
} }
@ -97,20 +113,6 @@ namespace ESM
if (!hasData) if (!hasData)
esm.fail("Missing DATA subrecord"); esm.fail("Missing DATA subrecord");
mCellId.mPaged = !(mData.mFlags & Interior);
if (mCellId.mPaged)
{
mCellId.mWorldspace = CellId::sDefaultWorldspace;
mCellId.mIndex.mX = mData.mX;
mCellId.mIndex.mY = mData.mY;
}
else
{
mCellId.mWorldspace = Misc::StringUtils::lowerCase(mName);
mCellId.mIndex.mX = 0;
mCellId.mIndex.mY = 0;
}
updateId(); updateId();
} }
@ -340,8 +342,4 @@ namespace ESM
mAmbi.mFogDensity = 0; mAmbi.mFogDensity = 0;
} }
const CellId& Cell::getCellId() const
{
return mCellId;
}
} }

@ -120,7 +120,6 @@ namespace ESM
std::vector<ESM_Context> mContextList; // File position; multiple positions for multiple plugin support std::vector<ESM_Context> mContextList; // File position; multiple positions for multiple plugin support
DATAstruct mData; DATAstruct mData;
CellId mCellId;
AMBIstruct mAmbi; AMBIstruct mAmbi;
bool mHasAmbi; bool mHasAmbi;
@ -191,7 +190,6 @@ namespace ESM
void blank(); void blank();
///< Set record to default state (does not touch the ID/index). ///< Set record to default state (does not touch the ID/index).
const CellId& getCellId() const;
const ESM::RefId& updateId(); const ESM::RefId& updateId();
}; };
} }

@ -11,7 +11,7 @@ namespace ESM
mObject.mRef.loadId(esm, true); mObject.mRef.loadId(esm, true);
mObject.load(esm); mObject.load(esm);
mCellId.load(esm); mCellId = esm.getCellId();
esm.getHNTSized<12>(mLastKnownExteriorPosition, "LKEP"); esm.getHNTSized<12>(mLastKnownExteriorPosition, "LKEP");
@ -19,7 +19,7 @@ namespace ESM
{ {
mHasMark = true; mHasMark = true;
esm.getHTSized<24>(mMarkedPosition); esm.getHTSized<24>(mMarkedPosition);
mMarkedCell.load(esm); mMarkedCell = esm.getCellId();
} }
else else
mHasMark = false; mHasMark = false;
@ -92,14 +92,14 @@ namespace ESM
{ {
mObject.save(esm); mObject.save(esm);
mCellId.save(esm); esm.writeCellId(mCellId);
esm.writeHNT("LKEP", mLastKnownExteriorPosition); esm.writeHNT("LKEP", mLastKnownExteriorPosition);
if (mHasMark) if (mHasMark)
{ {
esm.writeHNT("MARK", mMarkedPosition, 24); esm.writeHNT("MARK", mMarkedPosition, 24);
mMarkedCell.save(esm); esm.writeCellId(mMarkedCell);
} }
esm.writeHNRefId("SIGN", mBirthsign); esm.writeHNRefId("SIGN", mBirthsign);

@ -20,12 +20,12 @@ namespace ESM
struct Player struct Player
{ {
NpcState mObject; NpcState mObject;
CellId mCellId; RefId mCellId;
float mLastKnownExteriorPosition[3]; float mLastKnownExteriorPosition[3];
unsigned char mHasMark; unsigned char mHasMark;
bool mSetWerewolfAcrobatics; bool mSetWerewolfAcrobatics;
Position mMarkedPosition; Position mMarkedPosition;
CellId mMarkedCell; RefId mMarkedCell;
ESM::RefId mBirthsign; ESM::RefId mBirthsign;
int mCurrentCrimeId; int mCurrentCrimeId;

@ -45,7 +45,7 @@ namespace EsmLoader
return (v.mId); return (v.mId);
} }
const ESM::CellId& operator()(const ESM::Cell& v) const { return v.mCellId; } const ESM::RefId& operator()(const ESM::Cell& v) const { return v.mId; }
std::pair<int, int> operator()(const ESM::Land& v) const { return std::pair(v.mX, v.mY); } std::pair<int, int> operator()(const ESM::Land& v) const { return std::pair(v.mX, v.mY); }

Loading…
Cancel
Save