From 00c9c07c11672eb830ce7cff3357ac20c806badc Mon Sep 17 00:00:00 2001 From: Duncan Date: Tue, 11 May 2021 14:52:38 +0100 Subject: [PATCH] Fix #14589: Crash in sign window after tileelement reorg (#14626) TileElement pointers must always be revalidated every tick otherwise a tileelement reorg will cause them to point at the wrong element --- src/openrct2-ui/windows/Sign.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/openrct2-ui/windows/Sign.cpp b/src/openrct2-ui/windows/Sign.cpp index c8e81b18af..e83890a7e1 100644 --- a/src/openrct2-ui/windows/Sign.cpp +++ b/src/openrct2-ui/windows/Sign.cpp @@ -59,7 +59,6 @@ class SignWindow final : public Window private: bool _isSmall = false; Banner* _banner = nullptr; - TileElement* _tileElement = nullptr; void ShowTextInput() { @@ -94,24 +93,24 @@ public: return false; auto signViewPosition = _banner->position.ToCoordsXY().ToTileCentre(); - _tileElement = banner_get_tile_element(number); - if (_tileElement == nullptr) + auto* tileElement = banner_get_tile_element(number); + if (tileElement == nullptr) return false; - int32_t viewZ = _tileElement->GetBaseZ(); + int32_t viewZ = tileElement->GetBaseZ(); frame_no = viewZ; if (_isSmall) { - list_information_type = _tileElement->AsWall()->GetPrimaryColour(); - var_492 = _tileElement->AsWall()->GetSecondaryColour(); - SceneryEntry = _tileElement->AsWall()->GetEntryIndex(); + list_information_type = tileElement->AsWall()->GetPrimaryColour(); + var_492 = tileElement->AsWall()->GetSecondaryColour(); + SceneryEntry = tileElement->AsWall()->GetEntryIndex(); } else { - list_information_type = _tileElement->AsLargeScenery()->GetPrimaryColour(); - var_492 = _tileElement->AsLargeScenery()->GetSecondaryColour(); - SceneryEntry = _tileElement->AsLargeScenery()->GetEntryIndex(); + list_information_type = tileElement->AsLargeScenery()->GetPrimaryColour(); + var_492 = tileElement->AsLargeScenery()->GetSecondaryColour(); + SceneryEntry = tileElement->AsLargeScenery()->GetEntryIndex(); } // Create viewport @@ -136,19 +135,24 @@ public: break; case WIDX_SIGN_DEMOLISH: { + auto* tileElement = banner_get_tile_element(number); + if (tileElement == nullptr) + { + Close(); + } auto bannerCoords = _banner->position.ToCoordsXY(); if (_isSmall) { - CoordsXYZD wallLocation = { bannerCoords, _tileElement->GetBaseZ(), _tileElement->GetDirection() }; + CoordsXYZD wallLocation = { bannerCoords, tileElement->GetBaseZ(), tileElement->GetDirection() }; auto wallRemoveAction = WallRemoveAction(wallLocation); GameActions::Execute(&wallRemoveAction); } else { auto sceneryRemoveAction = LargeSceneryRemoveAction( - { bannerCoords, _tileElement->GetBaseZ(), _tileElement->GetDirection() }, - _tileElement->AsLargeScenery()->GetSequenceIndex()); + { bannerCoords, tileElement->GetBaseZ(), tileElement->GetDirection() }, + tileElement->AsLargeScenery()->GetSequenceIndex()); GameActions::Execute(&sceneryRemoveAction); } break;