1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-30 10:15:38 +00:00

ESM::CellVariant aans MWWorld:Cell now take reference in constructor: signals that nullptr isn't accepted.

also applied other review comments.
This commit is contained in:
florent.teppe 2023-01-27 14:07:50 +01:00
parent 531e55e04c
commit cb8cdd8831
10 changed files with 95 additions and 109 deletions

View file

@ -307,7 +307,7 @@ namespace MWClass
const osg::Vec2i index
= MWWorld::positionToCellIndex(door.mRef.getDoorDest().pos[0], door.mRef.getDoorDest().pos[1]);
const ESM::Cell* cell = world->getStore().get<ESM::Cell>().search(index.x(), index.y());
dest = world->getCellName(MWWorld::Cell(cell));
dest = world->getCellName(MWWorld::Cell(*cell));
}
return "#{sCell=" + std::string{ dest } + "}";

View file

@ -418,7 +418,7 @@ bool MWMechanics::AiPackage::isNearInactiveCell(osg::Vec3f position)
if (playerCell->isExterior())
{
// get actor's distance from origin of center cell
Misc::CoordinateConverter(ESM::CellVariant(playerCell)).toLocal(position);
Misc::CoordinateConverter(ESM::CellVariant(*playerCell)).toLocal(position);
// currently assumes 3 x 3 grid for exterior cells, with player at center cell.
// AI shuts down actors before they reach edges of 3 x 3 grid.

View file

@ -839,7 +839,7 @@ namespace MWMechanics
if (mDistance && storage.mCanWanderAlongPathGrid && !actor.getClass().isPureWaterCreature(actor))
{
// get NPC's position in local (i.e. cell) coordinates
auto converter = Misc::CoordinateConverter(ESM::CellVariant(cell));
auto converter = Misc::CoordinateConverter(ESM::CellVariant(*cell));
const osg::Vec3f npcPos = converter.toLocalVec3(mInitialActorPosition);
// Find closest pathgrid point

View file

@ -6,57 +6,56 @@
namespace MWWorld
{
Cell::Cell(const ESM4::Cell* cell)
Cell::Cell(const ESM4::Cell& cell)
: ESM::CellVariant(cell)
{
assert(cell != nullptr);
mNameID = cell->mEditorId;
mDisplayname = cell->mFullName;
mGridPos.x() = cell->mX;
mGridPos.y() = cell->mY;
mNameID = cell.mEditorId;
mDisplayname = cell.mFullName;
mGridPos.x() = cell.mX;
mGridPos.y() = cell.mY;
mRegion = ESM::RefId::sEmpty; // Unimplemented for now
mFlags.hasWater = (cell->mCellFlags & ESM4::CELL_HasWater) != 0;
mFlags.isExterior = !(cell->mCellFlags & ESM4::CELL_Interior);
mFlags.isQuasiExterior = (cell->mCellFlags & ESM4::CELL_QuasiExt) != 0;
mFlags.hasWater = (cell.mCellFlags & ESM4::CELL_HasWater) != 0;
mFlags.isExterior = !(cell.mCellFlags & ESM4::CELL_Interior);
mFlags.isQuasiExterior = (cell.mCellFlags & ESM4::CELL_QuasiExt) != 0;
mFlags.noSleep = false; // No such notion in ESM4
mCellId.mWorldspace = Misc::StringUtils::lowerCase(cell->mEditorId);
mCellId.mWorldspace = Misc::StringUtils::lowerCase(cell.mEditorId);
mCellId.mWorld = ESM::RefId::sEmpty;
mCellId.mIndex.mX = cell->getGridX();
mCellId.mIndex.mX = cell->getGridY();
mCellId.mIndex.mX = cell.getGridX();
mCellId.mIndex.mX = cell.getGridY();
mCellId.mPaged = isExterior();
mMood.mAmbiantColor = cell->mLighting.ambient;
mMood.mFogColor = cell->mLighting.fogColor;
mMood.mDirectionalColor = cell->mLighting.directional;
mMood.mFogDensity = cell->mLighting.fogPower;
mMood.mAmbiantColor = cell.mLighting.ambient;
mMood.mFogColor = cell.mLighting.fogColor;
mMood.mDirectionalColor = cell.mLighting.directional;
mMood.mFogDensity = cell.mLighting.fogPower;
}
Cell::Cell(const ESM::Cell* cell)
Cell::Cell(const ESM::Cell& cell)
: ESM::CellVariant(cell)
{
assert(cell != nullptr);
mNameID = cell->mName;
mDisplayname = cell->mName;
mGridPos.x() = cell->getGridX();
mGridPos.y() = cell->getGridY();
mNameID = cell.mName;
mDisplayname = cell.mName;
mGridPos.x() = cell.getGridX();
mGridPos.y() = cell.getGridY();
mRegion = ESM::RefId::sEmpty; // Unimplemented for now
mFlags.hasWater = (cell->mData.mFlags & ESM::Cell::HasWater) != 0;
mFlags.isExterior = !(cell->mData.mFlags & ESM::Cell::Interior);
mFlags.isQuasiExterior = (cell->mData.mFlags & ESM::Cell::QuasiEx) != 0;
mFlags.noSleep = (cell->mData.mFlags & ESM::Cell::NoSleep) != 0;
mFlags.hasWater = (cell.mData.mFlags & ESM::Cell::HasWater) != 0;
mFlags.isExterior = !(cell.mData.mFlags & ESM::Cell::Interior);
mFlags.isQuasiExterior = (cell.mData.mFlags & ESM::Cell::QuasiEx) != 0;
mFlags.noSleep = (cell.mData.mFlags & ESM::Cell::NoSleep) != 0;
mCellId = cell->getCellId();
mCellId = cell.getCellId();
mMood.mAmbiantColor = cell->mAmbi.mAmbient;
mMood.mFogColor = cell->mAmbi.mFog;
mMood.mDirectionalColor = cell->mAmbi.mSunlight;
mMood.mFogDensity = cell->mAmbi.mFogDensity;
mMood.mAmbiantColor = cell.mAmbi.mAmbient;
mMood.mFogColor = cell.mAmbi.mFog;
mMood.mDirectionalColor = cell.mAmbi.mSunlight;
mMood.mFogDensity = cell.mAmbi.mFogDensity;
}
std::string Cell::getDescription() const

View file

@ -30,8 +30,8 @@ namespace MWWorld
};
public:
explicit Cell(const ESM4::Cell* cell);
explicit Cell(const ESM::Cell* cell);
explicit Cell(const ESM4::Cell& cell);
explicit Cell(const ESM::Cell& cell);
int getGridX() const { return mGridPos.x(); }
int getGridY() const { return mGridPos.y(); }

View file

@ -383,57 +383,57 @@ namespace MWWorld
assert(mActiveCells.find(cell) == mActiveCells.end());
mActiveCells.insert(cell);
Log(Debug::Info) << "Loading cell " << cell->getCell()->getEditorName();
Log(Debug::Info) << "Loading cell " << cell->getCell()->getDescription();
const int cellX = cell->getCell()->getGridX();
const int cellY = cell->getCell()->getGridY();
auto cellVariant = *cell->getCell();
if (cellVariant.isExterior())
{
osg::ref_ptr<const ESMTerrain::LandObject> land = mRendering.getLandManager()->getLand(cellX, cellY);
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;
if (data)
{
mPhysics->addHeightField(
data->mHeights, cellX, cellY, worldsize, verts, data->mMinHeight, data->mMaxHeight, land.get());
}
else
{
static std::vector<float> defaultHeight;
defaultHeight.resize(verts * verts, ESM::Land::DEFAULT_HEIGHT);
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))
{
const osg::Vec2i cellPosition(cellX, cellY);
const btVector3& origin = heightField->getCollisionObject()->getWorldTransform().getOrigin();
const osg::Vec3f shift(origin.x(), origin.y(), origin.z());
const HeightfieldShape shape = [&]() -> HeightfieldShape {
if (data == nullptr)
{
return DetourNavigator::HeightfieldPlane{ static_cast<float>(ESM::Land::DEFAULT_HEIGHT) };
}
else
{
DetourNavigator::HeightfieldSurface heights;
heights.mHeights = data->mHeights;
heights.mSize = static_cast<std::size_t>(ESM::Land::LAND_SIZE);
heights.mMinHeight = data->mMinHeight;
heights.mMaxHeight = data->mMaxHeight;
return heights;
}
}();
mNavigator.addHeightfield(cellPosition, ESM::Land::REAL_SIZE, shape, navigatorUpdateGuard);
}
}
if (!cellVariant.isEsm4())
{
auto cell3 = cellVariant.getEsm3();
if (cell3.isExterior())
{
osg::ref_ptr<const ESMTerrain::LandObject> land = mRendering.getLandManager()->getLand(cellX, cellY);
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;
if (data)
{
mPhysics->addHeightField(
data->mHeights, cellX, cellY, worldsize, verts, data->mMinHeight, data->mMaxHeight, land.get());
}
else
{
static std::vector<float> defaultHeight;
defaultHeight.resize(verts * verts, ESM::Land::DEFAULT_HEIGHT);
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))
{
const osg::Vec2i cellPosition(cellX, cellY);
const btVector3& origin = heightField->getCollisionObject()->getWorldTransform().getOrigin();
const osg::Vec3f shift(origin.x(), origin.y(), origin.z());
const HeightfieldShape shape = [&]() -> HeightfieldShape {
if (data == nullptr)
{
return DetourNavigator::HeightfieldPlane{ static_cast<float>(ESM::Land::DEFAULT_HEIGHT) };
}
else
{
DetourNavigator::HeightfieldSurface heights;
heights.mHeights = data->mHeights;
heights.mSize = static_cast<std::size_t>(ESM::Land::LAND_SIZE);
heights.mMinHeight = data->mMinHeight;
heights.mMaxHeight = data->mMaxHeight;
return heights;
}
}();
mNavigator.addHeightfield(cellPosition, ESM::Land::REAL_SIZE, shape, navigatorUpdateGuard);
}
}
if (const auto pathgrid = mWorld.getStore().get<ESM::Pathgrid>().search(cell3))
mNavigator.addPathgrid(cell3, *pathgrid);
}

