diff --git a/distribution/changelog.txt b/distribution/changelog.txt index e5198e81f1..22a3ca8a08 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -54,6 +54,7 @@ - Fix: [#19379] “No platforms” station style shows platforms on the Junior Roller Coaster. - Fix: [#19380] Startup crash when no sequences are installed and random sequences are enabled. - Fix: [#19391] String corruption caused by an improper buffer handling in ‘GfxWrapString’. +- Fix: [#19434, #19509] Object types added by OpenRCT2 do not get removed when executing ‘remove_unused_objects’. - Fix: [#19475] Cannot increase loan when more than £1000 in debt. - Fix: [#19493] SV4 saves not importing the correct vehicle colours. - Fix: [#19517] Crash when peeps try to exit or enter hacked rides that have no waypoints specified. diff --git a/src/openrct2/EditorObjectSelectionSession.cpp b/src/openrct2/EditorObjectSelectionSession.cpp index e7bd586340..97db7b17c7 100644 --- a/src/openrct2/EditorObjectSelectionSession.cpp +++ b/src/openrct2/EditorObjectSelectionSession.cpp @@ -671,11 +671,13 @@ int32_t EditorRemoveUnusedObjects() { const ObjectRepositoryItem* item = &items[i]; ObjectType objectType = item->Type; - - if (objectType >= ObjectType::SceneryGroup) - { + if (ObjectTypeIsIntransient(objectType)) + continue; + + // These object types require exactly one object to be selected at all times. + // Removing that object can badly break the game state. + if (objectType == ObjectType::ParkEntrance || objectType == ObjectType::Water) continue; - } _numSelectedObjectsForType[EnumValue(objectType)]--; _objectSelectionFlags[i] &= ~ObjectSelectionFlags::Selected; diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 822da7fe62..b86b45e203 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -814,6 +814,7 @@ + diff --git a/src/openrct2/object/ObjectTypes.cpp b/src/openrct2/object/ObjectTypes.cpp new file mode 100644 index 0000000000..e9988e7053 --- /dev/null +++ b/src/openrct2/object/ObjectTypes.cpp @@ -0,0 +1,22 @@ +/***************************************************************************** + * Copyright (c) 2014-2023 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#include "ObjectTypes.h" + +#include + +bool ObjectTypeIsTransient(ObjectType type) +{ + return std::find(TransientObjectTypes.begin(), TransientObjectTypes.end(), type) != std::end(TransientObjectTypes); +} + +bool ObjectTypeIsIntransient(ObjectType type) +{ + return std::find(IntransientObjectTypes.begin(), IntransientObjectTypes.end(), type) != std::end(IntransientObjectTypes); +} diff --git a/src/openrct2/object/ObjectTypes.h b/src/openrct2/object/ObjectTypes.h index 5f6aa2f181..05444663a9 100644 --- a/src/openrct2/object/ObjectTypes.h +++ b/src/openrct2/object/ObjectTypes.h @@ -72,3 +72,9 @@ constexpr std::array TransientObjectTypes = { ObjectType::ParkEntrance, ObjectType::Water, ObjectType::TerrainSurface, ObjectType::TerrainEdge, ObjectType::Station, ObjectType::Music, ObjectType::FootpathSurface, ObjectType::FootpathRailings, }; + +// Object types that cannot be saved in a park file. +constexpr std::array IntransientObjectTypes = { ObjectType::ScenarioText, ObjectType::Audio }; + +bool ObjectTypeIsTransient(ObjectType type); +bool ObjectTypeIsIntransient(ObjectType type);