From c43a84e255e4c2784010fd3bcb5cfcd196d29262 Mon Sep 17 00:00:00 2001 From: Tulio Leao Date: Sat, 20 Jan 2024 12:25:17 -0300 Subject: [PATCH] Add FixWater capability to ScenarioPatcher --- src/openrct2/rct12/ScenarioPatcher.cpp | 81 +++++++++++++++++++++++++- src/openrct2/rct12/ScenarioPatcher.h | 2 +- 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/openrct2/rct12/ScenarioPatcher.cpp b/src/openrct2/rct12/ScenarioPatcher.cpp index 17814a7ace..7656dea6c5 100644 --- a/src/openrct2/rct12/ScenarioPatcher.cpp +++ b/src/openrct2/rct12/ScenarioPatcher.cpp @@ -108,6 +108,80 @@ static void ApplyLandOwnershipFixes(const json_t& scenarioPatch) } } +static void ApplyWaterFixes(const json_t& scenarioPatch) +{ + constexpr u8string_view waterFixKey = "water"; + if (!scenarioPatch.contains(waterFixKey)) + { + return; + } + + if (!scenarioPatch[waterFixKey].is_array()) + { + Guard::Assert(0, "Water fix should be an array"); + return; + } + + auto waterFixes = Json::AsArray(scenarioPatch[waterFixKey]); + if (waterFixes.empty()) + { + Guard::Assert(0, "Water fix array should not be empty"); + return; + } + + for (size_t i = 0; i < waterFixes.size(); ++i) + { + constexpr u8string_view heightKey = "height"; + if (!waterFixes[i].contains(heightKey)) + { + Guard::Assert(0, "Water fix sub-array should set a height"); + return; + } + + auto waterHeight = waterFixes[i][heightKey]; + + constexpr u8string_view coordinatesKey = "coordinates"; + if (!waterFixes[i].contains(coordinatesKey)) + { + Guard::Assert(0, "Water fix sub-array should contain coordinates"); + return; + } + + if (!waterFixes[i][coordinatesKey].is_array()) + { + Guard::Assert(0, "Water fix coordinates sub-array should be an array"); + return; + } + + auto coordinatesPairs = Json::AsArray(waterFixes[i][coordinatesKey]); + if (coordinatesPairs.empty()) + { + Guard::Assert(0, "Water fix coordinates sub-array should not be empty"); + return; + } + + for (size_t j = 0; j < coordinatesPairs.size(); ++j) + { + if (!coordinatesPairs[j].is_array()) + { + Guard::Assert(0, "Water fix coordinates should contain only arrays"); + return; + } + + auto coordinatesPair = Json::AsArray(coordinatesPairs[j]); + if (coordinatesPair.size() != 2) + { + Guard::Assert(0, "Water fix coordinates sub array should have 2 elements"); + return; + } + auto surfaceElement = MapGetSurfaceElementAt( + TileCoordsXY{ Json::GetNumber(coordinatesPair[0]), Json::GetNumber(coordinatesPair[1]) }); + + surfaceElement->SetWaterHeight(waterHeight); + } + } +} + static u8string GetPatchFileName(u8string_view scenarioName) { auto env = OpenRCT2::GetContext()->GetPlatformEnvironment(); @@ -116,7 +190,7 @@ static u8string GetPatchFileName(u8string_view scenarioName) return Path::Combine(scenarioPatches, scenarioPatchFile); } -void RCT12::FetchAndApplyScenarioPatch(u8string_view scenarioName) +void RCT12::FetchAndApplyScenarioPatch(u8string_view scenarioName, bool isScenario) { auto patchPath = GetPatchFileName(scenarioName); std::cout << "Path is: " << patchPath << std::endl; @@ -124,6 +198,11 @@ void RCT12::FetchAndApplyScenarioPatch(u8string_view scenarioName) if (File::Exists(patchPath)) { auto scenarioPatch = Json::ReadFromFile(patchPath); + // TODO: Land ownership is applied even when loading saved scenario. Should it? ApplyLandOwnershipFixes(scenarioPatch); + if (isScenario) + { + ApplyWaterFixes(scenarioPatch); + } } } \ No newline at end of file diff --git a/src/openrct2/rct12/ScenarioPatcher.h b/src/openrct2/rct12/ScenarioPatcher.h index 28cb9ac1ad..ebf564b9c5 100644 --- a/src/openrct2/rct12/ScenarioPatcher.h +++ b/src/openrct2/rct12/ScenarioPatcher.h @@ -13,5 +13,5 @@ namespace RCT12 { - void FetchAndApplyScenarioPatch(u8string_view scenarioName); + void FetchAndApplyScenarioPatch(u8string_view scenarioName, bool isScenario); }