mirror of
https://github.com/OpenMW/openmw.git
synced 2025-04-01 22:06:40 +00:00
encapsulations of esm3 cell and esm4 cells.
This commit is contained in:
parent
08b68fcd48
commit
562e129bd0
40 changed files with 292 additions and 162 deletions
|
@ -57,6 +57,8 @@ namespace ESM
|
|||
struct ItemLevList;
|
||||
struct TimeStamp;
|
||||
struct RefId;
|
||||
struct CellVariant;
|
||||
|
||||
}
|
||||
|
||||
namespace MWPhysics
|
||||
|
@ -179,7 +181,7 @@ namespace MWBase
|
|||
///
|
||||
/// \note If cell==0, the cell the player is currently in will be used instead to
|
||||
/// generate a name.
|
||||
virtual std::string_view getCellName(const ESM::Cell* cell) const = 0;
|
||||
virtual std::string_view getCellName(const ESM::CellVariant& cell) const = 0;
|
||||
|
||||
virtual void removeRefScript(MWWorld::RefData* ref) = 0;
|
||||
//< Remove the script attached to ref from mLocalScripts
|
||||
|
|
|
@ -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(cell);
|
||||
dest = world->getCellName(ESM::CellVariant(cell));
|
||||
}
|
||||
|
||||
return "#{sCell=" + std::string{ dest } + "}";
|
||||
|
|
|
@ -705,7 +705,7 @@ namespace MWGui
|
|||
ESM::Position markedPosition;
|
||||
MWBase::Environment::get().getWorld()->getPlayer().getMarkedPosition(markedCell, markedPosition);
|
||||
if (markedCell && markedCell->isExterior() == !mInterior
|
||||
&& (!mInterior || Misc::StringUtils::ciEqual(markedCell->getCell()->mName, mPrefix)))
|
||||
&& (!mInterior || Misc::StringUtils::ciEqual(markedCell->getCell()->getEditorName(), mPrefix)))
|
||||
{
|
||||
MarkerUserData markerPos(mLocalMapRender);
|
||||
MyGUI::ImageBox* markerWidget = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
|
||||
|
|
|
@ -200,7 +200,7 @@ namespace MWGui
|
|||
MWWorld::Ptr player = world->getPlayerPtr();
|
||||
if (mSleeping && player.getCell()->isExterior())
|
||||
{
|
||||
const ESM::RefId& regionstr = player.getCell()->getCell()->mRegion;
|
||||
const ESM::RefId& regionstr = player.getCell()->getCell()->getRegion();
|
||||
if (!regionstr.empty())
|
||||
{
|
||||
const ESM::Region* region = world->getStore().get<ESM::Region>().find(regionstr);
|
||||
|
|
|
@ -954,20 +954,21 @@ namespace MWGui
|
|||
|
||||
mMap->setCellName(name);
|
||||
mHud->setCellName(name);
|
||||
auto cellCommon = cell->getCellVariant().getCommon();
|
||||
|
||||
if (cell->getCell()->isExterior())
|
||||
if (cellCommon->isExterior())
|
||||
{
|
||||
if (!cell->getCell()->mName.empty())
|
||||
mMap->addVisitedLocation(name, cell->getCell()->getGridX(), cell->getCell()->getGridY());
|
||||
if (!cellCommon->getEditorName().empty())
|
||||
mMap->addVisitedLocation(name, cellCommon->getGridX(), cellCommon->getGridY());
|
||||
|
||||
mMap->cellExplored(cell->getCell()->getGridX(), cell->getCell()->getGridY());
|
||||
mMap->cellExplored(cellCommon->getGridX(), cellCommon->getGridY());
|
||||
|
||||
setActiveMap(cell->getCell()->getGridX(), cell->getCell()->getGridY(), false);
|
||||
setActiveMap(cellCommon->getGridX(), cellCommon->getGridY(), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
mMap->setCellPrefix(cell->getCell()->mName);
|
||||
mHud->setCellPrefix(cell->getCell()->mName);
|
||||
mMap->setCellPrefix(std::string(cellCommon->getEditorName()));
|
||||
mHud->setCellPrefix(std::string(cellCommon->getEditorName()));
|
||||
|
||||
osg::Vec3f worldPos;
|
||||
if (!MWBase::Environment::get().getWorld()->findInteriorPositionInWorldSpace(cell, worldPos))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "luabindings.hpp"
|
||||
|
||||
#include <components/esm/cellcommon.hpp>
|
||||
#include <components/esm/records.hpp>
|
||||
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
|
@ -29,35 +30,35 @@ namespace MWLua
|
|||
|
||||
cellT[sol::meta_function::equal_to] = [](const CellT& a, const CellT& b) { return a.mStore == b.mStore; };
|
||||
cellT[sol::meta_function::to_string] = [](const CellT& c) {
|
||||
const ESM::Cell* cell = c.mStore->getCell();
|
||||
auto cell = c.mStore->getCell();
|
||||
std::stringstream res;
|
||||
if (cell->isExterior())
|
||||
res << "exterior(" << cell->getGridX() << ", " << cell->getGridY() << ")";
|
||||
else
|
||||
res << "interior(" << cell->mName << ")";
|
||||
res << "interior(" << cell->getEditorName() << ")";
|
||||
return res.str();
|
||||
};
|
||||
|
||||
cellT["name"] = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->mName; });
|
||||
cellT["name"] = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->getEditorName(); });
|
||||
cellT["region"]
|
||||
= sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->mRegion.getRefIdString(); });
|
||||
= sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->getRegion().getRefIdString(); });
|
||||
cellT["gridX"] = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->getGridX(); });
|
||||
cellT["gridY"] = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->getGridY(); });
|
||||
cellT["hasWater"] = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->hasWater(); });
|
||||
cellT["hasSky"] = sol::readonly_property([](const CellT& c) {
|
||||
return c.mStore->getCell()->isExterior() || (c.mStore->getCell()->mData.mFlags & ESM::Cell::QuasiEx) != 0;
|
||||
return c.mStore->getCell()->isExterior() || (c.mStore->getCell()->isQuasiExterior()) != 0;
|
||||
});
|
||||
cellT["isExterior"] = sol::readonly_property([](const CellT& c) { return c.mStore->isExterior(); });
|
||||
|
||||
// deprecated, use cell:hasTag("QuasiExterior") instead
|
||||
cellT["isQuasiExterior"] = sol::readonly_property(
|
||||
[](const CellT& c) { return (c.mStore->getCell()->mData.mFlags & ESM::Cell::QuasiEx) != 0; });
|
||||
cellT["isQuasiExterior"]
|
||||
= sol::readonly_property([](const CellT& c) { return (c.mStore->getCell()->isQuasiExterior()) != 0; });
|
||||
|
||||
cellT["hasTag"] = [](const CellT& c, std::string_view tag) -> bool {
|
||||
if (tag == "NoSleep")
|
||||
return (c.mStore->getCell()->mData.mFlags & ESM::Cell::NoSleep) != 0;
|
||||
return (c.mStore->getCell()->noSleep()) != 0;
|
||||
else if (tag == "QuasiExterior")
|
||||
return (c.mStore->getCell()->mData.mFlags & ESM::Cell::QuasiEx) != 0;
|
||||
return (c.mStore->getCell()->isQuasiExterior()) != 0;
|
||||
return false;
|
||||
};
|
||||
|
||||
|
|
|
@ -176,12 +176,12 @@ namespace MWLua
|
|||
// TODO: change AiEscort implementation to accept ptr instead of a non-unique refId.
|
||||
const ESM::RefId& refId = target.ptr().getCellRef().getRefId();
|
||||
int gameHoursDuration = static_cast<int>(std::ceil(duration / 3600.0));
|
||||
const ESM::Cell* esmCell = cell.mStore->getCell();
|
||||
const ESM::CellCommon* esmCell = cell.mStore->getCell();
|
||||
if (esmCell->isExterior())
|
||||
ai.stack(MWMechanics::AiEscort(refId, gameHoursDuration, dest.x(), dest.y(), dest.z(), false), ptr);
|
||||
else
|
||||
ai.stack(MWMechanics::AiEscort(
|
||||
refId, esmCell->mName, gameHoursDuration, dest.x(), dest.y(), dest.z(), false),
|
||||
refId, esmCell->getEditorName(), gameHoursDuration, dest.x(), dest.y(), dest.z(), false),
|
||||
ptr);
|
||||
};
|
||||
selfAPI["_startAiWander"] = [](SelfObject& self, int distance, float duration) {
|
||||
|
|
|
@ -274,8 +274,8 @@ namespace MWMechanics
|
|||
.find("fInteriorHeadTrackMult")
|
||||
->mValue.getFloat();
|
||||
float maxDistance = fMaxHeadTrackDistance;
|
||||
const ESM::Cell* currentCell = actor.getCell()->getCell();
|
||||
if (!currentCell->isExterior() && !(currentCell->mData.mFlags & ESM::Cell::QuasiEx))
|
||||
auto currentCell = actor.getCell()->getCell();
|
||||
if (!currentCell->isExterior() && !(currentCell->isQuasiExterior()))
|
||||
maxDistance *= fInteriorHeadTrackMult;
|
||||
|
||||
const osg::Vec3f actor1Pos(actorRefData.getPosition().asVec3());
|
||||
|
|
|
@ -357,12 +357,12 @@ namespace MWMechanics
|
|||
case AiCombatStorage::FleeState_Idle:
|
||||
{
|
||||
float triggerDist = getMaxAttackDistance(target);
|
||||
|
||||
if (storage.mLOS && (triggerDist >= 1000 || getDistanceMinusHalfExtents(actor, target) <= triggerDist))
|
||||
auto cell3 = storage.mCell->getCellVariant().getEsm3();
|
||||
if (cell3 && storage.mLOS
|
||||
&& (triggerDist >= 1000 || getDistanceMinusHalfExtents(actor, target) <= triggerDist))
|
||||
{
|
||||
const ESM::Pathgrid* pathgrid
|
||||
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(
|
||||
*storage.mCell->getCell());
|
||||
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*cell3);
|
||||
|
||||
bool runFallback = true;
|
||||
|
||||
|
|
|
@ -174,7 +174,8 @@ namespace MWMechanics
|
|||
return true;
|
||||
}
|
||||
}
|
||||
else if (Misc::StringUtils::ciEqual(mCellId, actor.getCell()->getCell()->mName)) // Cell to travel to
|
||||
else if (Misc::StringUtils::ciEqual(
|
||||
mCellId, actor.getCell()->getCell()->getEditorName())) // Cell to travel to
|
||||
{
|
||||
mRemainingDuration = mDuration;
|
||||
return true;
|
||||
|
|
|
@ -411,7 +411,7 @@ bool MWMechanics::AiPackage::doesPathNeedRecalc(const osg::Vec3f& newDest, const
|
|||
|
||||
bool MWMechanics::AiPackage::isNearInactiveCell(osg::Vec3f position)
|
||||
{
|
||||
const ESM::Cell* playerCell(getPlayer().getCell()->getCell());
|
||||
const ESM::Cell* playerCell(getPlayer().getCell()->getCellVariant().getEsm3());
|
||||
if (playerCell->isExterior())
|
||||
{
|
||||
// get actor's distance from origin of center cell
|
||||
|
|
|
@ -271,9 +271,10 @@ namespace MWMechanics
|
|||
}
|
||||
|
||||
// Initialization to discover & store allowed node points for this actor.
|
||||
if (storage.mPopulateAvailableNodes)
|
||||
auto cell3 = actor.getCell()->getCellVariant().getEsm3();
|
||||
if (cell3 && storage.mPopulateAvailableNodes)
|
||||
{
|
||||
getAllowedNodes(actor, actor.getCell()->getCell(), storage);
|
||||
getAllowedNodes(actor, cell3, storage);
|
||||
}
|
||||
|
||||
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||
|
@ -721,8 +722,9 @@ namespace MWMechanics
|
|||
return;
|
||||
|
||||
AiWanderStorage& storage = state.get<AiWanderStorage>();
|
||||
if (storage.mPopulateAvailableNodes)
|
||||
getAllowedNodes(actor, actor.getCell()->getCell(), storage);
|
||||
auto cell3 = actor.getCell()->getCellVariant().getEsm3();
|
||||
if (cell3 && storage.mPopulateAvailableNodes)
|
||||
getAllowedNodes(actor, cell3, storage);
|
||||
|
||||
if (storage.mAllowedNodes.empty())
|
||||
return;
|
||||
|
@ -800,8 +802,11 @@ namespace MWMechanics
|
|||
void AiWander::getNeighbouringNodes(
|
||||
ESM::Pathgrid::Point dest, const MWWorld::CellStore* currentCell, ESM::Pathgrid::PointList& points)
|
||||
{
|
||||
auto cell3 = currentCell->getCellVariant().getEsm3();
|
||||
if (!cell3)
|
||||
return;
|
||||
const ESM::Pathgrid* pathgrid
|
||||
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*currentCell->getCell());
|
||||
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*cell3);
|
||||
|
||||
if (pathgrid == nullptr || pathgrid->mPoints.empty())
|
||||
return;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace ESM
|
||||
{
|
||||
struct Cell;
|
||||
struct CellCommon;
|
||||
namespace AiSequence
|
||||
{
|
||||
struct AiWander;
|
||||
|
@ -158,6 +159,8 @@ namespace MWMechanics
|
|||
GroupIndex_MaxIdle = 9
|
||||
};
|
||||
|
||||
/// convert point from local (i.e. cell) to world coordinates
|
||||
void ToWorldCoordinates(ESM::Pathgrid::Point& point, const ESM::CellCommon* cell);
|
||||
void setCurrentNodeToClosestAllowedNode(AiWanderStorage& storage);
|
||||
|
||||
void addNonPathGridAllowedPoints(const ESM::Pathgrid* pathGrid, int pointIndex, AiWanderStorage& storage,
|
||||
|
|
|
@ -104,8 +104,10 @@ namespace MWMechanics
|
|||
if (mIsGraphConstructed)
|
||||
return true;
|
||||
|
||||
mCell = cell->getCell();
|
||||
mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*cell->getCell());
|
||||
mCell = cell->getCellVariant().getEsm3();
|
||||
if (!mCell)
|
||||
return false;
|
||||
mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*mCell);
|
||||
if (!mPathgrid)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -489,7 +489,7 @@ namespace MWMechanics
|
|||
{
|
||||
std::string_view dest;
|
||||
if (!markedCell->isExterior())
|
||||
dest = markedCell->getCell()->mName;
|
||||
dest = markedCell->getCell()->getEditorName();
|
||||
MWWorld::ActionTeleport action(dest, markedPosition, false);
|
||||
action.execute(target);
|
||||
if (!caster.isEmpty())
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include <components/esm/cellcommon.hpp>
|
||||
#include <components/esm3/loadcell.hpp>
|
||||
#include <components/esm4/loadcell.hpp>
|
||||
#include <components/fallback/fallback.hpp>
|
||||
#include <components/sceneutil/util.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
@ -38,13 +40,17 @@ namespace MWRender
|
|||
DLInteriorFogEnd = Settings::Manager::getFloat("distant interior fog end", "Fog");
|
||||
}
|
||||
|
||||
void FogManager::configure(float viewDistance, const ESM::Cell* cell)
|
||||
void FogManager::configure(float viewDistance, const ESM::CellVariant& cell)
|
||||
{
|
||||
osg::Vec4f color = SceneUtil::colourFromRGB(cell->mAmbi.mFog);
|
||||
auto cell3 = cell.getEsm3();
|
||||
auto cell4 = cell.getEsm4();
|
||||
|
||||
osg::Vec4f color = SceneUtil::colourFromRGB(cell3 ? cell3->mAmbi.mFog : cell4->mLighting.fogColor);
|
||||
|
||||
const float fogDensity = cell3 ? cell3->mAmbi.mFogDensity : cell4->mLighting.fogPower;
|
||||
if (mDistantFog)
|
||||
{
|
||||
float density = std::max(0.2f, cell->mAmbi.mFogDensity);
|
||||
float density = std::max(0.2f, fogDensity);
|
||||
mLandFogStart = DLInteriorFogEnd * (1.0f - density) + DLInteriorFogStart * density;
|
||||
mLandFogEnd = DLInteriorFogEnd;
|
||||
mUnderwaterFogStart = DLUnderwaterFogStart;
|
||||
|
@ -52,7 +58,7 @@ namespace MWRender
|
|||
mFogColor = color;
|
||||
}
|
||||
else
|
||||
configure(viewDistance, cell->mAmbi.mFogDensity, mUnderwaterIndoorFog, 1.0f, 0.0f, color);
|
||||
configure(viewDistance, fogDensity, mUnderwaterIndoorFog, 1.0f, 0.0f, color);
|
||||
}
|
||||
|
||||
void FogManager::configure(float viewDistance, float fogDepth, float underwaterFog, float dlFactor, float dlOffset,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
namespace ESM
|
||||
{
|
||||
struct Cell;
|
||||
struct CellVariant;
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
|
@ -15,7 +15,7 @@ namespace MWRender
|
|||
public:
|
||||
FogManager();
|
||||
|
||||
void configure(float viewDistance, const ESM::Cell* cell);
|
||||
void configure(float viewDistance, const ESM::CellVariant& cell);
|
||||
void configure(float viewDistance, float fogDepth, float underwaterFog, float dlFactor, float dlOffset,
|
||||
const osg::Vec4f& color);
|
||||
|
||||
|
|
|
@ -102,7 +102,10 @@ namespace MWRender
|
|||
void Pathgrid::enableCellPathgrid(const MWWorld::CellStore* store)
|
||||
{
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
const ESM::Pathgrid* pathgrid = world->getStore().get<ESM::Pathgrid>().search(*store->getCell());
|
||||
auto cell3 = store->getCellVariant().getEsm3();
|
||||
if (!cell3)
|
||||
return;
|
||||
const ESM::Pathgrid* pathgrid = world->getStore().get<ESM::Pathgrid>().search(*cell3);
|
||||
if (!pathgrid)
|
||||
return;
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include <components/terrain/terraingrid.hpp>
|
||||
|
||||
#include <components/esm3/loadcell.hpp>
|
||||
#include <components/esm4/loadcell.hpp>
|
||||
|
||||
#include <components/debug/debugdraw.hpp>
|
||||
#include <components/detournavigator/navigator.hpp>
|
||||
|
@ -739,14 +740,24 @@ namespace MWRender
|
|||
mSky->setMoonColour(red);
|
||||
}
|
||||
|
||||
void RenderingManager::configureAmbient(const ESM::Cell* cell)
|
||||
void RenderingManager::configureAmbient(const ESM::CellVariant& cell)
|
||||
{
|
||||
bool isInterior = !cell->isExterior() && !(cell->mData.mFlags & ESM::Cell::QuasiEx);
|
||||
bool isInterior = !cell.getCommon()->isExterior() && !cell.getCommon()->isQuasiExterior();
|
||||
bool needsAdjusting = false;
|
||||
if (mResourceSystem->getSceneManager()->getLightingMethod() != SceneUtil::LightingMethod::FFP)
|
||||
needsAdjusting = isInterior;
|
||||
|
||||
auto ambient = SceneUtil::colourFromRGB(cell->mAmbi.mAmbient);
|
||||
osg::Vec4f ambient;
|
||||
auto cell3 = cell.getEsm3();
|
||||
auto cell4 = cell.getEsm4();
|
||||
if (cell3)
|
||||
{
|
||||
ambient = SceneUtil::colourFromRGB(cell3->mAmbi.mAmbient);
|
||||
}
|
||||
else
|
||||
{
|
||||
ambient = SceneUtil::colourFromRGB(cell4->mLighting.ambient);
|
||||
}
|
||||
|
||||
if (needsAdjusting)
|
||||
{
|
||||
|
@ -770,7 +781,9 @@ namespace MWRender
|
|||
|
||||
setAmbientColour(ambient);
|
||||
|
||||
osg::Vec4f diffuse = SceneUtil::colourFromRGB(cell->mAmbi.mSunlight);
|
||||
osg::Vec4f diffuse = cell3 ? SceneUtil::colourFromRGB(cell3->mAmbi.mSunlight)
|
||||
: SceneUtil::colourFromRGB(cell4->mLighting.directional);
|
||||
|
||||
setSunColour(diffuse, diffuse, 1.f);
|
||||
|
||||
const osg::Vec4f interiorSunPos = osg::Vec4f(-0.15f, 0.15f, 1.f, 0.f);
|
||||
|
@ -890,7 +903,7 @@ namespace MWRender
|
|||
return false;
|
||||
}
|
||||
|
||||
void RenderingManager::configureFog(const ESM::Cell* cell)
|
||||
void RenderingManager::configureFog(const ESM::CellVariant& cell)
|
||||
{
|
||||
mFog->configure(mViewDistance, cell);
|
||||
}
|
||||
|
@ -1424,7 +1437,7 @@ namespace MWRender
|
|||
mMinimumAmbientLuminance
|
||||
= std::clamp(Settings::Manager::getFloat("minimum interior brightness", "Shaders"), 0.f, 1.f);
|
||||
if (MWMechanics::getPlayer().isInCell())
|
||||
configureAmbient(MWMechanics::getPlayer().getCell()->getCell());
|
||||
configureAmbient(MWMechanics::getPlayer().getCell()->getCellVariant());
|
||||
}
|
||||
else if (it->first == "Shaders"
|
||||
&& (it->second == "light bounds multiplier" || it->second == "maximum light distance"
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace ESM
|
|||
{
|
||||
struct Cell;
|
||||
struct RefNum;
|
||||
struct CellVariant;
|
||||
}
|
||||
|
||||
namespace Terrain
|
||||
|
@ -140,8 +141,8 @@ namespace MWRender
|
|||
void setSunColour(const osg::Vec4f& diffuse, const osg::Vec4f& specular, float sunVis);
|
||||
void setNight(bool isNight) { mNight = isNight; }
|
||||
|
||||
void configureAmbient(const ESM::Cell* cell);
|
||||
void configureFog(const ESM::Cell* cell);
|
||||
void configureAmbient(const ESM::CellVariant& cell);
|
||||
void configureFog(const ESM::CellVariant& cell);
|
||||
void configureFog(
|
||||
float fogDepth, float underwaterFog, float dlFactor, float dlOffset, const osg::Vec4f& colour);
|
||||
|
||||
|
|
|
@ -772,7 +772,8 @@ namespace MWRender
|
|||
bool wasInterior = mInterior;
|
||||
if (!isInterior)
|
||||
{
|
||||
mWaterNode->setPosition(getSceneNodeCoordinates(store->getCell()->mData.mX, store->getCell()->mData.mY));
|
||||
mWaterNode->setPosition(
|
||||
getSceneNodeCoordinates(store->getCell()->getGridX(), store->getCell()->getGridY()));
|
||||
mInterior = false;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -766,14 +766,14 @@ namespace MWSound
|
|||
{
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
const MWWorld::ConstPtr player = world->getPlayerPtr();
|
||||
const ESM::Cell* cell = player.getCell()->getCell();
|
||||
auto cell = player.getCell()->getCell();
|
||||
|
||||
if (!cell->isExterior())
|
||||
return;
|
||||
if (mCurrentRegionSound && mOutput->isSoundPlaying(mCurrentRegionSound))
|
||||
return;
|
||||
|
||||
if (const auto next = mRegionSoundSelector.getNextRandom(duration, cell->mRegion, *world))
|
||||
if (const auto next = mRegionSoundSelector.getNextRandom(duration, cell->getRegion(), *world))
|
||||
mCurrentRegionSound = playSound(*next, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
|
@ -781,7 +781,7 @@ namespace MWSound
|
|||
{
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
const MWWorld::ConstPtr player = world->getPlayerPtr();
|
||||
const ESM::Cell* curcell = player.getCell()->getCell();
|
||||
const ESM::Cell* curcell = player.getCell()->getCellVariant().getEsm3();
|
||||
const auto update = mWaterSoundUpdater.update(player, *world);
|
||||
|
||||
WaterSoundAction action;
|
||||
|
|
|
@ -505,7 +505,7 @@ namespace MWWorld
|
|||
return false;
|
||||
}
|
||||
|
||||
CellStore::CellStore(CellVariant cell, const MWWorld::ESMStore& esmStore, ESM::ReadersCache& readers)
|
||||
CellStore::CellStore(ESM::CellVariant cell, const MWWorld::ESMStore& esmStore, ESM::ReadersCache& readers)
|
||||
: mStore(esmStore)
|
||||
, mReaders(readers)
|
||||
, mCellVariant(cell)
|
||||
|
@ -526,12 +526,12 @@ namespace MWWorld
|
|||
CellStore::~CellStore() = default;
|
||||
CellStore::CellStore(CellStore&&) = default;
|
||||
|
||||
const ESM::Cell* CellStore::getCell() const
|
||||
const ESM::CellCommon* CellStore::getCell() const
|
||||
{
|
||||
return mCell;
|
||||
return mCellVariant.getCommon();
|
||||
}
|
||||
|
||||
CellVariant CellStore::getCellVariant() const
|
||||
ESM::CellVariant CellStore::getCellVariant() const
|
||||
{
|
||||
return mCellVariant;
|
||||
}
|
||||
|
@ -1087,8 +1087,11 @@ namespace MWWorld
|
|||
auto cell4Left = mCellVariant.getEsm4();
|
||||
auto cell4Right = right.mCellVariant.getEsm4();
|
||||
|
||||
auto cell3Left = mCellVariant.getEsm3();
|
||||
auto cell3Right = right.mCellVariant.getEsm3();
|
||||
|
||||
if (!cell4Left && !cell4Right)
|
||||
return getCell()->getCellId() == right.getCell()->getCellId();
|
||||
return cell3Left->getCellId() == cell3Right->getCellId();
|
||||
else if (cell4Left && cell4Right)
|
||||
return cell4Left->mId == cell4Right->mId;
|
||||
else
|
||||
|
@ -1299,4 +1302,5 @@ namespace MWWorld
|
|||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,11 +9,13 @@
|
|||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <typeinfo>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "cellreflist.hpp"
|
||||
#include "livecellref.hpp"
|
||||
|
||||
#include <components/esm/cellcommon.hpp>
|
||||
#include <components/esm/refid.hpp>
|
||||
#include <components/esm3/fogstate.hpp>
|
||||
#include <components/misc/tuplemeta.hpp>
|
||||
|
@ -49,6 +51,7 @@ namespace ESM
|
|||
struct Static;
|
||||
struct Weapon;
|
||||
struct BodyPart;
|
||||
struct CellCommon;
|
||||
}
|
||||
|
||||
namespace ESM4
|
||||
|
@ -64,39 +67,6 @@ namespace MWWorld
|
|||
class ESMStore;
|
||||
struct CellStoreImp;
|
||||
|
||||
struct CellVariant
|
||||
{
|
||||
std::variant<const ESM4::Cell*, const ESM::Cell*> mVariant;
|
||||
|
||||
CellVariant(const ESM4::Cell* cell)
|
||||
: mVariant(cell)
|
||||
{
|
||||
}
|
||||
|
||||
CellVariant(const ESM::Cell* cell)
|
||||
: mVariant(cell)
|
||||
{
|
||||
}
|
||||
|
||||
bool isEsm4() const { return getEsm4(); }
|
||||
|
||||
const ESM4::Cell* getEsm4() const
|
||||
{
|
||||
auto cell4 = std::get_if<const ESM4::Cell*>(&mVariant);
|
||||
if (cell4)
|
||||
return *cell4;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const ESM::Cell* getEsm3() const
|
||||
{
|
||||
auto cell3 = std::get_if<const ESM::Cell*>(&mVariant);
|
||||
if (cell3)
|
||||
return *cell3;
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
using CellStoreTuple = std::tuple<CellRefList<ESM::Activator>, CellRefList<ESM::Potion>,
|
||||
CellRefList<ESM::Apparatus>, CellRefList<ESM::Armor>, CellRefList<ESM::Book>, CellRefList<ESM::Clothing>,
|
||||
CellRefList<ESM::Container>, CellRefList<ESM::Creature>, CellRefList<ESM::Door>, CellRefList<ESM::Ingredient>,
|
||||
|
@ -129,7 +99,7 @@ namespace MWWorld
|
|||
std::unique_ptr<ESM::FogState> mFogState;
|
||||
|
||||
const ESM::Cell* mCell;
|
||||
CellVariant mCellVariant;
|
||||
ESM::CellVariant mCellVariant;
|
||||
State mState;
|
||||
bool mHasState;
|
||||
std::vector<ESM::RefId> mIds;
|
||||
|
@ -224,12 +194,12 @@ namespace MWWorld
|
|||
}
|
||||
|
||||
/// @param readerList The readers to use for loading of the cell on-demand.
|
||||
CellStore(CellVariant cell, const MWWorld::ESMStore& store, ESM::ReadersCache& readers);
|
||||
CellStore(ESM::CellVariant cell, const MWWorld::ESMStore& store, ESM::ReadersCache& readers);
|
||||
CellStore(CellStore&&);
|
||||
~CellStore();
|
||||
|
||||
const ESM::Cell* getCell() const;
|
||||
CellVariant getCellVariant() const;
|
||||
const ESM::CellCommon* getCell() const;
|
||||
ESM::CellVariant getCellVariant() const;
|
||||
|
||||
std::string_view getEditorName() const;
|
||||
|
||||
|
|
|
@ -317,8 +317,8 @@ namespace MWWorld
|
|||
{
|
||||
if (mActiveCells.find(cell) == mActiveCells.end())
|
||||
return;
|
||||
|
||||
Log(Debug::Info) << "Unloading cell " << cell->getCell()->getDescription();
|
||||
std::string description = cell->getCell()->getDescription();
|
||||
Log(Debug::Info) << "Unloading cell " << description;
|
||||
|
||||
ListAndResetObjectsVisitor visitor;
|
||||
|
||||
|
@ -355,8 +355,12 @@ namespace MWWorld
|
|||
if (cell->getCell()->hasWater())
|
||||
mNavigator.removeWater(osg::Vec2i(cellX, cellY), navigatorUpdateGuard);
|
||||
|
||||
if (const auto pathgrid = mWorld.getStore().get<ESM::Pathgrid>().search(*cell->getCell()))
|
||||
mNavigator.removePathgrid(*pathgrid);
|
||||
auto cell3 = cell->getCellVariant().getEsm3();
|
||||
if (cell3)
|
||||
{
|
||||
if (const auto pathgrid = mWorld.getStore().get<ESM::Pathgrid>().search(*cell3))
|
||||
mNavigator.removePathgrid(*pathgrid);
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getMechanicsManager()->drop(cell);
|
||||
|
||||
|
@ -383,14 +387,11 @@ namespace MWWorld
|
|||
Log(Debug::Info) << "Loading cell " << cell->getEditorName();
|
||||
|
||||
auto cell3 = cell->getCellVariant().getEsm3();
|
||||
int cellX = 0;
|
||||
int cellY = 0;
|
||||
const int cellX = cell->getCellVariant().getCommon()->getGridX();
|
||||
const int cellY = cell->getCellVariant().getCommon()->getGridY();
|
||||
if (cell3 != nullptr)
|
||||
{
|
||||
|
||||
int cellX = cell3->getGridX();
|
||||
int cellY = cell3->getGridY();
|
||||
|
||||
if (cell3->isExterior())
|
||||
{
|
||||
osg::ref_ptr<const ESMTerrain::LandObject> land = mRendering.getLandManager()->getLand(cellX, cellY);
|
||||
|
@ -472,8 +473,10 @@ namespace MWWorld
|
|||
else
|
||||
mPhysics->disableWater();
|
||||
|
||||
if (cell3 && !cell->isExterior() && !(cell3->mData.mFlags & ESM::Cell::QuasiEx))
|
||||
mRendering.configureAmbient(cell3);
|
||||
const auto cellVariant = cell->getCellVariant();
|
||||
|
||||
if (!cell->isExterior() && !cellVariant.getCommon()->isQuasiExterior())
|
||||
mRendering.configureAmbient(cellVariant);
|
||||
|
||||
mPreloader->notifyLoaded(cell);
|
||||
}
|
||||
|
@ -549,7 +552,7 @@ namespace MWWorld
|
|||
|
||||
mNavigator.setWorldspace(
|
||||
Misc::StringUtils::lowerCase(
|
||||
mWorld.getWorldModel().getExterior(playerCellX, playerCellY)->getCell()->mCellId.mWorldspace),
|
||||
mWorld.getWorldModel().getExterior(playerCellX, playerCellY)->getCell()->getCellId().mWorldspace),
|
||||
navigatorUpdateGuard.get());
|
||||
mNavigator.updateBounds(pos, navigatorUpdateGuard.get());
|
||||
|
||||
|
@ -672,7 +675,7 @@ namespace MWWorld
|
|||
|
||||
CellStore* cell = mWorld.getWorldModel().getExterior(it->mData.mX, it->mData.mY);
|
||||
mNavigator.setWorldspace(
|
||||
Misc::StringUtils::lowerCase(cell->getCell()->mCellId.mWorldspace), navigatorUpdateGuard.get());
|
||||
Misc::StringUtils::lowerCase(cell->getCell()->getCellId().mWorldspace), 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());
|
||||
|
@ -730,7 +733,7 @@ namespace MWWorld
|
|||
|
||||
CellStore* cell = mWorld.getWorldModel().getInterior(it->mName);
|
||||
mNavigator.setWorldspace(
|
||||
Misc::StringUtils::lowerCase(cell->getCell()->mCellId.mWorldspace), navigatorUpdateGuard.get());
|
||||
Misc::StringUtils::lowerCase(cell->getCell()->getCellId().mWorldspace), navigatorUpdateGuard.get());
|
||||
ESM::Position position;
|
||||
mWorld.findInteriorPosition(it->mName, position);
|
||||
mNavigator.updateBounds(position.asVec3(), navigatorUpdateGuard.get());
|
||||
|
@ -746,7 +749,7 @@ namespace MWWorld
|
|||
{
|
||||
assert(!(*iter)->getCell()->isExterior());
|
||||
|
||||
if (it->mName == (*iter)->getCell()->mName)
|
||||
if (it->mName == (*iter)->getCell()->getEditorName())
|
||||
{
|
||||
unloadCell(*iter, navigatorUpdateGuard.get());
|
||||
break;
|
||||
|
@ -898,7 +901,7 @@ namespace MWWorld
|
|||
changePlayerCell(cell, position, adjustPlayerPos);
|
||||
|
||||
// adjust fog
|
||||
mRendering.configureFog(mCurrentCell->getCell());
|
||||
mRendering.configureFog(mCurrentCell->getCellVariant());
|
||||
|
||||
// Sky system
|
||||
mWorld.adjustSky();
|
||||
|
@ -914,7 +917,7 @@ namespace MWWorld
|
|||
MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
|
||||
|
||||
MWBase::Environment::get().getWorld()->getPostProcessor()->setExteriorFlag(
|
||||
cell->getCell()->mData.mFlags & ESM::Cell::QuasiEx);
|
||||
cell->getCellVariant().getCommon()->isQuasiExterior());
|
||||
}
|
||||
|
||||
void Scene::changeToExteriorCell(const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
|
||||
|
|
|
@ -704,7 +704,7 @@ namespace MWWorld
|
|||
if (!paused || mFastForward)
|
||||
{
|
||||
// Add new transitions when either the player's current external region changes.
|
||||
if (updateWeatherTime() || updateWeatherRegion(player.getCell()->getCell()->mRegion))
|
||||
if (updateWeatherTime() || updateWeatherRegion(player.getCell()->getCell()->getRegion()))
|
||||
{
|
||||
auto it = mRegions.find(mCurrentRegion);
|
||||
if (it != mRegions.end())
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <components/esm3/loadmgef.hpp>
|
||||
#include <components/esm3/loadregn.hpp>
|
||||
#include <components/esm3/loadstat.hpp>
|
||||
|
||||
#include <components/esm4/loadcell.hpp>
|
||||
#include <components/esm4/loadstat.hpp>
|
||||
|
||||
#include <components/misc/constants.hpp>
|
||||
|
@ -634,18 +634,22 @@ namespace MWWorld
|
|||
{
|
||||
if (!cell)
|
||||
cell = mWorldScene->getCurrentCell();
|
||||
return getCellName(cell->getCell());
|
||||
return getCellName(cell->getCellVariant());
|
||||
}
|
||||
|
||||
std::string_view World::getCellName(const ESM::Cell* cell) const
|
||||
std::string_view World::getCellName(const ESM::CellVariant& cell) const
|
||||
{
|
||||
if (cell)
|
||||
auto cellCommon = cell.getCommon();
|
||||
if (cellCommon)
|
||||
{
|
||||
if (!cell->isExterior() || !cell->mName.empty())
|
||||
return cell->mName;
|
||||
if (!cellCommon->isExterior() || !cellCommon->getEditorName().empty())
|
||||
return cellCommon->getEditorName();
|
||||
|
||||
if (const ESM::Region* region = mStore.get<ESM::Region>().search(cell->mRegion))
|
||||
if (cell.getEsm3())
|
||||
{
|
||||
const ESM::Region* region = mStore.get<ESM::Region>().search(cell.getEsm3()->mRegion);
|
||||
return region->mName;
|
||||
}
|
||||
}
|
||||
|
||||
return mStore.get<ESM::GameSetting>().find("sDefaultCellname")->mValue.getString();
|
||||
|
@ -1139,7 +1143,7 @@ namespace MWWorld
|
|||
{
|
||||
if (!newCell->isExterior())
|
||||
{
|
||||
changeToInteriorCell(newCell->getCell()->mName, pos, false);
|
||||
changeToInteriorCell(newCell->getCell()->getEditorName(), pos, false);
|
||||
removeContainerScripts(getPlayerPtr());
|
||||
}
|
||||
else
|
||||
|
@ -1400,7 +1404,7 @@ namespace MWWorld
|
|||
esmPos.pos[2] = traced.z();
|
||||
std::string_view cell;
|
||||
if (!actor.getCell()->isExterior())
|
||||
cell = actor.getCell()->getCell()->mName;
|
||||
cell = actor.getCell()->getCell()->getEditorName();
|
||||
MWWorld::ActionTeleport(cell, esmPos, false).execute(actor);
|
||||
}
|
||||
}
|
||||
|
@ -1988,10 +1992,7 @@ namespace MWWorld
|
|||
const CellStore* currentCell = mWorldScene->getCurrentCell();
|
||||
if (currentCell)
|
||||
{
|
||||
if (!(currentCell->getCell()->mData.mFlags & ESM::Cell::QuasiEx))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
return currentCell->getCell()->isQuasiExterior();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -2312,7 +2313,7 @@ namespace MWWorld
|
|||
if (!cell)
|
||||
return false;
|
||||
|
||||
if (!(cell->getCell()->hasWater()))
|
||||
if (!(cell->getCellVariant().getCommon()->hasWater()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -2468,8 +2469,7 @@ namespace MWWorld
|
|||
|| isFlying(player))
|
||||
return Rest_PlayerIsInAir;
|
||||
|
||||
if ((currentCell->getCell()->mData.mFlags & ESM::Cell::NoSleep)
|
||||
|| player.getClass().getNpcStats(player).isWerewolf())
|
||||
if (currentCell->getCell()->noSleep() || player.getClass().getNpcStats(player).isWerewolf())
|
||||
return Rest_OnlyWaiting;
|
||||
|
||||
return Rest_Allowed;
|
||||
|
@ -2840,7 +2840,7 @@ namespace MWWorld
|
|||
{
|
||||
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
||||
|
||||
const ESM::Cell* ext = nullptr;
|
||||
const ESM::CellCommon* ext = nullptr;
|
||||
try
|
||||
{
|
||||
ext = mWorldModel.getCell(nameId)->getCell();
|
||||
|
@ -3247,9 +3247,11 @@ namespace MWWorld
|
|||
}
|
||||
else
|
||||
{
|
||||
uint32_t ambient = cell->getCell()->mAmbi.mAmbient;
|
||||
auto cellVariant = cell->getCellVariant();
|
||||
uint32_t ambient = cellVariant.getEsm3() ? cellVariant.getEsm3()->mAmbi.mAmbient
|
||||
: cellVariant.getEsm4()->mLighting.ambient;
|
||||
int ambientTotal = (ambient & 0xff) + ((ambient >> 8) & 0xff) + ((ambient >> 16) & 0xff);
|
||||
return !(cell->getCell()->mData.mFlags & ESM::Cell::NoSleep) && ambientTotal <= 201;
|
||||
return !cell->getCell()->noSleep() && ambientTotal <= 201;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3328,7 +3330,7 @@ namespace MWWorld
|
|||
std::set<std::string_view> nextCells;
|
||||
MWWorld::ConstPtr closestMarker;
|
||||
|
||||
nextCells.insert(ptr.getCell()->getCell()->mName);
|
||||
nextCells.insert(ptr.getCell()->getCell()->getEditorName());
|
||||
while (!nextCells.empty())
|
||||
{
|
||||
currentCells = nextCells;
|
||||
|
@ -3423,7 +3425,7 @@ namespace MWWorld
|
|||
|
||||
std::string_view cellName = "";
|
||||
if (!closestMarker.mCell->isExterior())
|
||||
cellName = closestMarker.mCell->getCell()->mName;
|
||||
cellName = closestMarker.mCell->getCell()->getEditorName();
|
||||
|
||||
MWWorld::ActionTeleport action(cellName, closestMarker.getRefData().getPosition(), false);
|
||||
action.execute(ptr);
|
||||
|
@ -3436,7 +3438,7 @@ namespace MWWorld
|
|||
{
|
||||
mPlayer->setTeleported(false);
|
||||
|
||||
const ESM::RefId& playerRegion = getPlayerPtr().getCell()->getCell()->mRegion;
|
||||
const ESM::RefId& playerRegion = getPlayerPtr().getCell()->getCell()->getRegion();
|
||||
mWeatherManager->playerTeleported(playerRegion, isExterior);
|
||||
}
|
||||
|
||||
|
|
|
@ -269,7 +269,7 @@ namespace MWWorld
|
|||
///
|
||||
/// \note If cell==0, the cell the player is currently in will be used instead to
|
||||
/// generate a name.
|
||||
std::string_view getCellName(const ESM::Cell* cell) const override;
|
||||
std::string_view getCellName(const ESM::CellVariant& cell) const override;
|
||||
|
||||
void removeRefScript(MWWorld::RefData* ref) override;
|
||||
//< Remove the script attached to ref from mLocalScripts
|
||||
|
|
|
@ -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(cell, mStore, mReaders)).first;
|
||||
result = mInteriors.emplace(cell->mName, CellStore(ESM::CellVariant(cell), mStore, mReaders)).first;
|
||||
|
||||
return &result->second;
|
||||
}
|
||||
|
@ -78,7 +78,8 @@ MWWorld::CellStore* MWWorld::WorldModel::getCellStore(const ESM::Cell* cell)
|
|||
|
||||
if (result == mExteriors.end())
|
||||
result = mExteriors
|
||||
.emplace(std::make_pair(cell->getGridX(), cell->getGridY()), CellStore(cell, mStore, mReaders))
|
||||
.emplace(std::make_pair(cell->getGridX(), cell->getGridY()),
|
||||
CellStore(ESM::CellVariant(cell), mStore, mReaders))
|
||||
.first;
|
||||
|
||||
return &result->second;
|
||||
|
@ -185,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(cell, mStore, mReaders)).first;
|
||||
result = mExteriors.emplace(std::make_pair(x, y), CellStore(ESM::CellVariant(cell), mStore, mReaders)).first;
|
||||
}
|
||||
|
||||
if (result->second.getState() != CellStore::State_Loaded)
|
||||
|
@ -207,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(cell, mStore, mReaders)).first;
|
||||
result = mInteriors.emplace(name, CellStore(ESM::CellVariant(cell), mStore, mReaders)).first;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = mInteriors.emplace(name, CellStore(cell4, mStore, mReaders)).first;
|
||||
result = mInteriors.emplace(name, CellStore(ESM::CellVariant(cell4), mStore, mReaders)).first;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,14 +262,14 @@ const ESM::Cell* MWWorld::WorldModel::getESMCellByName(std::string_view name)
|
|||
return cell;
|
||||
}
|
||||
|
||||
MWWorld::CellVariant MWWorld::WorldModel::getCellByName(std::string_view name)
|
||||
ESM::CellVariant MWWorld::WorldModel::getCellByName(std::string_view name)
|
||||
{
|
||||
const ESM::Cell* cellEsm3 = getESMCellByName(name);
|
||||
return cellEsm3;
|
||||
return ESM::CellVariant(cellEsm3);
|
||||
if (!cellEsm3)
|
||||
{
|
||||
const ESM4::Cell* cellESM4 = mStore.get<ESM4::Cell>().searchCellName(name);
|
||||
return cellESM4;
|
||||
return ESM::CellVariant(cellESM4);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace MWWorld
|
|||
WorldModel& operator=(const WorldModel&);
|
||||
|
||||
const ESM::Cell* getESMCellByName(std::string_view name);
|
||||
CellVariant getCellByName(std::string_view name);
|
||||
ESM::CellVariant getCellByName(std::string_view name);
|
||||
|
||||
CellStore* getCellStore(const ESM::Cell* cell);
|
||||
Ptr getPtrAndCache(const ESM::RefId& name, CellStore& cellStore);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <boost/program_options/options_description.hpp>
|
||||
#include <boost/program_options/variables_map.hpp>
|
||||
|
||||
#include <components/esm/defs.hpp>
|
||||
#include <components/esm/records.hpp>
|
||||
#include <components/esm3/esmreader.hpp>
|
||||
#include <components/esm3/esmwriter.hpp>
|
||||
|
@ -316,7 +317,7 @@ static void testRecNameIntCount(const MWWorld::Store<T>& store, const MWWorld::E
|
|||
const unsigned int recordIdCount
|
||||
= std::apply([](auto&&... x) { return (hasSameRecordId(x, T::sRecordId) + ...); }, stores);
|
||||
ASSERT_EQ(recordIdCount, static_cast<unsigned int>(1))
|
||||
<< "The same RecNameInt is used twice ESM::REC_" << MWWorld::getRecNameString(T::sRecordId).toStringView();
|
||||
<< "The same RecNameInt is used twice ESM::REC_" << ESM::getRecNameString(T::sRecordId).toStringView();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ add_component_dir (to_utf8
|
|||
to_utf8
|
||||
)
|
||||
|
||||
add_component_dir(esm attr common defs esmcommon records util luascripts format refid)
|
||||
add_component_dir(esm attr common defs esmcommon records util luascripts format refid cellcommon)
|
||||
|
||||
add_component_dir(fx pass technique lexer widgets stateupdater)
|
||||
|
||||
|
|
15
components/esm/cellcommon.cpp
Normal file
15
components/esm/cellcommon.cpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include <components/esm/cellcommon.hpp>
|
||||
#include <components/esm3/loadcell.hpp>
|
||||
#include <components/esm4/loadcell.hpp>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
const ESM::CellCommon* CellVariant::getCommon() const
|
||||
{
|
||||
auto cell3 = getEsm3();
|
||||
if (cell3)
|
||||
return cell3;
|
||||
else
|
||||
return getEsm4();
|
||||
}
|
||||
}
|
68
components/esm/cellcommon.hpp
Normal file
68
components/esm/cellcommon.hpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
#ifndef COMPONENTS_ESM_CELLCOMMON
|
||||
#define COMPONENTS_ESM_CELLCOMMON
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
|
||||
namespace ESM4
|
||||
{
|
||||
struct Cell;
|
||||
}
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
struct Cell;
|
||||
struct CellId;
|
||||
struct RefId;
|
||||
// Common interface for esm3 and esm4 cells
|
||||
struct CellCommon
|
||||
{
|
||||
virtual int getGridX() const = 0;
|
||||
virtual int getGridY() const = 0;
|
||||
virtual bool isExterior() const = 0;
|
||||
virtual bool isQuasiExterior() const = 0;
|
||||
virtual bool hasWater() const = 0;
|
||||
virtual bool noSleep() const { return false; }
|
||||
virtual const ESM::CellId& getCellId() const = 0;
|
||||
virtual const ESM::RefId& getRegion() const = 0;
|
||||
virtual std::string_view getEditorName() const = 0;
|
||||
virtual std::string getDescription() const = 0;
|
||||
};
|
||||
|
||||
struct CellVariant
|
||||
{
|
||||
std::variant<const ESM4::Cell*, const ESM::Cell*> mVariant;
|
||||
|
||||
explicit CellVariant(const ESM4::Cell* cell)
|
||||
: mVariant(cell)
|
||||
{
|
||||
}
|
||||
|
||||
explicit CellVariant(const ESM::Cell* cell)
|
||||
: mVariant(cell)
|
||||
{
|
||||
}
|
||||
|
||||
bool isEsm4() const { return getEsm4(); }
|
||||
|
||||
const ESM4::Cell* getEsm4() const
|
||||
{
|
||||
auto cell4 = std::get_if<const ESM4::Cell*>(&mVariant);
|
||||
if (cell4)
|
||||
return *cell4;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const ESM::Cell* getEsm3() const
|
||||
{
|
||||
auto cell3 = std::get_if<const ESM::Cell*>(&mVariant);
|
||||
if (cell3)
|
||||
return *cell3;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const ESM::CellCommon* getCommon() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -31,7 +31,7 @@ namespace ESM
|
|||
|
||||
bool operator==(const CellId& left, const CellId& right)
|
||||
{
|
||||
return left.mWorldspace == right.mWorldspace && left.mPaged == right.mPaged
|
||||
return left.mWorld == right.mWorld && left.mWorldspace == right.mWorldspace && left.mPaged == right.mPaged
|
||||
&& (!left.mPaged || (left.mIndex.mX == right.mIndex.mX && left.mIndex.mY == right.mIndex.mY));
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace ESM
|
|||
int mY;
|
||||
};
|
||||
|
||||
ESM::RefId mWorld;
|
||||
std::string mWorldspace;
|
||||
CellIndex mIndex;
|
||||
bool mPaged;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "cellid.hpp"
|
||||
#include "cellref.hpp"
|
||||
#include "components/esm/cellcommon.hpp"
|
||||
#include "components/esm/defs.hpp"
|
||||
#include "components/esm/esmcommon.hpp"
|
||||
#include "components/esm/refid.hpp"
|
||||
|
@ -65,7 +66,7 @@ namespace ESM
|
|||
(using ESMReader::getContext()) and jumping back into place
|
||||
whenever we need to load a given cell.
|
||||
*/
|
||||
struct Cell
|
||||
struct Cell : public CellCommon
|
||||
{
|
||||
constexpr static RecNameInts sRecordId = REC_CELL;
|
||||
|
||||
|
@ -150,13 +151,14 @@ namespace ESM
|
|||
void save(ESMWriter& esm, bool isDeleted = false) const;
|
||||
void saveTempMarker(ESMWriter& esm, int tempCount) const;
|
||||
|
||||
bool isExterior() const { return !(mData.mFlags & Interior); }
|
||||
bool isExterior() const override { return !(mData.mFlags & Interior); }
|
||||
bool isQuasiExterior() const override { return mData.mFlags & QuasiEx; }
|
||||
|
||||
int getGridX() const { return mData.mX; }
|
||||
int getGridX() const override { return mData.mX; }
|
||||
|
||||
int getGridY() const { return mData.mY; }
|
||||
int getGridY() const override { return mData.mY; }
|
||||
|
||||
bool hasWater() const { return ((mData.mFlags & HasWater) != 0) || isExterior(); }
|
||||
bool hasWater() const override { return ((mData.mFlags & HasWater) != 0) || isExterior(); }
|
||||
|
||||
bool hasAmbient() const { return mHasAmbi; }
|
||||
|
||||
|
@ -169,7 +171,7 @@ namespace ESM
|
|||
// exactly.
|
||||
void restore(ESMReader& esm, int iCtx) const;
|
||||
|
||||
std::string getDescription() const;
|
||||
std::string getDescription() const override;
|
||||
///< Return a short string describing the cell (mostly used for debugging/logging purpose)
|
||||
|
||||
/* Get the next reference in this cell, if any. Returns false when
|
||||
|
@ -191,7 +193,10 @@ namespace ESM
|
|||
void blank();
|
||||
///< Set record to default state (does not touch the ID/index).
|
||||
|
||||
const CellId& getCellId() const;
|
||||
const CellId& getCellId() const override;
|
||||
const ESM::RefId& getRegion() const override { return mRegion; }
|
||||
bool noSleep() const override { return mData.mFlags & ESM::Cell::NoSleep; }
|
||||
std::string_view getEditorName() const override { return mName; }
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
// #include "writer.hpp"
|
||||
|
||||
#include <components/esm/refid.hpp>
|
||||
#include <components/misc/algorithm.hpp>
|
||||
|
||||
// TODO: Try loading only EDID and XCLC (along with mFormId, mFlags and mParent)
|
||||
//
|
||||
|
@ -77,6 +78,12 @@ void ESM4::Cell::load(ESM4::Reader& reader)
|
|||
std::uint32_t esmVer = reader.esmVersion();
|
||||
bool isFONV = esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134;
|
||||
|
||||
mCellId.mWorldspace = Misc::StringUtils::lowerCase(mEditorId);
|
||||
mCellId.mWorld = ESM::RefId::sEmpty;
|
||||
mCellId.mIndex.mX = getGridX();
|
||||
mCellId.mIndex.mX = getGridY();
|
||||
mCellId.mPaged = isExterior();
|
||||
|
||||
while (reader.getSubRecordHeader())
|
||||
{
|
||||
const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
|
||||
|
|
|
@ -34,8 +34,10 @@
|
|||
#include "formid.hpp"
|
||||
#include "lighting.hpp"
|
||||
|
||||
#include <components/esm/cellcommon.hpp>
|
||||
#include <components/esm/defs.hpp>
|
||||
#include <components/esm/refid.hpp>
|
||||
#include <components/esm3/cellid.hpp>
|
||||
|
||||
namespace ESM4
|
||||
{
|
||||
|
@ -60,7 +62,7 @@ namespace ESM4
|
|||
|
||||
// Unlike TES3, multiple cells can have the same exterior co-ordinates.
|
||||
// The cells need to be organised under world spaces.
|
||||
struct Cell
|
||||
struct Cell final : public ESM::CellCommon
|
||||
{
|
||||
FormId mParent; // world formId (for grouping cells), from the loading sequence
|
||||
|
||||
|
@ -94,12 +96,24 @@ namespace ESM4
|
|||
|
||||
CellGroup* mCellGroup;
|
||||
|
||||
ESM::CellId mCellId;
|
||||
|
||||
void load(ESM4::Reader& reader);
|
||||
// void save(ESM4::Writer& writer) const;
|
||||
|
||||
void blank();
|
||||
|
||||
static constexpr ESM::RecNameInts sRecordId = ESM::REC_CELL4;
|
||||
|
||||
int getGridX() const override { return mX; }
|
||||
int getGridY() const override { return mY; }
|
||||
bool isExterior() const override { return false; /*unimplemented for now*/ }
|
||||
virtual bool isQuasiExterior() const override { return false; /*unimplemented for now*/ }
|
||||
virtual bool hasWater() const override { return false; /*unimplemented for now*/ }
|
||||
const ESM::CellId& getCellId() const override { return mCellId; }
|
||||
const ESM::RefId& getRegion() const override { return ESM::RefId::sEmpty; }
|
||||
std::string_view getEditorName() const override { return mEditorId; }
|
||||
std::string getDescription() const override { return mEditorId; };
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ namespace Misc
|
|||
{
|
||||
}
|
||||
|
||||
explicit CoordinateConverter(const ESM::Cell* cell)
|
||||
: CoordinateConverter(cell->isExterior(), cell->mData.mX, cell->mData.mY)
|
||||
explicit CoordinateConverter(const ESM::CellCommon* cell)
|
||||
: CoordinateConverter(cell->isExterior(), cell->getGridX(), cell->getGridY())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue