diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 25fda484c5..152e66d807 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -32,7 +32,7 @@ // This string specifies which version of network stream current build uses. // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "16" +#define NETWORK_STREAM_VERSION "17" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/world/TileInspector.cpp b/src/openrct2/world/TileInspector.cpp index 7b30204588..c16d40ef40 100644 --- a/src/openrct2/world/TileInspector.cpp +++ b/src/openrct2/world/TileInspector.cpp @@ -141,6 +141,52 @@ GameActionResult::Ptr tile_inspector_insert_corrupt_at(const CoordsXY& loc, int1 return std::make_unique(); } +static int32_t numLargeScenerySequences(const CoordsXY& loc, const LargeSceneryElement* const largeScenery) +{ + const rct_scenery_entry* const largeEntry = largeScenery->GetEntry(); + const auto* const tiles = largeEntry->large_scenery.tiles; + const auto direction = largeScenery->GetDirection(); + + const auto rotatedFirstTile = CoordsXYZ{ + CoordsXY{ tiles[largeScenery->GetSequenceIndex()].x_offset, tiles[largeScenery->GetSequenceIndex()].y_offset }.Rotate( + direction), + tiles[largeScenery->GetSequenceIndex()].z_offset + }; + + const auto firstTile = CoordsXYZ{ loc, largeScenery->GetBaseZ() } - rotatedFirstTile; + auto numFoundElements = 0; + for (int32_t i = 0; tiles[i].x_offset != -1; i++) + { + const auto rotatedCurrentTile = CoordsXYZ{ CoordsXY{ tiles[i].x_offset, tiles[i].y_offset }.Rotate(direction), + tiles[i].z_offset }; + + const auto currentTile = firstTile + rotatedCurrentTile; + + const TileElement* tileElement = map_get_first_element_at(currentTile); + if (tileElement != nullptr) + { + do + { + if (tileElement->GetType() != TILE_ELEMENT_TYPE_LARGE_SCENERY) + continue; + + if (tileElement->GetDirection() != direction) + continue; + + if (tileElement->AsLargeScenery()->GetSequenceIndex() != i) + continue; + + if (tileElement->GetBaseZ() != currentTile.z) + continue; + + numFoundElements++; + break; + } while (!(tileElement++)->IsLastForTile()); + } + } + return numFoundElements; +} + /** * Forcefully removes an element for a given tile * @param x The x coordinate of the tile @@ -157,6 +203,22 @@ GameActionResult::Ptr tile_inspector_remove_element_at(const CoordsXY& loc, int1 { return std::make_unique(GA_ERROR::UNKNOWN, STR_NONE); } + + auto largeScenery = tileElement->AsLargeScenery(); + if (largeScenery) + { + // Only delete the banner entry if there are no other parts of the large scenery to delete + if (numLargeScenerySequences(loc, largeScenery) == 1) + { + tile_element_remove_banner_entry(tileElement); + } + } + else + { + // Removes any potential banners from the entry + tile_element_remove_banner_entry(tileElement); + } + tile_element_remove(tileElement); map_invalidate_tile_full(loc);