1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-01 14:09:42 +00:00

Better handling of water levels for exterior cells.

Especially for skyrim and it's weird water level values in exteriors.
If we don't have a valid exterior water level we use the world's water level
This commit is contained in:
florent.teppe 2023-05-05 16:31:31 +02:00
parent 56cb2a83ec
commit 3de08e654f
4 changed files with 21 additions and 3 deletions

View file

@ -2,8 +2,12 @@
#include <components/esm3/loadcell.hpp> #include <components/esm3/loadcell.hpp>
#include <components/esm4/loadcell.hpp> #include <components/esm4/loadcell.hpp>
#include <components/esm4/loadwrld.hpp>
#include <components/misc/algorithm.hpp> #include <components/misc/algorithm.hpp>
#include "../mwbase/environment.hpp"
#include "esmstore.hpp"
namespace MWWorld namespace MWWorld
{ {
Cell::Cell(const ESM4::Cell& cell) Cell::Cell(const ESM4::Cell& cell)
@ -26,6 +30,12 @@ namespace MWWorld
.mFogDensity = 1.f,} .mFogDensity = 1.f,}
,mWaterHeight(cell.mWaterHeight) ,mWaterHeight(cell.mWaterHeight)
{ {
if (isExterior() && mWaterHeight == ESM4::Cell::sInvalidWaterLevel)
{
auto& worldStore = MWBase::Environment::get().getESMStore()->get<ESM4::World>();
const ESM4::World* cellWorld = worldStore.find(mParent);
mWaterHeight = cellWorld->mWaterLevel;
}
} }
Cell::Cell(const ESM::Cell& cell) Cell::Cell(const ESM::Cell& cell)
@ -48,6 +58,8 @@ namespace MWWorld
} }
,mWaterHeight(cell.mWater) ,mWaterHeight(cell.mWater)
{ {
if (isExterior())
mWaterHeight = -1.f;
} }
std::string Cell::getDescription() const std::string Cell::getDescription() const

View file

@ -664,7 +664,7 @@ namespace MWWorld
float CellStore::getWaterLevel() const float CellStore::getWaterLevel() const
{ {
if (isExterior()) if (isExterior())
return -1; return getCell()->getWaterHeight();
return mWaterLevel; return mWaterLevel;
} }

View file

@ -33,6 +33,7 @@
#include <cassert> #include <cassert>
#include <cfloat> // FLT_MAX for gcc #include <cfloat> // FLT_MAX for gcc
#include <iostream> // FIXME: debug only #include <iostream> // FIXME: debug only
#include <limits>
#include <stdexcept> #include <stdexcept>
#include "grouptype.hpp" #include "grouptype.hpp"
@ -41,6 +42,8 @@
#include <components/esm/refid.hpp> #include <components/esm/refid.hpp>
float ESM4::Cell::sInvalidWaterLevel = std::numeric_limits<float>::min();
// TODO: Try loading only EDID and XCLC (along with mFormId, mFlags and mParent) // TODO: Try loading only EDID and XCLC (along with mFormId, mFlags and mParent)
// //
// But, for external cells we may be scanning the whole record since we don't know if there is // But, for external cells we may be scanning the whole record since we don't know if there is
@ -55,7 +58,7 @@ void ESM4::Cell::load(ESM4::Reader& reader)
mId = ESM::RefId::formIdRefId(mFormId); mId = ESM::RefId::formIdRefId(mFormId);
mFlags = reader.hdr().record.flags; mFlags = reader.hdr().record.flags;
mParent = ESM::RefId::formIdRefId(reader.currWorld()); mParent = ESM::RefId::formIdRefId(reader.currWorld());
mWaterHeight = sInvalidWaterLevel;
reader.clearCellGrid(); // clear until XCLC FIXME: somehow do this automatically? reader.clearCellGrid(); // clear until XCLC FIXME: somehow do this automatically?
// Sometimes cell 0,0 does not have an XCLC sub record (e.g. ToddLand 000009BF) // Sometimes cell 0,0 does not have an XCLC sub record (e.g. ToddLand 000009BF)
@ -237,7 +240,8 @@ void ESM4::Cell::load(ESM4::Reader& reader)
throw std::runtime_error("ESM4::CELL::load - Unknown subrecord " + ESM::printName(subHdr.typeId)); throw std::runtime_error("ESM4::CELL::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
} }
} }
if (mWaterHeight > 1e8) // A Bit of a hack for skyrim, there is a value for the cell but it is all wrong.
mWaterHeight = sInvalidWaterLevel;
mReaderContext = reader.getContext(); mReaderContext = reader.getContext();
} }

View file

@ -107,6 +107,8 @@ namespace ESM4
int getGridX() const { return mX; } int getGridX() const { return mX; }
int getGridY() const { return mY; } int getGridY() const { return mY; }
bool isExterior() const { return !(mCellFlags & CELL_Interior); } bool isExterior() const { return !(mCellFlags & CELL_Interior); }
static float sInvalidWaterLevel;
}; };
} }