From 55ebebb869aec2b7888cdfe3a0b472da0125f1ce Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 24 Jan 2021 16:46:16 +0000 Subject: [PATCH] Add title sequence API --- distribution/openrct2.d.ts | 83 ++++++++ src/openrct2-ui/libopenrct2ui.vcxproj | 1 + src/openrct2-ui/scripting/ScTitleSequence.hpp | 182 ++++++++++++++++++ src/openrct2-ui/scripting/UiExtensions.cpp | 5 + 4 files changed, 271 insertions(+) create mode 100644 src/openrct2-ui/scripting/ScTitleSequence.hpp diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index 733310e66d..f944c78d78 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -37,6 +37,11 @@ declare global { var park: Park; /** APIs for the current scenario. */ var scenario: Scenario; + /** + * APIs for creating and editing title sequences. + * These will only be available to clients that are not running headless mode. + */ + var titleSequenceManager: TitleSequenceManager; /** * APIs for controlling the user interface. * These will only be available to servers and clients that are not running headless mode. @@ -2168,4 +2173,82 @@ declare global { off(event: 'error', callback: (hadError: boolean) => void): Socket; off(event: 'data', callback: (data: string) => void): Socket; } + + interface TitleSequence { + /** + * The name of the title sequence. + */ + name: string; + + /** + * The full path of the title sequence. + */ + readonly path: string; + + /** + * Whether the title sequence is a single file or directory. + */ + readonly isDirectory: boolean; + + /** + * Whether or not the title sequence is read-only (e.g. a pre-installed sequence). + */ + readonly isReadOnly: boolean; + + /** + * The parks stored within this title sequence. + */ + parks: string[]; + + /** + * The commands that describe how to play the title sequence. + */ + commands: TitleSequenceCommand[]; + + /** + * Creates a new title sequence identical to this one. + * @param name The name of the new title sequence. + */ + clone(name: string): TitleSequence; + + /** + * Deletes this title sequence from disc. + */ + delete(): void; + } + + type TitleSequenceCommandType = + 'load' | + 'loadsc' | + 'location' | + 'rotate' | + 'zoom' | + 'speed' | + 'follow' | + 'wait' | + 'restart' | + 'end'; + + interface TitleSequenceCommand { + type: TitleSequenceCommandType; + } + + interface LocationTitleSequenceCommand extends TitleSequenceCommand { + type: 'location'; + x: number; + y: number; + } + + interface TitleSequenceManager { + /** + * Gets all the available title sequences. + */ + readonly titleSequences: TitleSequence[]; + + /** + * Creates a new blank title sequence. + * @param name The name of the title sequence. + */ + create(name: string): TitleSequence; + } } diff --git a/src/openrct2-ui/libopenrct2ui.vcxproj b/src/openrct2-ui/libopenrct2ui.vcxproj index 74b08e49ae..54276d1838 100644 --- a/src/openrct2-ui/libopenrct2ui.vcxproj +++ b/src/openrct2-ui/libopenrct2ui.vcxproj @@ -54,6 +54,7 @@ + diff --git a/src/openrct2-ui/scripting/ScTitleSequence.hpp b/src/openrct2-ui/scripting/ScTitleSequence.hpp new file mode 100644 index 0000000000..054153228f --- /dev/null +++ b/src/openrct2-ui/scripting/ScTitleSequence.hpp @@ -0,0 +1,182 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 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 +# include +# include + +namespace OpenRCT2::Scripting +{ + class ScTitleSequence + { + private: + std::string _path; + + public: + ScTitleSequence(const std::string& path) + { + _path = path; + } + + private: + std::string name_get() const + { + const auto* item = GetItem(); + if (item != nullptr) + { + return item->Name; + } + return {}; + } + + void name_set(const std::string& value) + { + auto index = GetManagerIndex(); + if (index) + { + auto newIndex = TitleSequenceManager::RenameItem(*index, value.c_str()); + + // Update path to new value + auto newItem = TitleSequenceManager::GetItem(newIndex); + _path = newItem != nullptr ? newItem->Path : std::string(); + } + } + + std::string path_get() const + { + const auto* item = GetItem(); + if (item != nullptr) + { + return item->Path; + } + return {}; + } + + bool isDirectory_get() const + { + const auto* item = GetItem(); + if (item != nullptr) + { + return !item->IsZip; + } + return {}; + } + + bool isReadOnly_get() const + { + const auto* item = GetItem(); + if (item != nullptr) + { + return item->PredefinedIndex != std::numeric_limits::max(); + } + return {}; + } + + std::shared_ptr clone(const std::string& name) const + { + auto copyIndex = GetManagerIndex(); + if (copyIndex) + { + auto index = TitleSequenceManager::DuplicateItem(*copyIndex, name.c_str()); + auto* item = TitleSequenceManager::GetItem(index); + if (item != nullptr) + { + return std::make_shared(item->Path); + } + } + return nullptr; + } + + void delete_() + { + auto index = GetManagerIndex(); + if (index) + { + TitleSequenceManager::DeleteItem(*index); + } + _path = {}; + } + + public: + static void Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScTitleSequence::name_get, &ScTitleSequence::name_set, "name"); + dukglue_register_property(ctx, &ScTitleSequence::path_get, nullptr, "path"); + dukglue_register_property(ctx, &ScTitleSequence::isDirectory_get, nullptr, "isDirectory"); + dukglue_register_property(ctx, &ScTitleSequence::isReadOnly_get, nullptr, "isReadOnly"); + dukglue_register_method(ctx, &ScTitleSequence::clone, "clone"); + dukglue_register_method(ctx, &ScTitleSequence::delete_, "delete"); + } + + private: + std::optional GetManagerIndex() const + { + auto count = TitleSequenceManager::GetCount(); + for (size_t i = 0; i < count; i++) + { + auto item = TitleSequenceManager::GetItem(i); + if (item != nullptr && item->Path == _path) + { + return i; + } + } + return {}; + } + + const TitleSequenceManagerItem* GetItem() const + { + auto index = GetManagerIndex(); + if (index) + { + return TitleSequenceManager::GetItem(*index); + } + return nullptr; + } + }; + + class ScTitleSequenceManager + { + private: + std::vector> titleSequences_get() const + { + std::vector> result; + auto count = TitleSequenceManager::GetCount(); + for (size_t i = 0; i < count; i++) + { + const auto& path = TitleSequenceManager::GetItem(i)->Path; + result.push_back(std::make_shared(path)); + } + return result; + } + + std::shared_ptr create(const std::string& name) + { + auto index = TitleSequenceManager::CreateItem(name.c_str()); + auto* item = TitleSequenceManager::GetItem(index); + if (item != nullptr) + { + return std::make_shared(item->Path); + } + return nullptr; + } + + public: + static void Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScTitleSequenceManager::titleSequences_get, nullptr, "titleSequences"); + dukglue_register_method(ctx, &ScTitleSequenceManager::create, "create"); + } + }; +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2-ui/scripting/UiExtensions.cpp b/src/openrct2-ui/scripting/UiExtensions.cpp index 0361b58f1d..f97c58f653 100644 --- a/src/openrct2-ui/scripting/UiExtensions.cpp +++ b/src/openrct2-ui/scripting/UiExtensions.cpp @@ -13,6 +13,7 @@ # include "CustomMenu.h" # include "ScTileSelection.hpp" +# include "ScTitleSequence.hpp" # include "ScUi.hpp" # include "ScWidget.hpp" # include "ScWindow.hpp" @@ -25,6 +26,7 @@ void UiScriptExtensions::Extend(ScriptEngine& scriptEngine) { auto ctx = scriptEngine.GetContext(); + dukglue_register_global(ctx, std::make_shared(), "titleSequenceManager"); dukglue_register_global(ctx, std::make_shared(scriptEngine), "ui"); ScTileSelection::Register(ctx); @@ -43,6 +45,9 @@ void UiScriptExtensions::Extend(ScriptEngine& scriptEngine) ScSpinnerWidget::Register(ctx); ScTextBoxWidget::Register(ctx); ScViewportWidget::Register(ctx); + + ScTitleSequence::Register(ctx); + ScTitleSequenceManager::Register(ctx); ScWindow::Register(ctx); InitialiseCustomMenuItems(scriptEngine);