diff --git a/CHANGELOG.md b/CHANGELOG.md index ea44cab4b1..d6138e46d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -152,6 +152,7 @@ Bug #7796: Absorbed enchantments don't restore magicka Bug #7832: Ingredient tooltips show magnitude for Fortify Maximum Magicka effect Bug #7840: First run of the launcher doesn't save viewing distance as the default value + Bug #7841: Editor: "Dirty" water heights are saved in modified CELLs Feature #2566: Handle NAM9 records for manual cell references Feature #3537: Shader-based water ripples Feature #5173: Support for NiFogProperty diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index 245012ce13..b1185a4d33 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -612,7 +612,6 @@ namespace EsmTool } else std::cout << " Map Color: " << Misc::StringUtils::format("0x%08X", mData.mMapColor) << std::endl; - std::cout << " Water Level Int: " << mData.mWaterInt << std::endl; std::cout << " RefId counter: " << mData.mRefNumCounter << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl; } diff --git a/apps/opencs/model/world/nestedcoladapterimp.cpp b/apps/opencs/model/world/nestedcoladapterimp.cpp index 13ae821a77..8b8c7b17be 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.cpp +++ b/apps/opencs/model/world/nestedcoladapterimp.cpp @@ -996,7 +996,10 @@ namespace CSMWorld case 5: { if (isInterior && interiorWater) + { cell.mWater = value.toFloat(); + cell.setHasWaterHeightSub(true); + } else return; // return without saving break; diff --git a/components/esm3/loadcell.cpp b/components/esm3/loadcell.cpp index 829cf9e916..0c37e64f1e 100644 --- a/components/esm3/loadcell.cpp +++ b/components/esm3/loadcell.cpp @@ -118,6 +118,7 @@ namespace ESM bool overriding = !mName.empty(); bool isLoaded = false; mHasAmbi = false; + mHasWaterHeightSub = false; while (!isLoaded && esm.hasMoreSubs()) { esm.getSubName(); @@ -126,13 +127,13 @@ namespace ESM case fourCC("INTV"): int32_t waterl; esm.getHT(waterl); + mHasWaterHeightSub = true; mWater = static_cast(waterl); - mWaterInt = true; break; case fourCC("WHGT"): float waterLevel; esm.getHT(waterLevel); - mWaterInt = false; + mHasWaterHeightSub = true; if (!std::isfinite(waterLevel)) { if (!overriding) @@ -190,25 +191,15 @@ namespace ESM if (mData.mFlags & Interior) { - if (mWaterInt) - { - int32_t water = (mWater >= 0) ? static_cast(mWater + 0.5) : static_cast(mWater - 0.5); - esm.writeHNT("INTV", water); - } - else - { + // Try to avoid saving ambient information when it's unnecessary. + // This is to fix black lighting and flooded water + // in resaved cell records that lack this information. + if (mHasWaterHeightSub) esm.writeHNT("WHGT", mWater); - } - if (mData.mFlags & QuasiEx) esm.writeHNOCRefId("RGNN", mRegion); - else - { - // Try to avoid saving ambient lighting information when it's unnecessary. - // This is to fix black lighting in resaved cell records that lack this information. - if (mHasAmbi) - esm.writeHNT("AMBI", mAmbi, 16); - } + else if (mHasAmbi) + esm.writeHNT("AMBI", mAmbi, 16); } else { @@ -324,7 +315,6 @@ namespace ESM mName.clear(); mRegion = ESM::RefId(); mWater = 0; - mWaterInt = false; mMapColor = 0; mRefNumCounter = 0; @@ -333,6 +323,7 @@ namespace ESM mData.mY = 0; mHasAmbi = true; + mHasWaterHeightSub = true; mAmbi.mAmbient = 0; mAmbi.mSunlight = 0; mAmbi.mFog = 0; diff --git a/components/esm3/loadcell.hpp b/components/esm3/loadcell.hpp index bfabdd58f9..3f16bcca31 100644 --- a/components/esm3/loadcell.hpp +++ b/components/esm3/loadcell.hpp @@ -111,7 +111,7 @@ namespace ESM , mRegion(ESM::RefId()) , mHasAmbi(true) , mWater(0) - , mWaterInt(false) + , mHasWaterHeightSub(false) , mMapColor(0) , mRefNumCounter(0) { @@ -131,7 +131,7 @@ namespace ESM bool mHasAmbi; float mWater; // Water level - bool mWaterInt; + bool mHasWaterHeightSub; int32_t mMapColor; // Counter for RefNums. This is only used during content file editing and has no impact on gameplay. // It prevents overwriting previous refNums, even if they were deleted. @@ -163,6 +163,8 @@ namespace ESM bool hasWater() const { return ((mData.mFlags & HasWater) != 0) || isExterior(); } + void setHasWaterHeightSub(bool hasWater) { mHasWaterHeightSub = hasWater; } + bool hasAmbient() const { return mHasAmbi; } void setHasAmbient(bool hasAmbi) { mHasAmbi = hasAmbi; }