1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 19:13:07 +01:00

Fix #15028, #15042. Crash when placing large scenery (#15043)

* Fix #15028, #15042. Crash when placing large scenery

When the fragmented tile element limit is reached whilst placing a large scenery ghost the game will perform a reorg of the map elements invalidating tile element pointers. As large scenery are multi tiled this can happen mid action invalidating the pointer that was allocated for the first tile element. Large scenery actions pass back the first tile element pointer to the calling function for use with ghost removal. When this pointer is invalid it causes the crash. The ultimate fix for this would be to create an undo function for actions. As an interim the function has been modified to return the first tile height.

* Update changelog
This commit is contained in:
Duncan
2021-07-21 13:01:09 +01:00
committed by GitHub
parent 8b9129d9f3
commit bbef85e752
4 changed files with 5 additions and 6 deletions

View File

@@ -1,5 +1,6 @@
0.3.4+ (in development)
------------------------------------------------------------------------
- Fix: [#15028] Crash when placing large scenery.
- Improved: [#12626] Allow using RCT2 saves to mark RCT Classic (.sea) parks as finished and vice versa.
0.3.4 (2021-07-19)

View File

@@ -2549,9 +2549,7 @@ static money32 try_place_ghost_large_scenery(
gSceneryPlaceRotation = loc.direction;
TileElement* tileElement = lspar->tileElement;
gSceneryGhostPosition = { loc, tileElement->GetBaseZ() };
gSceneryGhostPosition = { loc, lspar->firstTileHeight };
if (lspar->GroundFlags & ELEMENT_IS_UNDERGROUND)
{
// Set underground on

View File

@@ -284,12 +284,12 @@ GameActions::Result::Ptr LargeSceneryPlaceAction::Execute() const
SetNewLargeSceneryElement(*newSceneryElement, tileNum);
map_animation_create(MAP_ANIMATION_TYPE_LARGE_SCENERY, { curTile, zLow });
map_invalidate_tile_full(curTile);
if (tileNum == 0)
{
res->tileElement = newSceneryElement->as<TileElement>();
res->firstTileHeight = zLow;
}
map_invalidate_tile_full(curTile);
}
// Allocate banner after all tiles to ensure banner id doesn't need to be freed.

View File

@@ -22,7 +22,7 @@ public:
LargeSceneryPlaceActionResult(GameActions::Status error, rct_string_id message, uint8_t* args);
uint8_t GroundFlags{ 0 };
TileElement* tileElement = nullptr;
int32_t firstTileHeight{ 0 };
};
DEFINE_GAME_ACTION(LargeSceneryPlaceAction, GameCommand::PlaceLargeScenery, LargeSceneryPlaceActionResult)