From f95472c70ae07a89259f96b64ea6da9ebc730db0 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 11 Apr 2022 23:18:44 +0100 Subject: [PATCH] Add API for installed objects --- distribution/openrct2.d.ts | 16 +- src/openrct2/scripting/ScriptEngine.cpp | 2 + .../bindings/object/ScInstalledObject.hpp | 189 ++++++++++++++++++ .../scripting/bindings/object/ScObject.hpp | 39 ++-- 4 files changed, 207 insertions(+), 39 deletions(-) create mode 100644 src/openrct2/scripting/bindings/object/ScInstalledObject.hpp diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index f5c95d0255..cf53310bf8 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -1631,7 +1631,7 @@ declare global { /** * The original game or expansion pack this object first appeared in. */ - readonly sourceGame: ObjectSourceGame; + readonly sourceGames: ObjectSourceGame[]; /** * The unique identifier of the object, e.g. "rct2.burgb". @@ -1660,20 +1660,6 @@ declare global { * The name in the user's current language. */ readonly name: string; - - /** - * Attempt to load the object into the current park at the given index for the object type. - * If an object already exists at the given index, that object will be unloaded and this object - * will replace it, providing the object type is the same. - * @param index The index to load the object to. If not provided, an empty slot will be used. - * @returns The index of the loaded object. - */ - load(index?: number): number; - - /** - * Unloads the object, if loaded. - */ - unload(): void; } /** diff --git a/src/openrct2/scripting/ScriptEngine.cpp b/src/openrct2/scripting/ScriptEngine.cpp index d98ec01034..f55c94b143 100644 --- a/src/openrct2/scripting/ScriptEngine.cpp +++ b/src/openrct2/scripting/ScriptEngine.cpp @@ -39,6 +39,7 @@ # include "bindings/network/ScPlayer.hpp" # include "bindings/network/ScPlayerGroup.hpp" # include "bindings/network/ScSocket.hpp" +# include "bindings/object/ScInstalledObject.hpp" # include "bindings/object/ScObject.hpp" # include "bindings/ride/ScRide.hpp" # include "bindings/ride/ScRideStation.hpp" @@ -403,6 +404,7 @@ void ScriptEngine::Initialise() ScDisposable::Register(ctx); ScMap::Register(ctx); ScNetwork::Register(ctx); + ScInstalledObject::Register(ctx); ScObject::Register(ctx); ScSceneryObject::Register(ctx); ScSmallSceneryObject::Register(ctx); diff --git a/src/openrct2/scripting/bindings/object/ScInstalledObject.hpp b/src/openrct2/scripting/bindings/object/ScInstalledObject.hpp new file mode 100644 index 0000000000..eb8178d33b --- /dev/null +++ b/src/openrct2/scripting/bindings/object/ScInstalledObject.hpp @@ -0,0 +1,189 @@ +/***************************************************************************** + * Copyright (c) 2014-2020 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. + *****************************************************************************/ + +#pragma once + +#ifdef ENABLE_SCRIPTING + +# include "../../../Context.h" +# include "../../../common.h" +# include "../../../object/ObjectRepository.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" + +# include + +namespace OpenRCT2::Scripting +{ + inline std::string_view ObjectTypeToString(uint8_t type) + { + static constexpr std::string_view Types[] = { + "ride", + "small_scenery", + "large_scenery", + "wall", + "banner", + "footpath", + "footpath_addition", + "scenery_group", + "park_entrance", + "water", + "stex", + "terrain_surface", + "terrain_edge", + "station", + "music", + "footpath_surface", + "footpath_railings", + }; + if (type >= std::size(Types)) + return "unknown"; + return Types[type]; + } + + inline std::string_view ObjectSourceGameToString(ObjectSourceGame sourceGame) + { + static constexpr std::string_view values[] = { "custom", "wacky_worlds", "time_twister", "openrct2_official", + "rct1", "added_attractions", "loopy_landscapes", "unknown", + "rct2" }; + if (EnumValue(sourceGame) >= std::size(values)) + return "unknown"; + return values[EnumValue(sourceGame)]; + } + + class ScInstalledObject + { + protected: + size_t _index{}; + + public: + ScInstalledObject(size_t index) + : _index(index) + { + } + + static void Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScInstalledObject::path_get, nullptr, "path"); + dukglue_register_property(ctx, &ScInstalledObject::generation_get, nullptr, "generation"); + dukglue_register_property(ctx, &ScInstalledObject::identifier_get, nullptr, "identifier"); + dukglue_register_property(ctx, &ScInstalledObject::type_get, nullptr, "type"); + dukglue_register_property(ctx, &ScInstalledObject::sourceGames_get, nullptr, "sourceGames"); + dukglue_register_property(ctx, &ScInstalledObject::legacyIdentifier_get, nullptr, "legacyIdentifier"); + dukglue_register_property(ctx, &ScInstalledObject::authors_get, nullptr, "authors"); + dukglue_register_property(ctx, &ScInstalledObject::name_get, nullptr, "name"); + } + + private: + std::string path_get() const + { + auto installedObject = GetInstalledObject(); + if (installedObject != nullptr) + { + return installedObject->Path; + } + return {}; + } + + std::string generation_get() const + { + auto installedObject = GetInstalledObject(); + if (installedObject != nullptr) + { + if (installedObject->Generation == ObjectGeneration::DAT) + return "dat"; + else + return "json"; + } + return {}; + } + + std::vector sourceGames_get() const + { + std::vector result; + auto installedObject = GetInstalledObject(); + if (installedObject != nullptr) + { + for (const auto& sourceGame : installedObject->Sources) + { + result.push_back(std::string(ObjectSourceGameToString(sourceGame))); + } + } + return result; + } + + std::string type_get() const + { + auto installedObject = GetInstalledObject(); + if (installedObject != nullptr) + { + return std::string(ObjectTypeToString(EnumValue(installedObject->Type))); + } + return {}; + } + + std::string identifier_get() const + { + auto installedObject = GetInstalledObject(); + if (installedObject != nullptr) + { + return installedObject->Identifier; + } + return {}; + } + + std::string legacyIdentifier_get() const + { + auto installedObject = GetInstalledObject(); + if (installedObject != nullptr) + { + if (!installedObject->ObjectEntry.IsEmpty()) + { + return std::string(installedObject->ObjectEntry.GetName()); + } + } + return {}; + } + + std::vector authors_get() const + { + auto installedObject = GetInstalledObject(); + if (installedObject != nullptr) + { + return installedObject->Authors; + } + return {}; + } + + std::string name_get() const + { + auto installedObject = GetInstalledObject(); + if (installedObject != nullptr) + { + return installedObject->Name; + } + return {}; + } + + const ObjectRepositoryItem* GetInstalledObject() const + { + auto context = GetContext(); + auto& objectRepository = context->GetObjectRepository(); + auto numObjects = objectRepository.GetNumObjects(); + if (_index < numObjects) + { + auto* objects = objectRepository.GetObjects(); + return &objects[_index]; + } + return nullptr; + } + }; +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/object/ScObject.hpp b/src/openrct2/scripting/bindings/object/ScObject.hpp index 589d71c138..974a955175 100644 --- a/src/openrct2/scripting/bindings/object/ScObject.hpp +++ b/src/openrct2/scripting/bindings/object/ScObject.hpp @@ -19,6 +19,7 @@ # include "../../../object/SmallSceneryObject.h" # include "../../Duktape.hpp" # include "../../ScriptEngine.h" +# include "ScInstalledObject.hpp" # include # include @@ -40,6 +41,7 @@ namespace OpenRCT2::Scripting static void Register(duk_context* ctx) { + dukglue_register_property(ctx, &ScObject::installedObject_get, nullptr, "installedObject"); dukglue_register_property(ctx, &ScObject::type_get, nullptr, "type"); dukglue_register_property(ctx, &ScObject::index_get, nullptr, "index"); dukglue_register_property(ctx, &ScObject::identifier_get, nullptr, "identifier"); @@ -62,33 +64,22 @@ namespace OpenRCT2::Scripting return std::nullopt; } - static std::string_view ObjectTypeToString(uint8_t type) + private: + std::shared_ptr installedObject_get() const { - static constexpr std::string_view Types[] = { - "ride", - "small_scenery", - "large_scenery", - "wall", - "banner", - "footpath", - "footpath_addition", - "scenery_group", - "park_entrance", - "water", - "stex", - "terrain_surface", - "terrain_edge", - "station", - "music", - "footpath_surface", - "footpath_railings", - }; - if (type >= std::size(Types)) - return "unknown"; - return Types[type]; + auto obj = GetObject(); + if (obj != nullptr) + { + auto& objectRepository = GetContext()->GetObjectRepository(); + auto installedObject = objectRepository.FindObject(obj->GetIdentifier()); + if (installedObject != nullptr) + { + return std::make_shared(installedObject->Id); + } + } + return {}; } - private: std::string type_get() const { return std::string(ObjectTypeToString(EnumValue(_type)));