mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 19:13:07 +01:00
* 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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user