1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-20 15:40:32 +00:00

No more Cellid used by ESM4 cells

and that also means it is no longer used by MWWorld::Cell
fixes tests
This commit is contained in:
florent.teppe 2023-02-19 21:18:15 +01:00
parent 1bbf4a3acf
commit 9f597ecfea
13 changed files with 59 additions and 31 deletions

View File

@ -2,6 +2,7 @@
#include <components/esm3/aisequence.hpp>
#include <components/esm3/loadcell.hpp>
#include <components/misc/algorithm.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
@ -78,7 +79,7 @@ namespace MWMechanics
}
}
if (!mCellId.empty() && mCellId != actor.getCell()->getCell()->getCellId().mWorldspace)
if (!mCellId.empty() && !Misc::StringUtils::ciEqual(mCellId, actor.getCell()->getCell()->getNameId()))
return false; // Not in the correct cell, pause and rely on the player to go back through a teleport door
actor.getClass().getCreatureStats(actor).setDrawState(DrawState::Nothing);

View File

@ -330,9 +330,9 @@ void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor)
const MWMechanics::PathgridGraph& MWMechanics::AiPackage::getPathGridGraph(const MWWorld::CellStore* cell)
{
const ESM::CellId& id = cell->getCell()->getCellId();
const ESM::RefId& id = cell->getCell()->getId();
// static cache is OK for now, pathgrids can never change during runtime
typedef std::map<ESM::CellId, std::unique_ptr<MWMechanics::PathgridGraph>> CacheMap;
typedef std::map<ESM::RefId, std::unique_ptr<MWMechanics::PathgridGraph>> CacheMap;
static CacheMap cache;
CacheMap::iterator found = cache.find(id);
if (found == cache.end())

View File

@ -87,8 +87,8 @@ namespace MWScript
float distance;
// If the objects are in different worldspaces, return a large value (just like vanilla)
if (!to.isInCell() || !from.isInCell()
|| to.getCell()->getCell()->getCellId().mWorldspace
!= from.getCell()->getCell()->getCellId().mWorldspace)
|| !Misc::StringUtils::ciEqual(
to.getCell()->getCell()->getNameId(), from.getCell()->getCell()->getNameId()))
distance = std::numeric_limits<float>::max();
else
{

View File

@ -555,7 +555,7 @@ void MWState::StateManager::loadGame(const Character* character, const std::file
if (ptr.isInCell())
{
const ESM::CellId& cellId = ptr.getCell()->getCell()->getCellId();
const ESM::RefId& cellId = ptr.getCell()->getCell()->getId();
// Use detectWorldSpaceChange=false, otherwise some of the data we just loaded would be cleared again
MWBase::Environment::get().getWorld()->changeToCell(cellId, ptr.getRefData().getPosition(), false, false);
@ -574,7 +574,7 @@ void MWState::StateManager::loadGame(const Character* character, const std::file
pos.rot[0] = 0;
pos.rot[1] = 0;
pos.rot[2] = 0;
MWBase::Environment::get().getWorld()->changeToCell(cell->getCell()->getCellId(), pos, true, false);
MWBase::Environment::get().getWorld()->changeToCell(cell->getCell()->getId(), pos, true, false);
}
MWBase::Environment::get().getWorld()->updateProjectilesCasters();

View File

@ -16,10 +16,6 @@ namespace MWWorld
, mDisplayname(cell.mFullName)
, mNameID(cell.mEditorId)
, mRegion(ESM::RefId()) // Unimplemented for now
, mCellId{
.mWorldspace{ Misc::StringUtils::lowerCase(cell.mEditorId) },
.mIndex{ cell.getGridX(), cell.getGridY() },
.mPaged = isExterior(),}
, mId(cell.mId)
,mMood{
.mAmbiantColor = cell.mLighting.ambient,
@ -41,7 +37,6 @@ namespace MWWorld
, mDisplayname(cell.mName)
, mNameID(cell.mName)
, mRegion(cell.mRegion)
, mCellId(cell.getCellId())
, mId(cell.mId)
, mMood{
.mAmbiantColor = cell.mAmbi.mAmbient,

View File

@ -42,7 +42,6 @@ namespace MWWorld
bool isQuasiExterior() const { return mIsQuasiExterior; }
bool hasWater() const { return mHasWater; }
bool noSleep() const { return mNoSleep; }
const ESM::CellId& getCellId() const { return mCellId; }
const ESM::RefId& getRegion() const { return mRegion; }
std::string_view getNameId() const { return mNameID; }
std::string_view getDisplayName() const { return mDisplayname; }
@ -61,7 +60,6 @@ namespace MWWorld
std::string mDisplayname; // How the game displays it
std::string mNameID; // The name that will be used by the script and console commands
ESM::RefId mRegion;
ESM::CellId mCellId;
ESM::RefId mId;
MoodData mMood;

View File

@ -988,7 +988,7 @@ namespace MWWorld
void CellStore::saveState(ESM::CellState& state) const
{
state.mId = mCellVariant.getCellId();
state.mId = ESM::CellId::extractFromRefId(mCellVariant.getId());
if (!mCellVariant.isExterior() && mCellVariant.hasWater())
state.mWaterLevel = mWaterLevel;
@ -1019,7 +1019,7 @@ namespace MWWorld
for (const auto& [base, store] : mMovedToAnotherCell)
{
ESM::RefNum refNum = base->mRef.getRefNum();
ESM::CellId movedTo = store->getCell()->getCellId();
ESM::CellId movedTo = ESM::CellId::extractFromRefId(store->getCell()->getId());
refNum.save(writer, true, "MVRF");
movedTo.save(writer);

View File

@ -283,7 +283,7 @@ namespace MWWorld
ESM::Player player;
mPlayer.save(player.mObject);
player.mCellId = mCellStore->getCell()->getCellId();
player.mCellId = ESM::CellId::extractFromRefId(mCellStore->getCell()->getId());
player.mCurrentCrimeId = mCurrentCrimeId;
player.mPaidCrimeId = mPaidCrimeId;
@ -298,7 +298,7 @@ namespace MWWorld
{
player.mHasMark = true;
player.mMarkedPosition = mMarkedPosition;
player.mMarkedCell = mMarkedCell->getCell()->getCellId();
player.mMarkedCell = ESM::CellId::extractFromRefId(mMarkedCell->getCell()->getId());
}
else
player.mHasMark = false;

View File

@ -554,7 +554,7 @@ namespace MWWorld
mNavigator.setWorldspace(
Misc::StringUtils::lowerCase(
mWorld.getWorldModel().getExterior(playerCellX, playerCellY)->getCell()->getCellId().mWorldspace),
mWorld.getWorldModel().getExterior(playerCellX, playerCellY)->getCell()->getNameId()),
navigatorUpdateGuard.get());
mNavigator.updateBounds(pos, navigatorUpdateGuard.get());
@ -676,7 +676,7 @@ namespace MWWorld
CellStore* cell = mWorld.getWorldModel().getExterior(it->mData.mX, it->mData.mY);
mNavigator.setWorldspace(
Misc::StringUtils::lowerCase(cell->getCell()->getCellId().mWorldspace), navigatorUpdateGuard.get());
Misc::StringUtils::lowerCase(cell->getCell()->getNameId()), navigatorUpdateGuard.get());
const osg::Vec3f position
= osg::Vec3f(it->mData.mX + 0.5f, it->mData.mY + 0.5f, 0) * Constants::CellSizeInUnits;
mNavigator.updateBounds(position, navigatorUpdateGuard.get());
@ -734,7 +734,7 @@ namespace MWWorld
CellStore* cell = mWorld.getWorldModel().getInterior(it->mName);
mNavigator.setWorldspace(
Misc::StringUtils::lowerCase(cell->getCell()->getCellId().mWorldspace), navigatorUpdateGuard.get());
Misc::StringUtils::lowerCase(cell->getCell()->getNameId()), navigatorUpdateGuard.get());
ESM::Position position;
mWorld.findInteriorPosition(it->mName, position);
mNavigator.updateBounds(position.asVec3(), navigatorUpdateGuard.get());
@ -890,7 +890,7 @@ namespace MWWorld
loadingListener->setProgressRange(cell->count());
mNavigator.setWorldspace(
Misc::StringUtils::lowerCase(cell->getCell()->getCellId().mWorldspace), navigatorUpdateGuard.get());
Misc::StringUtils::lowerCase(cell->getCell()->getNameId()), navigatorUpdateGuard.get());
mNavigator.updateBounds(position.asVec3(), navigatorUpdateGuard.get());
// Load cell.

View File

@ -240,16 +240,12 @@ MWWorld::CellStore* MWWorld::WorldModel::getCell(const ESM::RefId& id)
if (result != mCells.end())
return &result->second;
// TODO: in the future replace that with elsid's refId variant that can be a osg::Vec2i
const std::string& idString = id.getRefIdString();
if (idString[0] == '#' && idString.find(',')) // That is an exterior cell Id
// TODO tetramir: in the future replace that with elsid's refId variant that can be a osg::Vec2i
ESM::CellId cellId = ESM::CellId::extractFromRefId(id);
if (cellId.mPaged) // That is an exterior cell Id
{
int x, y;
std::stringstream stringStream = std::stringstream(idString);
char sharp = '#';
char comma = ',';
stringStream >> sharp >> x >> comma >> y;
return getExterior(x, y);
return getExterior(cellId.mIndex.mX, cellId.mIndex.mY);
}
const ESM4::Cell* cell4 = mStore.get<ESM4::Cell>().search(id);

View File

@ -445,6 +445,13 @@ namespace
decltype(RecordType::mId) refId;
if constexpr (ESM::hasIndex<RecordType> && !std::is_same_v<RecordType, ESM::LandTexture>)
refId = RecordType::indexToRefId(index);
else if constexpr (std::is_same_v<RecordType, ESM::Cell>)
{
ESM::CellId cellId;
cellId.mPaged = true;
cellId.mIndex = { 0, 0 };
refId = cellId.getCellRefId();
}
else
refId = ESM::StringRefId(stringId);
@ -484,6 +491,9 @@ namespace
else
result = esmStore.get<RecordType>().search(refId);
if (result == nullptr || result->mId != refId)
int debug = 0;
ASSERT_NE(result, nullptr);
EXPECT_EQ(result->mId, refId);
}

View File

@ -2,6 +2,7 @@
#include "esmreader.hpp"
#include "esmwriter.hpp"
#include <components/misc/algorithm.hpp>
namespace ESM
{
@ -45,6 +46,30 @@ namespace ESM
}
}
CellId CellId::extractFromRefId(const ESM::RefId& id)
{
// This is bad and that code should not be merged.
const std::string& idString = id.getRefIdString();
CellId out;
if (idString[0] == '#' && idString.find(',')) // That is an exterior cell Id
{
int x, y;
std::stringstream stringStream = std::stringstream(idString);
char sharp = '#';
char comma = ',';
stringStream >> sharp >> x >> comma >> y;
out.mPaged = true;
out.mIndex = { x, y };
}
else
{
out.mPaged = false;
out.mWorldspace = Misc::StringUtils::lowerCase(idString);
}
return out;
}
bool operator==(const CellId& left, const CellId& right)
{
return left.mWorldspace == right.mWorldspace && left.mPaged == right.mPaged

View File

@ -26,6 +26,9 @@ namespace ESM
void load(ESMReader& esm);
void save(ESMWriter& esm) const;
ESM::RefId getCellRefId() const;
// TODO tetramir: this probably shouldn't exist, needs it because some CellIds are saved on disk
static CellId extractFromRefId(const ESM::RefId& id);
};
bool operator==(const CellId& left, const CellId& right);