From b71062ce1b19c8cb67d1d5eda2d524c5e275141d Mon Sep 17 00:00:00 2001 From: Olivier Wervers Date: Sat, 18 Apr 2020 13:19:03 +0200 Subject: [PATCH] Fix #6530: Make land tools work consistently on park borders (#11181) Makes all land tools behave the same --- distribution/changelog.txt | 1 + src/openrct2/actions/LandLowerAction.hpp | 18 +++++++++++++++ src/openrct2/actions/LandRaiseAction.hpp | 19 ++++++++++++++++ src/openrct2/actions/WaterLowerAction.hpp | 26 ++++++++++++++++++++++ src/openrct2/actions/WaterRaiseAction.hpp | 27 +++++++++++++++++++++++ src/openrct2/network/Network.cpp | 2 +- src/openrct2/world/Map.cpp | 17 ++++++++++++++ 7 files changed, 109 insertions(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 02924f5701..af76c6ac12 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -4,6 +4,7 @@ - Feature: [#11231] Change shortcut window list order to be more intuitive, and split it into logical sections. - Fix: [#11072] Land and water tools working out of bounds (original bug). - Fix: [#11315] Ride that has never opened is shown as favorite ride of many guests. +- Improved: [#6530] Allow water and land height changes on park borders. 0.2.6 (2020-04-17) ------------------------------------------------------------------------ diff --git a/src/openrct2/actions/LandLowerAction.hpp b/src/openrct2/actions/LandLowerAction.hpp index 6a65a38f93..3372151ecb 100644 --- a/src/openrct2/actions/LandLowerAction.hpp +++ b/src/openrct2/actions/LandLowerAction.hpp @@ -92,6 +92,7 @@ private: } uint8_t maxHeight = map_get_highest_land_height(validRange); + bool withinOwnership = false; for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += COORDS_XY_STEP) { @@ -101,6 +102,15 @@ private: if (surfaceElement == nullptr) continue; + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_in_park(CoordsXY{ x, y })) + { + continue; + } + } + withinOwnership = true; + uint8_t height = surfaceElement->base_height; if (surfaceElement->GetSlope() & TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK) height += 2; @@ -134,6 +144,14 @@ private: } } + if (!withinOwnership) + { + GameActionResult::Ptr ownerShipResult = std::make_unique( + GA_ERROR::DISALLOWED, STR_LAND_NOT_OWNED_BY_PARK); + ownerShipResult->ErrorTitle = STR_CANT_LOWER_LAND_HERE; + return ownerShipResult; + } + // Force ride construction to recheck area _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; diff --git a/src/openrct2/actions/LandRaiseAction.hpp b/src/openrct2/actions/LandRaiseAction.hpp index 8c221f9aeb..11742d12a8 100644 --- a/src/openrct2/actions/LandRaiseAction.hpp +++ b/src/openrct2/actions/LandRaiseAction.hpp @@ -93,6 +93,7 @@ private: } uint8_t minHeight = map_get_lowest_land_height(validRange); + bool withinOwnership = false; for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += COORDS_XY_STEP) { @@ -101,6 +102,16 @@ private: auto* surfaceElement = map_get_surface_element_at(CoordsXY{ x, y }); if (surfaceElement == nullptr) continue; + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_in_park(CoordsXY{ x, y })) + { + continue; + } + } + withinOwnership = true; + uint8_t height = surfaceElement->base_height; if (height > minHeight) @@ -129,6 +140,14 @@ private: } } + if (!withinOwnership) + { + GameActionResult::Ptr ownerShipResult = std::make_unique( + GA_ERROR::DISALLOWED, STR_LAND_NOT_OWNED_BY_PARK); + ownerShipResult->ErrorTitle = STR_CANT_RAISE_LAND_HERE; + return ownerShipResult; + } + // Force ride construction to recheck area _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; diff --git a/src/openrct2/actions/WaterLowerAction.hpp b/src/openrct2/actions/WaterLowerAction.hpp index a403def1ba..e2875323c8 100644 --- a/src/openrct2/actions/WaterLowerAction.hpp +++ b/src/openrct2/actions/WaterLowerAction.hpp @@ -74,6 +74,7 @@ private: uint8_t minHeight = GetLowestHeight(validRange); bool hasChanged = false; + bool withinOwnership = false; for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += COORDS_XY_STEP) { for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += COORDS_XY_STEP) @@ -82,6 +83,15 @@ private: if (surfaceElement == nullptr) continue; + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_in_park(CoordsXY{ x, y })) + { + continue; + } + } + withinOwnership = true; + uint8_t height = surfaceElement->GetWaterHeight() / COORDS_Z_STEP; if (height == 0) continue; @@ -107,6 +117,14 @@ private: } } + if (!withinOwnership) + { + GameActionResult::Ptr ownerShipResult = std::make_unique( + GA_ERROR::DISALLOWED, STR_LAND_NOT_OWNED_BY_PARK); + ownerShipResult->ErrorTitle = STR_CANT_LOWER_WATER_LEVEL_HERE; + return ownerShipResult; + } + if (isExecuting && hasChanged) { audio_play_sound_at_location(SoundId::LayingOutWater, res->Position); @@ -126,6 +144,14 @@ private: { for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += COORDS_XY_STEP) { + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_in_park(CoordsXY{ x, y })) + { + continue; + } + } + auto* surfaceElement = map_get_surface_element_at(CoordsXY{ x, y }); if (surfaceElement == nullptr) continue; diff --git a/src/openrct2/actions/WaterRaiseAction.hpp b/src/openrct2/actions/WaterRaiseAction.hpp index de22d956a2..9e80f02137 100644 --- a/src/openrct2/actions/WaterRaiseAction.hpp +++ b/src/openrct2/actions/WaterRaiseAction.hpp @@ -75,6 +75,7 @@ private: auto maxHeight = GetHighestHeight(validRange) / COORDS_Z_STEP; bool hasChanged = false; + bool withinOwnership = false; for (int32_t y = validRange.GetTop(); y <= validRange.GetBottom(); y += COORDS_XY_STEP) { for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += COORDS_XY_STEP) @@ -82,6 +83,16 @@ private: auto surfaceElement = map_get_surface_element_at(CoordsXY{ x, y }); if (surfaceElement == nullptr) continue; + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_in_park(CoordsXY{ x, y })) + { + continue; + } + } + withinOwnership = true; + uint8_t height = surfaceElement->GetWaterHeight() / COORDS_Z_STEP; if (surfaceElement->base_height > maxHeight) @@ -114,6 +125,14 @@ private: } } + if (!withinOwnership) + { + GameActionResult::Ptr ownerShipResult = std::make_unique( + GA_ERROR::DISALLOWED, STR_LAND_NOT_OWNED_BY_PARK); + ownerShipResult->ErrorTitle = STR_CANT_RAISE_WATER_LEVEL_HERE; + return ownerShipResult; + } + if (isExecuting && hasChanged) { audio_play_sound_at_location(SoundId::LayingOutWater, res->Position); @@ -133,6 +152,14 @@ private: { for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += COORDS_XY_STEP) { + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_in_park(CoordsXY{ x, y })) + { + continue; + } + } + auto* surfaceElement = map_get_surface_element_at(CoordsXY{ x, y }); if (surfaceElement == nullptr) continue; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index ed3873d281..f7fb60004a 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -31,7 +31,7 @@ // This string specifies which version of network stream current build uses. // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "2" +#define NETWORK_STREAM_VERSION "3" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index ec68fecc9e..b0541fc5f1 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -878,8 +878,17 @@ uint8_t map_get_lowest_land_height(const MapRange& range) for (int32_t xi = validRange.GetLeft(); xi <= validRange.GetRight(); xi += COORDS_XY_STEP) { auto* surfaceElement = map_get_surface_element_at(CoordsXY{ xi, yi }); + if (surfaceElement != nullptr && min_height > surfaceElement->base_height) { + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_in_park(CoordsXY{ xi, yi })) + { + continue; + } + } + min_height = surfaceElement->base_height; } } @@ -901,6 +910,14 @@ uint8_t map_get_highest_land_height(const MapRange& range) auto* surfaceElement = map_get_surface_element_at(CoordsXY{ xi, yi }); if (surfaceElement != nullptr) { + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_in_park(CoordsXY{ xi, yi })) + { + continue; + } + } + uint8_t base_height = surfaceElement->base_height; if (surfaceElement->GetSlope() & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP) base_height += 2;