From cbd4c78cf6e0f39fc996a957acdfba7eeebcecba Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 30 Apr 2023 14:42:22 +0100 Subject: [PATCH] Handle legacy objects correctly --- src/openrct2/object/Object.cpp | 23 +++++++++++++++++++ src/openrct2/object/Object.h | 2 ++ .../bindings/object/ScInstalledObject.hpp | 9 +++++++- .../scripting/bindings/object/ScObject.hpp | 2 +- .../bindings/object/ScObjectManager.cpp | 17 ++++++++++---- 5 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/openrct2/object/Object.cpp b/src/openrct2/object/Object.cpp index d2a0bacfd0..c7a9348dd6 100644 --- a/src/openrct2/object/Object.cpp +++ b/src/openrct2/object/Object.cpp @@ -98,6 +98,29 @@ std::string ObjectEntryDescriptor::ToString() const } } +static uint32_t ParseHex(std::string_view x) +{ + assert(x.size() != 8); + char buffer[9]; + std::memcpy(buffer, x.data(), 8); + buffer[8] = 0; + char* endp{}; + return static_cast(std::strtol(buffer, &endp, 16)); +} + +ObjectEntryDescriptor ObjectEntryDescriptor::Parse(std::string_view identifier) +{ + if (identifier.size() == 26 && identifier[8] == '|' && identifier[17] == '|') + { + RCTObjectEntry entry{}; + entry.flags = ParseHex(identifier.substr(0, 8)); + entry.SetName(identifier.substr(9, 8)); + entry.checksum = ParseHex(identifier.substr(18)); + return ObjectEntryDescriptor(entry); + } + return ObjectEntryDescriptor(identifier); +} + bool ObjectEntryDescriptor::operator==(const ObjectEntryDescriptor& rhs) const { if (Generation != rhs.Generation) diff --git a/src/openrct2/object/Object.h b/src/openrct2/object/Object.h index 21a715628e..36a3886904 100644 --- a/src/openrct2/object/Object.h +++ b/src/openrct2/object/Object.h @@ -143,6 +143,8 @@ struct ObjectEntryDescriptor bool operator==(const ObjectEntryDescriptor& rhs) const; bool operator!=(const ObjectEntryDescriptor& rhs) const; + + static ObjectEntryDescriptor Parse(std::string_view identifier); }; struct IObjectRepository; diff --git a/src/openrct2/scripting/bindings/object/ScInstalledObject.hpp b/src/openrct2/scripting/bindings/object/ScInstalledObject.hpp index eb8178d33b..f722280a38 100644 --- a/src/openrct2/scripting/bindings/object/ScInstalledObject.hpp +++ b/src/openrct2/scripting/bindings/object/ScInstalledObject.hpp @@ -133,7 +133,14 @@ namespace OpenRCT2::Scripting auto installedObject = GetInstalledObject(); if (installedObject != nullptr) { - return installedObject->Identifier; + if (installedObject->Generation == ObjectGeneration::DAT) + { + return ObjectEntryDescriptor(installedObject->ObjectEntry).ToString(); + } + else + { + return installedObject->Identifier; + } } return {}; } diff --git a/src/openrct2/scripting/bindings/object/ScObject.hpp b/src/openrct2/scripting/bindings/object/ScObject.hpp index 974a955175..bd5a47b86a 100644 --- a/src/openrct2/scripting/bindings/object/ScObject.hpp +++ b/src/openrct2/scripting/bindings/object/ScObject.hpp @@ -71,7 +71,7 @@ namespace OpenRCT2::Scripting if (obj != nullptr) { auto& objectRepository = GetContext()->GetObjectRepository(); - auto installedObject = objectRepository.FindObject(obj->GetIdentifier()); + auto installedObject = objectRepository.FindObject(obj->GetDescriptor()); if (installedObject != nullptr) { return std::make_shared(installedObject->Id); diff --git a/src/openrct2/scripting/bindings/object/ScObjectManager.cpp b/src/openrct2/scripting/bindings/object/ScObjectManager.cpp index 6ac67415b1..0e450e219e 100644 --- a/src/openrct2/scripting/bindings/object/ScObjectManager.cpp +++ b/src/openrct2/scripting/bindings/object/ScObjectManager.cpp @@ -1,3 +1,12 @@ +/***************************************************************************** + * 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 "ScObjectManager.h" #include "../../../object/ObjectList.h" @@ -51,7 +60,7 @@ DukValue ScObjectManager::load(const DukValue& p1, const DukValue& p2) throw DukException() << "Expected string for 'identifier'."; const auto& identifier = item.as_string(); - descriptors.emplace_back(identifier); + descriptors.push_back(ObjectEntryDescriptor::Parse(identifier)); } duk_push_array(ctx); @@ -84,7 +93,7 @@ DukValue ScObjectManager::load(const DukValue& p1, const DukValue& p2) throw DukException() << "Expected string for 'identifier'."; const auto& identifier = p1.as_string(); - ObjectEntryDescriptor descriptor(identifier); + auto descriptor = ObjectEntryDescriptor::Parse(identifier); auto installedObject = objectRepository.FindObject(descriptor); if (installedObject != nullptr) @@ -154,7 +163,7 @@ void ScObjectManager::unload(const DukValue& p1, const DukValue& p2) else { // unload(identifier) - objectManager.UnloadObjects({ ObjectEntryDescriptor(szP1) }); + objectManager.UnloadObjects({ ObjectEntryDescriptor::Parse(szP1) }); } } else if (p1.is_array()) @@ -166,7 +175,7 @@ void ScObjectManager::unload(const DukValue& p1, const DukValue& p2) { if (identifier.type() == DukValue::STRING) { - descriptors.emplace_back(identifier.as_string()); + descriptors.push_back(ObjectEntryDescriptor::Parse(identifier.as_string())); } } objectManager.UnloadObjects(descriptors);