1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-01 08:09:46 +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/esm4/loadcell.hpp>
#include <components/esm4/loadwrld.hpp>
#include <components/misc/algorithm.hpp>
#include "../mwbase/environment.hpp"
#include "esmstore.hpp"
namespace MWWorld
{
Cell::Cell(const ESM4::Cell& cell)
@ -26,6 +30,12 @@ namespace MWWorld
.mFogDensity = 1.f,}
,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)
@ -48,6 +58,8 @@ namespace MWWorld
}
,mWaterHeight(cell.mWater)
{
if (isExterior())
mWaterHeight = -1.f;
}
std::string Cell::getDescription() const

View file

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

View file

@ -33,6 +33,7 @@
#include <cassert>
#include <cfloat> // FLT_MAX for gcc
#include <iostream> // FIXME: debug only
#include <limits>
#include <stdexcept>
#include "grouptype.hpp"
@ -41,6 +42,8 @@
#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)
//
// 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);
mFlags = reader.hdr().record.flags;
mParent = ESM::RefId::formIdRefId(reader.currWorld());
mWaterHeight = sInvalidWaterLevel;
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)
@ -237,7 +240,8 @@ void ESM4::Cell::load(ESM4::Reader& reader)
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();
}

View file

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