mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-28 22:13:21 +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:
parent
531e55e04c
commit
cb8cdd8831
@ -307,7 +307,7 @@ namespace MWClass
|
|||||||
const osg::Vec2i index
|
const osg::Vec2i index
|
||||||
= MWWorld::positionToCellIndex(door.mRef.getDoorDest().pos[0], door.mRef.getDoorDest().pos[1]);
|
= 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());
|
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 } + "}";
|
return "#{sCell=" + std::string{ dest } + "}";
|
||||||
|
@ -418,7 +418,7 @@ bool MWMechanics::AiPackage::isNearInactiveCell(osg::Vec3f position)
|
|||||||
if (playerCell->isExterior())
|
if (playerCell->isExterior())
|
||||||
{
|
{
|
||||||
// get actor's distance from origin of center cell
|
// 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.
|
// 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.
|
// AI shuts down actors before they reach edges of 3 x 3 grid.
|
||||||
|
@ -839,7 +839,7 @@ namespace MWMechanics
|
|||||||
if (mDistance && storage.mCanWanderAlongPathGrid && !actor.getClass().isPureWaterCreature(actor))
|
if (mDistance && storage.mCanWanderAlongPathGrid && !actor.getClass().isPureWaterCreature(actor))
|
||||||
{
|
{
|
||||||
// get NPC's position in local (i.e. cell) coordinates
|
// 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);
|
const osg::Vec3f npcPos = converter.toLocalVec3(mInitialActorPosition);
|
||||||
|
|
||||||
// Find closest pathgrid point
|
// Find closest pathgrid point
|
||||||
|
@ -6,57 +6,56 @@
|
|||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
Cell::Cell(const ESM4::Cell* cell)
|
Cell::Cell(const ESM4::Cell& cell)
|
||||||
: ESM::CellVariant(cell)
|
: ESM::CellVariant(cell)
|
||||||
{
|
{
|
||||||
assert(cell != nullptr);
|
|
||||||
|
|
||||||
mNameID = cell->mEditorId;
|
mNameID = cell.mEditorId;
|
||||||
mDisplayname = cell->mFullName;
|
mDisplayname = cell.mFullName;
|
||||||
mGridPos.x() = cell->mX;
|
mGridPos.x() = cell.mX;
|
||||||
mGridPos.y() = cell->mY;
|
mGridPos.y() = cell.mY;
|
||||||
|
|
||||||
mRegion = ESM::RefId::sEmpty; // Unimplemented for now
|
mRegion = ESM::RefId::sEmpty; // Unimplemented for now
|
||||||
|
|
||||||
mFlags.hasWater = (cell->mCellFlags & ESM4::CELL_HasWater) != 0;
|
mFlags.hasWater = (cell.mCellFlags & ESM4::CELL_HasWater) != 0;
|
||||||
mFlags.isExterior = !(cell->mCellFlags & ESM4::CELL_Interior);
|
mFlags.isExterior = !(cell.mCellFlags & ESM4::CELL_Interior);
|
||||||
mFlags.isQuasiExterior = (cell->mCellFlags & ESM4::CELL_QuasiExt) != 0;
|
mFlags.isQuasiExterior = (cell.mCellFlags & ESM4::CELL_QuasiExt) != 0;
|
||||||
mFlags.noSleep = false; // No such notion in ESM4
|
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.mWorld = ESM::RefId::sEmpty;
|
||||||
mCellId.mIndex.mX = cell->getGridX();
|
mCellId.mIndex.mX = cell.getGridX();
|
||||||
mCellId.mIndex.mX = cell->getGridY();
|
mCellId.mIndex.mX = cell.getGridY();
|
||||||
mCellId.mPaged = isExterior();
|
mCellId.mPaged = isExterior();
|
||||||
|
|
||||||
mMood.mAmbiantColor = cell->mLighting.ambient;
|
mMood.mAmbiantColor = cell.mLighting.ambient;
|
||||||
mMood.mFogColor = cell->mLighting.fogColor;
|
mMood.mFogColor = cell.mLighting.fogColor;
|
||||||
mMood.mDirectionalColor = cell->mLighting.directional;
|
mMood.mDirectionalColor = cell.mLighting.directional;
|
||||||
mMood.mFogDensity = cell->mLighting.fogPower;
|
mMood.mFogDensity = cell.mLighting.fogPower;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cell::Cell(const ESM::Cell* cell)
|
Cell::Cell(const ESM::Cell& cell)
|
||||||
: ESM::CellVariant(cell)
|
: ESM::CellVariant(cell)
|
||||||
{
|
{
|
||||||
assert(cell != nullptr);
|
assert(cell != nullptr);
|
||||||
mNameID = cell->mName;
|
mNameID = cell.mName;
|
||||||
mDisplayname = cell->mName;
|
mDisplayname = cell.mName;
|
||||||
mGridPos.x() = cell->getGridX();
|
mGridPos.x() = cell.getGridX();
|
||||||
mGridPos.y() = cell->getGridY();
|
mGridPos.y() = cell.getGridY();
|
||||||
|
|
||||||
mRegion = ESM::RefId::sEmpty; // Unimplemented for now
|
mRegion = ESM::RefId::sEmpty; // Unimplemented for now
|
||||||
|
|
||||||
mFlags.hasWater = (cell->mData.mFlags & ESM::Cell::HasWater) != 0;
|
mFlags.hasWater = (cell.mData.mFlags & ESM::Cell::HasWater) != 0;
|
||||||
mFlags.isExterior = !(cell->mData.mFlags & ESM::Cell::Interior);
|
mFlags.isExterior = !(cell.mData.mFlags & ESM::Cell::Interior);
|
||||||
mFlags.isQuasiExterior = (cell->mData.mFlags & ESM::Cell::QuasiEx) != 0;
|
mFlags.isQuasiExterior = (cell.mData.mFlags & ESM::Cell::QuasiEx) != 0;
|
||||||
mFlags.noSleep = (cell->mData.mFlags & ESM::Cell::NoSleep) != 0;
|
mFlags.noSleep = (cell.mData.mFlags & ESM::Cell::NoSleep) != 0;
|
||||||
|
|
||||||
mCellId = cell->getCellId();
|
mCellId = cell.getCellId();
|
||||||
|
|
||||||
mMood.mAmbiantColor = cell->mAmbi.mAmbient;
|
mMood.mAmbiantColor = cell.mAmbi.mAmbient;
|
||||||
mMood.mFogColor = cell->mAmbi.mFog;
|
mMood.mFogColor = cell.mAmbi.mFog;
|
||||||
mMood.mDirectionalColor = cell->mAmbi.mSunlight;
|
mMood.mDirectionalColor = cell.mAmbi.mSunlight;
|
||||||
mMood.mFogDensity = cell->mAmbi.mFogDensity;
|
mMood.mFogDensity = cell.mAmbi.mFogDensity;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Cell::getDescription() const
|
std::string Cell::getDescription() const
|
||||||
|
@ -30,8 +30,8 @@ namespace MWWorld
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Cell(const ESM4::Cell* cell);
|
explicit Cell(const ESM4::Cell& cell);
|
||||||
explicit Cell(const ESM::Cell* cell);
|
explicit Cell(const ESM::Cell& cell);
|
||||||
|
|
||||||
int getGridX() const { return mGridPos.x(); }
|
int getGridX() const { return mGridPos.x(); }
|
||||||
int getGridY() const { return mGridPos.y(); }
|
int getGridY() const { return mGridPos.y(); }
|
||||||
|
@ -383,57 +383,57 @@ namespace MWWorld
|
|||||||
assert(mActiveCells.find(cell) == mActiveCells.end());
|
assert(mActiveCells.find(cell) == mActiveCells.end());
|
||||||
mActiveCells.insert(cell);
|
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 cellX = cell->getCell()->getGridX();
|
||||||
const int cellY = cell->getCell()->getGridY();
|
const int cellY = cell->getCell()->getGridY();
|
||||||
auto cellVariant = *cell->getCell();
|
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())
|
if (!cellVariant.isEsm4())
|
||||||
{
|
{
|
||||||
auto cell3 = cellVariant.getEsm3();
|
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))
|
if (const auto pathgrid = mWorld.getStore().get<ESM::Pathgrid>().search(cell3))
|
||||||
mNavigator.addPathgrid(cell3, *pathgrid);
|
mNavigator.addPathgrid(cell3, *pathgrid);
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ MWWorld::CellStore* MWWorld::WorldModel::getCellStore(const ESM::Cell* cell)
|
|||||||
auto result = mInteriors.find(cell->mName);
|
auto result = mInteriors.find(cell->mName);
|
||||||
|
|
||||||
if (result == mInteriors.end())
|
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;
|
return &result->second;
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ MWWorld::CellStore* MWWorld::WorldModel::getCellStore(const ESM::Cell* cell)
|
|||||||
if (result == mExteriors.end())
|
if (result == mExteriors.end())
|
||||||
result = mExteriors
|
result = mExteriors
|
||||||
.emplace(std::make_pair(cell->getGridX(), cell->getGridY()),
|
.emplace(std::make_pair(cell->getGridX(), cell->getGridY()),
|
||||||
CellStore(MWWorld::Cell(cell), mStore, mReaders))
|
CellStore(MWWorld::Cell(*cell), mStore, mReaders))
|
||||||
.first;
|
.first;
|
||||||
|
|
||||||
return &result->second;
|
return &result->second;
|
||||||
@ -186,7 +186,7 @@ MWWorld::CellStore* MWWorld::WorldModel::getExterior(int x, int y)
|
|||||||
cell = MWBase::Environment::get().getWorld()->createRecord(record);
|
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)
|
if (result->second.getState() != CellStore::State_Loaded)
|
||||||
@ -208,11 +208,11 @@ MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name)
|
|||||||
if (!cell4)
|
if (!cell4)
|
||||||
{
|
{
|
||||||
const ESM::Cell* cell = mStore.get<ESM::Cell>().find(name);
|
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
|
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)
|
ESM::CellVariant MWWorld::WorldModel::getCellByName(std::string_view name)
|
||||||
{
|
{
|
||||||
const ESM::Cell* cellEsm3 = getESMCellByName(name);
|
const ESM::Cell* cellEsm3 = getESMCellByName(name);
|
||||||
return ESM::CellVariant(cellEsm3);
|
|
||||||
if (!cellEsm3)
|
if (!cellEsm3)
|
||||||
{
|
{
|
||||||
const ESM4::Cell* cellESM4 = mStore.get<ESM4::Cell>().searchCellName(name);
|
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)
|
MWWorld::CellStore* MWWorld::WorldModel::getCell(std::string_view name)
|
||||||
|
@ -134,7 +134,7 @@ namespace DetourNavigator
|
|||||||
|
|
||||||
void NavigatorImpl::addPathgrid(const ESM::Cell& cell, const ESM::Pathgrid& pathgrid)
|
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)
|
for (const auto& edge : pathgrid.mEdges)
|
||||||
{
|
{
|
||||||
const auto src = Misc::Convert::makeOsgVec3f(converter.toWorldPoint(pathgrid.mPoints[edge.mV0]));
|
const auto src = Misc::Convert::makeOsgVec3f(converter.toWorldPoint(pathgrid.mPoints[edge.mV0]));
|
||||||
|
@ -6,17 +6,13 @@ namespace ESM
|
|||||||
{
|
{
|
||||||
const ESM4::Cell& CellVariant::getEsm4() const
|
const ESM4::Cell& CellVariant::getEsm4() const
|
||||||
{
|
{
|
||||||
auto cell4 = std::get<0>(mVariant);
|
auto cell4 = std::get<const ESM4::Cell*>(mVariant);
|
||||||
if (!cell4)
|
|
||||||
throw std::runtime_error("invalid variant acess");
|
|
||||||
return *cell4;
|
return *cell4;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ESM::Cell& CellVariant::getEsm3() const
|
const ESM::Cell& CellVariant::getEsm3() const
|
||||||
{
|
{
|
||||||
auto cell = std::get<1>(mVariant);
|
auto cell = std::get<const ESM::Cell*>(mVariant);
|
||||||
if (!cell)
|
|
||||||
throw std::runtime_error("invalid variant acess");
|
|
||||||
return *cell;
|
return *cell;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,29 +19,20 @@ namespace ESM
|
|||||||
|
|
||||||
struct CellVariant
|
struct CellVariant
|
||||||
{
|
{
|
||||||
std::variant<const ESM4::Cell*, const ESM::Cell*, const void*> mVariant;
|
private:
|
||||||
|
std::variant<const ESM4::Cell*, const ESM::Cell*> mVariant;
|
||||||
|
|
||||||
CellVariant()
|
public:
|
||||||
: mVariant((void*)(nullptr))
|
explicit CellVariant(const ESM4::Cell& cell)
|
||||||
|
: mVariant(&cell)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit CellVariant(const ESM4::Cell* cell)
|
explicit CellVariant(const ESM::Cell& cell)
|
||||||
: mVariant(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); }
|
bool isEsm4() const { return std::holds_alternative<const ESM4::Cell*>(mVariant); }
|
||||||
|
|
||||||
const ESM4::Cell& getEsm4() const;
|
const ESM4::Cell& getEsm4() const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user