diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index 4c96804d33..bc4c716fef 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -33,16 +33,49 @@ export interface Context { * The user's current configuration. */ configuration: Configuration; + + /** + * Registers a new intent (command) that can be mapped to a shortcut. + */ + registerIntent(desc: IntentDesc); + /** * Subscribes to the given hook. */ subscribe(hook: string, callback: Function): IDisposable; } +export interface IntentDesc +{ + key: string; + title?: string; + shortcut?: string; + action: Function; +} + export interface IDisposable { dispose(): void; } +export type TileElementType = + "surface" | "footpath-item"; + +export interface TileElement { + type: TileElementType; + zBase: number; + zClearance: number; + + // footpath-item: + broken: boolean; +} + +export interface Tile { + x: number; + y: number; + type: TileType; + elements: TileElement[]; +} + export interface Ride { name: string; excitement: number; @@ -51,8 +84,28 @@ export interface Ride { totalCustomers: number; } +export type TileElementType = + "car" | "duck" | "peep"; + +export interface Thing { + type: ThingType; + x: number; + y: number; + z: number; + + // Peep + tshirt: number; + trousers: number; +} + export interface Map { + size: { x: number; y: number; }; + rides: number; + things: number; + getRide(id: number): Ride; + getTile(x: number, y: number): Tile; + getThing(id: number): Thing; } export type ParkMessageType = diff --git a/src/openrct2/scripting/Plugin.cpp b/src/openrct2/scripting/Plugin.cpp index 8ab7954dd3..201749ec57 100644 --- a/src/openrct2/scripting/Plugin.cpp +++ b/src/openrct2/scripting/Plugin.cpp @@ -55,7 +55,7 @@ Plugin::~Plugin() void Plugin::Load() { - std::string projectedVariables = "console,park"; + std::string projectedVariables = "console,context,map,park"; std::string code; { std::ifstream fs(_path); diff --git a/src/openrct2/scripting/ScContext.hpp b/src/openrct2/scripting/ScContext.hpp index c533cab3ed..864979054c 100644 --- a/src/openrct2/scripting/ScContext.hpp +++ b/src/openrct2/scripting/ScContext.hpp @@ -22,6 +22,10 @@ namespace OpenRCT2::Scripting { } + void registerIntent(const DukValue& desc) + { + } + std::shared_ptr subscribe(const std::string &hook, const DukValue &callback) { auto hookType = GetHookType(hook); @@ -51,6 +55,7 @@ namespace OpenRCT2::Scripting static void Register(duk_context * ctx) { + dukglue_register_method(ctx, &ScContext::registerIntent, "registerIntent"); dukglue_register_method(ctx, &ScContext::subscribe, "subscribe"); } }; diff --git a/src/openrct2/scripting/ScMap.hpp b/src/openrct2/scripting/ScMap.hpp new file mode 100644 index 0000000000..c4f69e16ae --- /dev/null +++ b/src/openrct2/scripting/ScMap.hpp @@ -0,0 +1,64 @@ +#pragma once + +#include +#include "../common.h" +#include "../ride/Ride.h" +#include "../world/Map.h" +#include "ScThing.hpp" + +namespace OpenRCT2::Scripting +{ + class ScMap + { + private: + duk_context * _context; + + public: + ScMap(duk_context * ctx) + : _context(ctx) + { + } + + DukValue size_get() + { + auto ctx = _context; + auto objIdx = duk_push_object(ctx); + duk_push_number(ctx, gMapSize); + duk_put_prop_string(ctx, objIdx, "x"); + duk_push_number(ctx, gMapSize); + duk_put_prop_string(ctx, objIdx, "y"); + return DukValue::take_from_stack(ctx); + } + + sint32 rides_get() + { + return MAX_RIDES; + } + + sint32 things_get() + { + return MAX_SPRITES; + } + + std::shared_ptr getThing(sint32 id) + { + if (id >= 0 && id < MAX_SPRITES) + { + auto sprite = get_sprite(id); + if (sprite != nullptr && sprite->unknown.sprite_identifier != SPRITE_IDENTIFIER_NULL) + { + return std::make_shared(sprite); + } + } + return nullptr; + } + + static void Register(duk_context * ctx) + { + dukglue_register_property(ctx, &ScMap::size_get, nullptr, "size"); + dukglue_register_property(ctx, &ScMap::rides_get, nullptr, "rides"); + dukglue_register_property(ctx, &ScMap::things_get, nullptr, "things"); + dukglue_register_method(ctx, &ScMap::getThing, "getThing"); + } + }; +} diff --git a/src/openrct2/scripting/ScThing.hpp b/src/openrct2/scripting/ScThing.hpp new file mode 100644 index 0000000000..980ce1d2b2 --- /dev/null +++ b/src/openrct2/scripting/ScThing.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include +#include "../common.h" +#include "../world/Sprite.h" + +namespace OpenRCT2::Scripting +{ + class ScThing + { + private: + rct_sprite * _sprite; + + public: + ScThing(rct_sprite * sprite) + : _sprite(sprite) + { + } + + std::string type_get() + { + if (_sprite->unknown.sprite_identifier == SPRITE_IDENTIFIER_PEEP) + { + return "peep"; + } + return "unknown"; + } + + sint32 x_get() { return _sprite->unknown.x; } + sint32 y_get() { return _sprite->unknown.y; } + sint32 z_get() { return _sprite->unknown.z; } + + uint8 tshirtColour_get() { return _sprite->peep.tshirt_colour; } + void tshirtColour_set(uint8 value) { _sprite->peep.tshirt_colour = value; } + uint8 trousersColour_get() { return _sprite->peep.trousers_colour; } + void trousersColour_set(uint8 value) { _sprite->peep.trousers_colour = value; } + + static void Register(duk_context * ctx) + { + dukglue_register_property(ctx, &ScThing::type_get, nullptr, "type"); + dukglue_register_property(ctx, &ScThing::x_get, nullptr, "x"); + dukglue_register_property(ctx, &ScThing::y_get, nullptr, "y"); + dukglue_register_property(ctx, &ScThing::z_get, nullptr, "z"); + dukglue_register_property(ctx, &ScThing::tshirtColour_get, &ScThing::tshirtColour_set, "tshirtColour"); + dukglue_register_property(ctx, &ScThing::trousersColour_get, &ScThing::trousersColour_set, "trousersColour"); + } + }; +} diff --git a/src/openrct2/scripting/ScriptEngine.cpp b/src/openrct2/scripting/ScriptEngine.cpp index d5f854107c..2d641a63fd 100644 --- a/src/openrct2/scripting/ScriptEngine.cpp +++ b/src/openrct2/scripting/ScriptEngine.cpp @@ -21,7 +21,9 @@ #include "ScConsole.hpp" #include "ScContext.hpp" #include "ScDisposable.hpp" +#include "ScMap.hpp" #include "ScPark.hpp" +#include "ScThing.hpp" using namespace OpenRCT2; using namespace OpenRCT2::Scripting; @@ -52,10 +54,13 @@ void ScriptEngine::Initialise() ScConsole::Register(ctx); ScContext::Register(ctx); ScDisposable::Register(ctx); + ScMap::Register(ctx); ScPark::Register(ctx); + ScThing::Register(ctx); dukglue_register_global(ctx, std::make_shared(_console), "console"); dukglue_register_global(ctx, std::make_shared(_execInfo, _hookEngine), "context"); + dukglue_register_global(ctx, std::make_shared(ctx), "map"); dukglue_register_global(ctx, std::make_shared(), "park"); LoadPlugins(); diff --git a/src/openrct2/thirdparty/dukglue/detail_primitive_types.h b/src/openrct2/thirdparty/dukglue/detail_primitive_types.h index ebba1ad80a..6ff83c1735 100644 --- a/src/openrct2/thirdparty/dukglue/detail_primitive_types.h +++ b/src/openrct2/thirdparty/dukglue/detail_primitive_types.h @@ -218,15 +218,19 @@ namespace dukglue { template static void push(duk_context* ctx, const std::shared_ptr& value) { - dukglue::detail::ProtoManager::make_script_object(ctx, value.get()); + if (value == nullptr) { + duk_push_null(ctx); + } else { + dukglue::detail::ProtoManager::make_script_object(ctx, value.get()); - // create + set shared_ptr - duk_push_pointer(ctx, new std::shared_ptr(value)); - duk_put_prop_string(ctx, -2, "\xFF" "shared_ptr"); + // create + set shared_ptr + duk_push_pointer(ctx, new std::shared_ptr(value)); + duk_put_prop_string(ctx, -2, "\xFF" "shared_ptr"); - // set shared_ptr finalizer - duk_push_c_function(ctx, &shared_ptr_finalizer, 1); - duk_set_finalizer(ctx, -2); + // set shared_ptr finalizer + duk_push_c_function(ctx, &shared_ptr_finalizer, 1); + duk_set_finalizer(ctx, -2); + } } };