Move banner allocations to reduce chance of not freeing a banner id (#11879)

This commit is contained in:
Duncan 2020-06-05 21:05:48 +01:00 committed by GitHub
parent d879c2fba4
commit d145b64ab8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 67 deletions

View File

@ -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;
}

View File

@ -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<LargeSceneryPlaceActionResult>(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<LargeSceneryPlaceActionResult>(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;

View File

@ -342,36 +342,6 @@ public:
return std::make_unique<WallPlaceActionResult>(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<WallPlaceActionResult>(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<WallPlaceActionResult>(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<WallPlaceActionResult>(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<WallPlaceActionResult>(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);