View file

@ -67,7 +67,7 @@ MWWorld::CellStore* MWWorld::WorldModel::getCellStore(const ESM::Cell* cell)
auto result = mInteriors.find(cell->mName);
if (result == mInteriors.end())
result = mInteriors.emplace(cell->mName, CellStore(MWWorld::Cell(cell), mStore, mReaders)).first;
result = mInteriors.emplace(cell->mName, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first;
return &result->second;
}
@ -79,7 +79,7 @@ MWWorld::CellStore* MWWorld::WorldModel::getCellStore(const ESM::Cell* cell)
if (result == mExteriors.end())
result = mExteriors
.emplace(std::make_pair(cell->getGridX(), cell->getGridY()),
CellStore(MWWorld::Cell(cell), mStore, mReaders))
CellStore(MWWorld::Cell(*cell), mStore, mReaders))
.first;
return &result->second;
@ -186,7 +186,7 @@ MWWorld::CellStore* MWWorld::WorldModel::getExterior(int x, int y)
cell = MWBase::Environment::get().getWorld()->createRecord(record);
}
result = mExteriors.emplace(std::make_pair(x, y), CellStore(MWWorld::Cell(cell), mStore, mReaders)).first;
result = mExteriors.emplace(std::make_pair(x, y), CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first;
}
if (result->second.getState() != CellStore::State_Loaded)
@ -208,11 +208,11 @@ MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name)
if (!cell4)
{
const ESM::Cell* cell = mStore.get<ESM::Cell>().find(name);
result = mInteriors.emplace(name, CellStore(MWWorld::Cell(cell), mStore, mReaders)).first;
result = mInteriors.emplace(name, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first;
}
else
{
result = mInteriors.emplace(name, CellStore(MWWorld::Cell(cell4), mStore, mReaders)).first;
result = mInteriors.emplace(name, CellStore(MWWorld::Cell(*cell4), mStore, mReaders)).first;
}
}
@ -265,12 +265,12 @@ const ESM::Cell* MWWorld::WorldModel::getESMCellByName(std::string_view name)
ESM::CellVariant MWWorld::WorldModel::getCellByName(std::string_view name)
{
const ESM::Cell* cellEsm3 = getESMCellByName(name);
return ESM::CellVariant(cellEsm3);
if (!cellEsm3)
{
const ESM4::Cell* cellESM4 = mStore.get<ESM4::Cell>().searchCellName(name);
return ESM::CellVariant(cellESM4);
return ESM::CellVariant(*cellESM4);
}
return ESM::CellVariant(*cellEsm3);
}
MWWorld::CellStore* MWWorld::WorldModel::getCell(std::string_view name)

