diff --git a/src/openrct2/actions/BannerPlaceAction.hpp b/src/openrct2/actions/BannerPlaceAction.hpp index 8190d75271..5778d4b6b5 100644 --- a/src/openrct2/actions/BannerPlaceAction.hpp +++ b/src/openrct2/actions/BannerPlaceAction.hpp @@ -128,6 +128,13 @@ public: return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); } + rct_scenery_entry* bannerEntry = get_banner_entry(_bannerType); + if (bannerEntry == nullptr) + { + log_error("Invalid banner object type. bannerType = ", _bannerType); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); + } + auto banner = GetBanner(_bannerIndex); if (!banner->IsNull()) { @@ -141,7 +148,7 @@ public: banner->flags = 0; banner->text = {}; banner->text_colour = 2; - banner->type = _bannerType; + banner->type = _bannerType; // Banner must be deleted after this point in an early return banner->colour = _primaryColour; banner->position = TileCoordsXY(_loc); newTileElement->SetType(TILE_ELEMENT_TYPE_BANNER); @@ -157,12 +164,6 @@ public: map_invalidate_tile_full(_loc); map_animation_create(MAP_ANIMATION_TYPE_BANNER, CoordsXYZ{ _loc, bannerElement->GetBaseZ() }); - rct_scenery_entry* bannerEntry = get_banner_entry(_bannerType); - if (bannerEntry == nullptr) - { - log_error("Invalid banner object type. bannerType = ", _bannerType); - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE); - } res->Cost = bannerEntry->banner.price; return res; } diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.hpp b/src/openrct2/actions/LargeSceneryPlaceAction.hpp index ca88b302ab..38eb61090a 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.hpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.hpp @@ -244,36 +244,6 @@ public: res->Position.z = maxHeight; - if (sceneryEntry->large_scenery.scrolling_mode != SCROLLING_MODE_NONE) - { - if (_bannerId == BANNER_INDEX_NULL) - { - log_error("No free banners available"); - return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_BANNERS_IN_GAME); - } - - auto banner = GetBanner(_bannerId); - if (!banner->IsNull()) - { - log_error("No free banners available"); - return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS); - } - - banner->text = {}; - banner->colour = 2; - banner->text_colour = 2; - banner->flags = BANNER_FLAG_IS_LARGE_SCENERY; - banner->type = 0; - banner->position = TileCoordsXY(_loc); - - ride_id_t rideIndex = banner_get_closest_ride_index({ _loc, maxHeight }); - if (rideIndex != RIDE_ID_NULL) - { - banner->ride_index = rideIndex; - banner->flags |= BANNER_FLAG_LINKED_TO_RIDE; - } - } - if (!map_check_free_elements_and_reorganise(totalNumTiles)) { log_error("No free map elements available"); @@ -328,6 +298,37 @@ public: map_invalidate_tile_full(curTile); } + // Allocate banner after all tiles to ensure banner id doesn't need to be freed. + if (sceneryEntry->large_scenery.scrolling_mode != SCROLLING_MODE_NONE) + { + if (_bannerId == BANNER_INDEX_NULL) + { + log_error("No free banners available"); + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_BANNERS_IN_GAME); + } + + auto banner = GetBanner(_bannerId); + if (!banner->IsNull()) + { + log_error("No free banners available"); + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS); + } + + banner->text = {}; + banner->colour = 2; + banner->text_colour = 2; + banner->flags = BANNER_FLAG_IS_LARGE_SCENERY; + banner->type = 0; + banner->position = TileCoordsXY(_loc); + + ride_id_t rideIndex = banner_get_closest_ride_index({ _loc, maxHeight }); + if (rideIndex != RIDE_ID_NULL) + { + banner->ride_index = rideIndex; + banner->flags |= BANNER_FLAG_LINKED_TO_RIDE; + } + } + // Force ride construction to recheck area _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_RECHECK; diff --git a/src/openrct2/actions/WallPlaceAction.hpp b/src/openrct2/actions/WallPlaceAction.hpp index b8993a0a37..b6e7c51553 100644 --- a/src/openrct2/actions/WallPlaceAction.hpp +++ b/src/openrct2/actions/WallPlaceAction.hpp @@ -342,36 +342,6 @@ public: return std::make_unique(GA_ERROR::INVALID_PARAMETERS); } - if (wallEntry->wall.scrolling_mode != SCROLLING_MODE_NONE) - { - if (_bannerId == BANNER_INDEX_NULL) - { - log_error("Banner Index not specified."); - return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_TOO_MANY_BANNERS_IN_GAME); - } - - auto banner = GetBanner(_bannerId); - if (!banner->IsNull()) - { - log_error("No free banners available"); - return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS); - } - - banner->text = {}; - banner->colour = COLOUR_WHITE; - banner->text_colour = COLOUR_WHITE; - banner->flags = BANNER_FLAG_IS_WALL; - banner->type = 0; - banner->position = TileCoordsXY(_loc); - - ride_id_t rideIndex = banner_get_closest_ride_index(targetLoc); - if (rideIndex != RIDE_ID_NULL) - { - banner->ride_index = rideIndex; - banner->flags |= BANNER_FLAG_LINKED_TO_RIDE; - } - } - uint8_t clearanceHeight = targetHeight / COORDS_Z_STEP; if (edgeSlope & (EDGE_SLOPE_UPWARDS | EDGE_SLOPE_DOWNWARDS)) { @@ -393,6 +363,37 @@ public: { return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TILE_ELEMENT_LIMIT_REACHED); } + + if (wallEntry->wall.scrolling_mode != SCROLLING_MODE_NONE) + { + if (_bannerId == BANNER_INDEX_NULL) + { + log_error("Banner Index not specified."); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_TOO_MANY_BANNERS_IN_GAME); + } + + auto banner = GetBanner(_bannerId); + if (!banner->IsNull()) + { + log_error("No free banners available"); + return std::make_unique(GA_ERROR::NO_FREE_ELEMENTS); + } + + banner->text = {}; + banner->colour = COLOUR_WHITE; + banner->text_colour = COLOUR_WHITE; + banner->flags = BANNER_FLAG_IS_WALL; + banner->type = 0; // Banner must be deleted after this point in an early return + banner->position = TileCoordsXY(_loc); + + ride_id_t rideIndex = banner_get_closest_ride_index(targetLoc); + if (rideIndex != RIDE_ID_NULL) + { + banner->ride_index = rideIndex; + banner->flags |= BANNER_FLAG_LINKED_TO_RIDE; + } + } + TileElement* tileElement = tile_element_insert(targetLoc, 0b0000); assert(tileElement != nullptr);