From f9a06ae01b0d01a0258a5615aec5fbd5ccaeedac Mon Sep 17 00:00:00 2001 From: Michael Steenbeek <1478678+Gymnasiast@users.noreply.github.com> Date: Fri, 21 Jun 2024 20:50:15 +0200 Subject: [PATCH] Fix #21496: RCT1 scenery hidden after reloading (#22181) --- distribution/changelog.txt | 1 + src/openrct2/world/Scenery.cpp | 69 +++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 22 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 4b9927f87f..2a4fc131f9 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -30,6 +30,7 @@ - Fix: [#13234] Vehicle weight sometimes wrong after using Remove All Guests cheat. - Fix: [#13294] Map corners are cut off in some directions (original bug). - Fix: [#14630] Non-ASCII thousands and decimal separators not processed correctly. +- Fix: [#21496] Some RCT1 scenery is hidden after saving and reloading. - Fix: [#21974] No reason specified when attempting to place benches, lamps, or bins on path with no unconnected edges (original bug). - Fix: [#21987] [Plugin] API cannot handle negative removal prices. - Fix: [#22008] Uninverted Lay-down roller coaster uses the wrong support type. diff --git a/src/openrct2/world/Scenery.cpp b/src/openrct2/world/Scenery.cpp index 86418f2e83..73ed9b9424 100644 --- a/src/openrct2/world/Scenery.cpp +++ b/src/openrct2/world/Scenery.cpp @@ -425,17 +425,26 @@ bool ObjectTypeCanBeRestricted(ObjectType objectType) } } -static std::vector GetAllMiscScenery() +struct MiscScenery { - std::vector miscScenery; - std::vector nonMiscScenery; + // Scenery that will end up on the ‘?’ tab + std::vector miscScenery{}; + // Scenery that has attached itself to an existing group, but is not referenced directly. + std::vector additionalGroupScenery{}; +}; + +static MiscScenery GetAllMiscScenery() +{ + MiscScenery ret; + std::vector referencedBySceneryGroups; std::vector sceneryGroupIds; for (ObjectEntryIndex i = 0; i < MAX_SCENERY_GROUP_OBJECTS; i++) { const auto* sgEntry = OpenRCT2::ObjectManager::GetObjectEntry(i); if (sgEntry != nullptr) { - nonMiscScenery.insert(nonMiscScenery.end(), sgEntry->SceneryEntries.begin(), sgEntry->SceneryEntries.end()); + referencedBySceneryGroups.insert( + referencedBySceneryGroups.end(), sgEntry->SceneryEntries.begin(), sgEntry->SceneryEntries.end()); sceneryGroupIds.emplace_back(i); } } @@ -487,50 +496,66 @@ static std::vector GetAllMiscScenery() break; } - // An object may be link itself against a scenery group, in which case it should not be marked as miscellaneous. + const ScenerySelection sceneryItem = { sceneryType, i }; + if (!IsSceneryEntryValid(sceneryItem)) + continue; + + const bool isReferencedBySceneryGroup = std::find( + std::begin(referencedBySceneryGroups), + std::end(referencedBySceneryGroups), sceneryItem) + != std::end(referencedBySceneryGroups); + if (isReferencedBySceneryGroup) + continue; + + // An object may link itself against a scenery group, in which case it should not be marked as miscellaneous. + bool isLinkedToKnownSceneryGroup = false; if (linkedSceneryGroup != OBJECT_ENTRY_INDEX_NULL) { if (std::find(std::begin(sceneryGroupIds), std::end(sceneryGroupIds), linkedSceneryGroup) != std::end(sceneryGroupIds)) { - continue; + isLinkedToKnownSceneryGroup = true; } } - const ScenerySelection sceneryItem = { sceneryType, i }; - if (IsSceneryEntryValid(sceneryItem)) - { - if (std::find(std::begin(nonMiscScenery), std::end(nonMiscScenery), sceneryItem) == std::end(nonMiscScenery)) - { - miscScenery.push_back(sceneryItem); - } - } + if (isLinkedToKnownSceneryGroup) + ret.additionalGroupScenery.push_back(sceneryItem); + else + ret.miscScenery.push_back(sceneryItem); } } - return miscScenery; + return ret; } void RestrictAllMiscScenery() { auto& gameState = GetGameState(); - auto miscScenery = GetAllMiscScenery(); + auto miscScenery = GetAllMiscScenery().miscScenery; gameState.RestrictedScenery.insert(gameState.RestrictedScenery.begin(), miscScenery.begin(), miscScenery.end()); } -void MarkAllUnrestrictedSceneryAsInvented() +static void MarkAllUnrestrictedSceneryInVectorInvented(const std::vector& vector) { - auto& gameState = GetGameState(); - auto miscScenery = GetAllMiscScenery(); - for (const auto& sceneryItem : miscScenery) + auto& restrictedScenery = GetGameState().RestrictedScenery; + + for (const auto& sceneryItem : vector) { - if (std::find(gameState.RestrictedScenery.begin(), gameState.RestrictedScenery.end(), sceneryItem) - == gameState.RestrictedScenery.end()) + const bool isNotRestricted = std::find(restrictedScenery.begin(), restrictedScenery.end(), sceneryItem) + == restrictedScenery.end(); + if (isNotRestricted) { ScenerySetInvented(sceneryItem); } } } +void MarkAllUnrestrictedSceneryAsInvented() +{ + auto scenery = GetAllMiscScenery(); + MarkAllUnrestrictedSceneryInVectorInvented(scenery.miscScenery); + MarkAllUnrestrictedSceneryInVectorInvented(scenery.additionalGroupScenery); +} + ObjectType GetObjectTypeFromSceneryType(uint8_t type) { switch (type)