1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-23 15:52:55 +01:00

Add APIs for getting info about loaded objects

This commit is contained in:
Ted John
2020-03-07 14:41:29 +00:00
parent 7a62d55c5f
commit 76ebef10e3
5 changed files with 255 additions and 67 deletions

View File

@@ -112,6 +112,17 @@ declare global {
*/
sharedStorage: Configuration;
/**
* Gets the loaded object at the given index.
* @param type The object type.
* @param index The index.
*/
getObject(type: ObjectType, index: number): Object;
getObject(type: "ride", index: number): RideObject;
getAllObjects(type: ObjectType): Object[];
getAllObjects(type: "ride"): RideObject[];
/**
* Gets a random integer within the specified range using the game's pseudo-
* random number generator. This is part of the game state and shared across
@@ -175,6 +186,22 @@ declare global {
has(key: string): boolean;
}
type ObjectType =
"ride" |
"small_scenery" |
"large_scenery" |
"wall" |
"banner" |
"footpath" |
"footpath_addition" |
"scenery_group" |
"park_entrance" |
"water" |
"terrain_surface" |
"terrain_edge" |
"station" |
"music";
type HookType =
"interval.tick" | "interval.day" |
"network.chat" | "network.action" | "network.join" | "network.leave";
@@ -407,6 +434,16 @@ declare global {
* Represents the definition of a loaded object (.DAT or .json) such a ride type or scenery item.
*/
interface Object {
/**
* The object type.
*/
readonly type: ObjectType;
/**
* The index of the loaded object for the object type.
*/
readonly index: number;
/**
* The unique name identifier of the object, e.g. "BURGB ".
* This may have trailing spaces if the name is shorter than 8 characters.

View File

@@ -14,11 +14,13 @@
# include "../actions/CustomAction.hpp"
# include "../actions/ParkSetNameAction.hpp"
# include "../actions/SmallSceneryPlaceAction.hpp"
# include "../object/ObjectManager.h"
# include "../scenario/Scenario.h"
# include "Duktape.hpp"
# include "HookEngine.h"
# include "ScConfiguration.hpp"
# include "ScDisposable.hpp"
# include "ScObject.hpp"
# include "ScriptEngine.h"
# include <cstdio>
@@ -51,8 +53,64 @@ namespace OpenRCT2::Scripting
return std::make_shared<ScConfiguration>(scriptEngine.GetSharedStorage());
}
void registerIntent(const DukValue& desc)
static DukValue CreateScObject(duk_context* ctx, uint8_t type, int32_t index)
{
switch (type)
{
case OBJECT_TYPE_RIDE:
return GetObjectAsDukValue(ctx, std::make_shared<ScRideObject>(type, index));
break;
default:
return GetObjectAsDukValue(ctx, std::make_shared<ScObject>(type, index));
break;
}
}
DukValue getObject(const std::string& typez, int32_t index)
{
auto ctx = GetContext()->GetScriptEngine().GetContext();
auto& objManager = GetContext()->GetObjectManager();
auto type = ScObject::StringToObjectType(typez);
if (type)
{
auto obj = objManager.GetLoadedObject(*type, index);
if (obj != nullptr)
{
return CreateScObject(ctx, *type, index);
}
}
else
{
duk_error(ctx, DUK_ERR_ERROR, "Invalid object type.");
}
return {};
}
std::vector<DukValue> getAllObjects(const std::string& typez)
{
auto ctx = GetContext()->GetScriptEngine().GetContext();
auto& objManager = GetContext()->GetObjectManager();
std::vector<DukValue> result;
auto type = ScObject::StringToObjectType(typez);
if (type)
{
auto count = object_entry_group_counts[*type];
for (int32_t i = 0; i < count; i++)
{
auto obj = objManager.GetLoadedObject(*type, i);
if (obj != nullptr)
{
result.push_back(CreateScObject(ctx, *type, i));
}
}
}
else
{
duk_error(ctx, DUK_ERR_ERROR, "Invalid object type.");
}
return result;
}
int32_t getRandom(int32_t min, int32_t max)
@@ -230,8 +288,9 @@ namespace OpenRCT2::Scripting
{
dukglue_register_property(ctx, &ScContext::configuration_get, nullptr, "configuration");
dukglue_register_property(ctx, &ScContext::sharedStorage_get, nullptr, "sharedStorage");
dukglue_register_method(ctx, &ScContext::getObject, "getObject");
dukglue_register_method(ctx, &ScContext::getAllObjects, "getAllObjects");
dukglue_register_method(ctx, &ScContext::getRandom, "getRandom");
dukglue_register_method(ctx, &ScContext::registerIntent, "registerIntent");
dukglue_register_method(ctx, &ScContext::subscribe, "subscribe");
dukglue_register_method(ctx, &ScContext::queryAction, "queryAction");
dukglue_register_method(ctx, &ScContext::executeAction, "executeAction");

View File

@@ -0,0 +1,151 @@
/*****************************************************************************
* Copyright (c) 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 "../common.h"
# include "../object/ObjectManager.h"
# include "../object/RideObject.h"
# include "Duktape.hpp"
# include "ScriptEngine.h"
# include <optional>
namespace OpenRCT2::Scripting
{
class ScObject
{
private:
uint8_t _type{};
int32_t _index{};
public:
ScObject(uint8_t type, int32_t index)
: _type(type)
, _index(index)
{
}
static void Register(duk_context* ctx)
{
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");
dukglue_register_property(ctx, &ScObject::name_get, nullptr, "name");
}
static std::optional<uint8_t> StringToObjectType(const std::string_view& type)
{
for (uint8_t i = 0; i < OBJECT_TYPE_COUNT; i++)
{
auto s = ObjectTypeToString(i);
if (s == type)
{
return i;
}
}
return std::nullopt;
}
static std::string_view ObjectTypeToString(uint8_t type)
{
static const char* Types[] = { "ride", "small_scenery", "large_scenery", "wall", "banner",
"footpath", "footpath_addition", "scenery_group", "park_entrance", "water",
"stex", "terrain_surface", "terrain_edge", "station", "music" };
if (type >= std::size(Types))
return "unknown";
return Types[type];
}
private:
std::string type_get()
{
return std::string(ObjectTypeToString(_type));
}
int32_t index_get()
{
return _index;
}
std::string identifier_get()
{
auto obj = GetObject();
if (obj != nullptr)
{
return obj->GetIdentifier();
}
return {};
}
std::string name_get()
{
auto obj = GetObject();
if (obj != nullptr)
{
return obj->GetName();
}
return {};
}
protected:
Object* GetObject()
{
auto& objManager = GetContext()->GetObjectManager();
return objManager.GetLoadedObject(_type, _index);
}
};
class ScRideObject : public ScObject
{
public:
ScRideObject(uint8_t type, int32_t index)
: ScObject(type, index)
{
}
static void Register(duk_context* ctx)
{
dukglue_set_base_class<ScObject, ScRideObject>(ctx);
dukglue_register_property(ctx, &ScRideObject::description_get, nullptr, "description");
dukglue_register_property(ctx, &ScRideObject::capacity_get, nullptr, "capacity");
}
private:
std::string description_get()
{
auto obj = GetObject();
if (obj != nullptr)
{
return obj->GetDescription();
}
return {};
}
std::string capacity_get()
{
auto obj = GetObject();
if (obj != nullptr)
{
return obj->GetCapacity();
}
return {};
}
protected:
RideObject* GetObject()
{
return static_cast<RideObject*>(ScObject::GetObject());
}
};
} // namespace OpenRCT2::Scripting
#endif

View File

@@ -12,74 +12,13 @@
#ifdef __ENABLE_SCRIPTING__
# include "../common.h"
# include "../object/RideObject.h"
# include "../ride/Ride.h"
# include "Duktape.hpp"
# include "ScObject.hpp"
# include "ScriptEngine.h"
namespace OpenRCT2::Scripting
{
class ScRideObject
{
private:
rct_ride_entry* _entry{};
public:
ScRideObject(rct_ride_entry* entry)
: _entry(entry)
{
}
static void Register(duk_context* ctx)
{
dukglue_register_property(ctx, &ScRideObject::id_get, nullptr, "identifier");
dukglue_register_property(ctx, &ScRideObject::name_get, nullptr, "name");
dukglue_register_property(ctx, &ScRideObject::description_get, nullptr, "description");
dukglue_register_property(ctx, &ScRideObject::capacity_get, nullptr, "capacity");
}
private:
std::string id_get()
{
auto obj = static_cast<Object*>(_entry->obj);
if (obj != nullptr)
{
return obj->GetIdentifier();
}
return {};
}
std::string name_get()
{
auto obj = static_cast<Object*>(_entry->obj);
if (obj != nullptr)
{
return obj->GetName();
}
return {};
}
std::string description_get()
{
auto obj = static_cast<RideObject*>(_entry->obj);
if (obj != nullptr)
{
return obj->GetDescription();
}
return {};
}
std::string capacity_get()
{
auto obj = static_cast<RideObject*>(_entry->obj);
if (obj != nullptr)
{
return obj->GetCapacity();
}
return {};
}
};
class ScRide
{
private:
@@ -102,10 +41,10 @@ namespace OpenRCT2::Scripting
auto ride = GetRide();
if (ride != nullptr)
{
auto rideEntry = ride->GetRideEntry();
if (rideEntry != nullptr)
auto rideObject = GetContext()->GetObjectManager().GetLoadedObject(OBJECT_TYPE_RIDE, ride->subtype);
if (rideObject != nullptr)
{
return std::make_shared<ScRideObject>(rideEntry);
return std::make_shared<ScRideObject>(OBJECT_TYPE_RIDE, ride->subtype);
}
}
return nullptr;

View File

@@ -27,6 +27,7 @@
# include "ScDisposable.hpp"
# include "ScMap.hpp"
# include "ScNetwork.hpp"
# include "ScObject.hpp"
# include "ScPark.hpp"
# include "ScRide.hpp"
# include "ScThing.hpp"
@@ -373,6 +374,7 @@ void ScriptEngine::Initialise()
ScDisposable::Register(ctx);
ScMap::Register(ctx);
ScNetwork::Register(ctx);
ScObject::Register(ctx);
ScPark::Register(ctx);
ScPlayer::Register(ctx);
ScPlayerGroup::Register(ctx);