From af167552fba7a4c65a8033af4617d860287f043f Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 10 Aug 2022 23:47:13 +0200 Subject: [PATCH] Add flag to mark an object as a compatibility object --- data/language/en-GB.txt | 2 ++ .../windows/EditorObjectSelection.cpp | 20 +++++++++++++++++-- src/openrct2/EditorObjectSelectionSession.cpp | 5 +++++ src/openrct2/localisation/StringIds.h | 3 +++ src/openrct2/object/Object.cpp | 9 +++++++++ src/openrct2/object/Object.h | 4 ++++ src/openrct2/object/ObjectFactory.cpp | 1 + src/openrct2/object/ObjectRepository.cpp | 3 +++ src/openrct2/object/ObjectRepository.h | 6 ++++++ 9 files changed, 51 insertions(+), 2 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index b42f73fc88..2838b84003 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3650,6 +3650,8 @@ STR_6545 :Use RCT1 interest calculation STR_6546 :Use the interest calculation algorithm of RollerCoaster Tycoon 1, which used a fixed percentage of approximately 1.33%. STR_6547 :All Scenery STR_6548 :Show railings at junction +STR_6549 :Compatibility objects cannot be selected! +STR_6550 :This entry is included for backwards compatibility with old or damaged objects. It cannot be selected, only deselected. ############# # Scenarios # diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index 2c8ea108b1..bb5448b0e1 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -1130,7 +1130,8 @@ private: uint8_t selectionFlags = _objectSelectionFlags[i]; const ObjectRepositoryItem* item = &items[i]; if (item->Type == GetSelectedObjectType() && !(selectionFlags & ObjectSelectionFlags::Flag6) && FilterSource(item) - && FilterString(*item) && FilterChunks(item) && FilterSelected(selectionFlags)) + && FilterString(*item) && FilterChunks(item) && FilterSelected(selectionFlags) + && FilterCompatibilityObject(*item, selectionFlags)) { auto filter = std::make_unique(); filter->category[0] = 0; @@ -1188,6 +1189,14 @@ private: auto screenPos = windowPos + ScreenCoordsXY{ widgets[WIDX_LIST].right + 4, widget.bottom + 23 }; auto _width2 = windowPos.x + this->width - screenPos.x - 4; + if (_loadedObject->IsCompatibilityObject()) + { + screenPos.y += DrawTextWrapped( + *dpi, screenPos, _width2, STR_OBJECT_SELECTION_COMPAT_OBJECT_DESCRIPTION, {}, + { COLOUR_BRIGHT_RED }) + + LIST_ROW_HEIGHT; + } + auto description = ObjectGetDescription(_loadedObject.get()); if (!description.empty()) { @@ -1327,6 +1336,12 @@ private: return false; } + bool FilterCompatibilityObject(const ObjectRepositoryItem& item, uint8_t objectFlag) + { + // Only show compat objects if they are not selected already. + return !(item.Flags & ObjectItemFlags::IsCompatibilityObject) || (objectFlag & ObjectSelectionFlags::Selected); + } + static bool IsFilterInName(const ObjectRepositoryItem& item, std::string_view filter) { return String::Contains(item.Name, filter, true); @@ -1436,7 +1451,8 @@ private: for (size_t i = 0; i < numObjects; i++) { const ObjectRepositoryItem* item = &items[i]; - if (FilterSource(item) && FilterString(*item) && FilterChunks(item) && FilterSelected(selectionFlags[i])) + if (FilterSource(item) && FilterString(*item) && FilterChunks(item) && FilterSelected(selectionFlags[i]) + && FilterCompatibilityObject(*item, selectionFlags[i])) { _filter_object_counts[EnumValue(item->Type)]++; } diff --git a/src/openrct2/EditorObjectSelectionSession.cpp b/src/openrct2/EditorObjectSelectionSession.cpp index 64381637e2..4cbd84ddc8 100644 --- a/src/openrct2/EditorObjectSelectionSession.cpp +++ b/src/openrct2/EditorObjectSelectionSession.cpp @@ -566,6 +566,11 @@ ResultWithMessage WindowEditorObjectSelectionSelectObject( return { true }; } + if (item->Flags & ObjectItemFlags::IsCompatibilityObject) + { + return ObjectSelectionError(isMasterObject, STR_OBJECT_SELECTION_ERR_COMPAT_OBJECT); + } + ObjectType objectType = item->Type; uint16_t maxObjects = object_entry_group_counts[EnumValue(objectType)]; diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index c1437a1eb0..4e1793e5e2 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3947,6 +3947,9 @@ enum : uint16_t STR_TILE_INSPECTOR_PATH_JUNCTION_RAILINGS = 6548, + STR_OBJECT_SELECTION_ERR_COMPAT_OBJECT = 6549, + STR_OBJECT_SELECTION_COMPAT_OBJECT_DESCRIPTION = 6550, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working /* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings }; diff --git a/src/openrct2/object/Object.cpp b/src/openrct2/object/Object.cpp index 279cb59817..3dc6a3cf7f 100644 --- a/src/openrct2/object/Object.cpp +++ b/src/openrct2/object/Object.cpp @@ -198,6 +198,15 @@ void Object::SetAuthors(std::vector&& authors) _authors = std::move(authors); } +bool Object::IsCompatibilityObject() const +{ + return _isCompatibilityObject; +} +void Object::SetIsCompatibilityObject(const bool on) +{ + _isCompatibilityObject = on; +} + bool RCTObjectEntry::IsEmpty() const { uint64_t a, b; diff --git a/src/openrct2/object/Object.h b/src/openrct2/object/Object.h index bdc23c8787..f0224b3287 100644 --- a/src/openrct2/object/Object.h +++ b/src/openrct2/object/Object.h @@ -195,6 +195,7 @@ private: std::vector _authors; ObjectGeneration _generation{}; bool _usesFallbackImages{}; + bool _isCompatibilityObject{}; protected: StringTable& GetStringTable() @@ -310,6 +311,9 @@ public: _version = version; } + bool IsCompatibilityObject() const; + void SetIsCompatibilityObject(const bool on); + const ImageTable& GetImageTable() const { return _imageTable; diff --git a/src/openrct2/object/ObjectFactory.cpp b/src/openrct2/object/ObjectFactory.cpp index 368ac849a2..d48fd9289a 100644 --- a/src/openrct2/object/ObjectFactory.cpp +++ b/src/openrct2/object/ObjectFactory.cpp @@ -563,6 +563,7 @@ namespace ObjectFactory } } result->SetAuthors(std::move(authorVector)); + result->SetIsCompatibilityObject(Json::GetBoolean(jRoot["isCompatibilityObject"])); ExtractSourceGames(id, jRoot, *result); } diff --git a/src/openrct2/object/ObjectRepository.cpp b/src/openrct2/object/ObjectRepository.cpp index 840242ea2d..9c3147e6b2 100644 --- a/src/openrct2/object/ObjectRepository.cpp +++ b/src/openrct2/object/ObjectRepository.cpp @@ -126,6 +126,8 @@ public: item.Name = object->GetName(); item.Authors = object->GetAuthors(); item.Sources = object->GetSourceGames(); + if (object->IsCompatibilityObject()) + item.Flags |= ObjectItemFlags::IsCompatibilityObject; object->SetRepositoryItem(&item); return item; } @@ -144,6 +146,7 @@ protected: ds << item.Sources; ds << item.Authors; + ds << item.Flags; switch (item.Type) { diff --git a/src/openrct2/object/ObjectRepository.h b/src/openrct2/object/ObjectRepository.h index 659516d523..d810dc6fa4 100644 --- a/src/openrct2/object/ObjectRepository.h +++ b/src/openrct2/object/ObjectRepository.h @@ -34,6 +34,11 @@ namespace OpenRCT2::Localisation struct DrawPixelInfo; +enum ObjectItemFlags : uint8_t +{ + IsCompatibilityObject = 1, +}; + struct ObjectRepositoryItem { size_t Id; @@ -46,6 +51,7 @@ struct ObjectRepositoryItem ObjectVersion Version; std::vector Authors; std::vector Sources; + uint8_t Flags{}; std::shared_ptr LoadedObject{}; struct {