View file

@ -134,7 +134,7 @@ namespace DetourNavigator
void NavigatorImpl::addPathgrid(const ESM::Cell& cell, const ESM::Pathgrid& pathgrid)
{
Misc::CoordinateConverter converter = Misc::CoordinateConverter(ESM::CellVariant(&cell));
Misc::CoordinateConverter converter = Misc::CoordinateConverter(ESM::CellVariant(cell));
for (const auto& edge : pathgrid.mEdges)
{
const auto src = Misc::Convert::makeOsgVec3f(converter.toWorldPoint(pathgrid.mPoints[edge.mV0]));

View file

@ -6,17 +6,13 @@ namespace ESM
{
const ESM4::Cell& CellVariant::getEsm4() const
{
auto cell4 = std::get<0>(mVariant);
if (!cell4)
throw std::runtime_error("invalid variant acess");
auto cell4 = std::get<const ESM4::Cell*>(mVariant);
return *cell4;
}
const ESM::Cell& CellVariant::getEsm3() const
{
auto cell = std::get<1>(mVariant);
if (!cell)
throw std::runtime_error("invalid variant acess");
auto cell = std::get<const ESM::Cell*>(mVariant);
return *cell;
}
}

View file

@ -19,29 +19,20 @@ namespace ESM
struct CellVariant
{
std::variant<const ESM4::Cell*, const ESM::Cell*, const void*> mVariant;
private:
std::variant<const ESM4::Cell*, const ESM::Cell*> mVariant;
CellVariant()
: mVariant((void*)(nullptr))
public:
explicit CellVariant(const ESM4::Cell& cell)
: mVariant(&cell)
{
}
explicit CellVariant(const ESM4::Cell* cell)
: mVariant(cell)
explicit CellVariant(const ESM::Cell& cell)
: mVariant(&cell)
{
}
explicit CellVariant(const ESM::Cell* cell)
: mVariant(cell)
{
}
bool isValid() const
{
return std::holds_alternative<const ESM4::Cell*>(mVariant)
|| std::holds_alternative<const ESM::Cell*>(mVariant);
}
bool isEsm4() const { return std::holds_alternative<const ESM4::Cell*>(mVariant); }
const ESM4::Cell& getEsm4() const;