From c1d97b845e08775aabef32f1e8a863c0b905bbd5 Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Mon, 2 Aug 2021 02:40:05 +0300 Subject: [PATCH 1/5] Small cleanup in ScMap.hpp --- src/openrct2/scripting/ScMap.hpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/openrct2/scripting/ScMap.hpp b/src/openrct2/scripting/ScMap.hpp index b895769654..d3be992d42 100644 --- a/src/openrct2/scripting/ScMap.hpp +++ b/src/openrct2/scripting/ScMap.hpp @@ -38,13 +38,7 @@ namespace OpenRCT2::Scripting DukValue size_get() const { - 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); + return ToDuk(_context, CoordsXY{ gMapSize, gMapSize }); } int32_t numRides_get() const @@ -110,7 +104,7 @@ namespace OpenRCT2::Scripting result.push_back(GetObjectAsDukValue(_context, std::make_shared(sprite->sprite_index))); } } - if (type == "car") + else if (type == "car") { for (auto trainHead : TrainManager::View()) { From 5e3913965de31746c33f09eaa8cb18bf81350cdc Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Mon, 2 Aug 2021 03:34:55 +0300 Subject: [PATCH 2/5] Add scripting API to create entities --- distribution/openrct2.d.ts | 1 + src/openrct2/scripting/ScMap.hpp | 76 ++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index 720b75e9d7..9701d00821 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -577,6 +577,7 @@ declare global { getAllEntities(type: "peep"): Peep[]; getAllEntities(type: "guest"): Guest[]; getAllEntities(type: "staff"): Staff[]; + createEntity(type: EntityType, initializer: object): Entity; } type TileElementType = diff --git a/src/openrct2/scripting/ScMap.hpp b/src/openrct2/scripting/ScMap.hpp index d3be992d42..d4f90f7220 100644 --- a/src/openrct2/scripting/ScMap.hpp +++ b/src/openrct2/scripting/ScMap.hpp @@ -17,7 +17,11 @@ # include "../world/Balloon.h" # include "../world/Duck.h" # include "../world/EntityList.h" +# include "../world/Fountain.h" +# include "../world/Litter.h" # include "../world/Map.h" +# include "../world/MoneyEffect.h" +# include "../world/Particle.h" # include "Duktape.hpp" # include "ScEntity.hpp" # include "ScRide.hpp" @@ -163,6 +167,77 @@ namespace OpenRCT2::Scripting return result; } + template DukValue createEntityType(const DukValue& initializer) + { + TEntityType* entity = CreateEntity(); + + auto entityPos = CoordsXYZ{ AsOrDefault(initializer["x"], 0), AsOrDefault(initializer["y"], 0), + AsOrDefault(initializer["z"], 0) }; + entity->MoveTo(entityPos); + + return GetObjectAsDukValue(_context, std::make_shared(entity->sprite_index)); + } + + DukValue createEntity(const std::string& type, const DukValue& initializer) + { + if (type == "car") + { + return createEntityType(initializer); + } + else if (type == "staff") + { + return createEntityType(initializer); + } + else if (type == "guest") + { + return createEntityType(initializer); + } + else if (type == "steam_particle") + { + return createEntityType(initializer); + } + else if (type == "money_effect") + { + return createEntityType(initializer); + } + else if (type == "crashed_vehicle_particle") + { + return createEntityType(initializer); + } + else if (type == "explosion_cloud") + { + return createEntityType(initializer); + } + else if (type == "crash_splash") + { + return createEntityType(initializer); + } + else if (type == "explosion_flare") + { + return createEntityType(initializer); + } + else if (type == "balloon") + { + return createEntityType(initializer); + } + else if (type == "duck") + { + return createEntityType(initializer); + } + else if (type == "jumping_fountain") + { + return createEntityType(initializer); + } + else if (type == "litter") + { + return createEntityType(initializer); + } + else + { + duk_error(_context, DUK_ERR_ERROR, "Invalid entity type."); + } + } + static void Register(duk_context* ctx) { dukglue_register_property(ctx, &ScMap::size_get, nullptr, "size"); @@ -173,6 +248,7 @@ namespace OpenRCT2::Scripting dukglue_register_method(ctx, &ScMap::getTile, "getTile"); dukglue_register_method(ctx, &ScMap::getEntity, "getEntity"); dukglue_register_method(ctx, &ScMap::getAllEntities, "getAllEntities"); + dukglue_register_method(ctx, &ScMap::createEntity, "createEntity"); } private: From 94daa1e42c499849d1e92cef2f342d8d775014fe Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Sat, 7 Aug 2021 22:02:51 +0300 Subject: [PATCH 3/5] Bump up scripting version --- src/openrct2/scripting/ScriptEngine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/scripting/ScriptEngine.h b/src/openrct2/scripting/ScriptEngine.h index 6c9d470fd6..f5f8bc9a2d 100644 --- a/src/openrct2/scripting/ScriptEngine.h +++ b/src/openrct2/scripting/ScriptEngine.h @@ -46,7 +46,7 @@ namespace OpenRCT2 namespace OpenRCT2::Scripting { - static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 34; + static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 35; // Versions marking breaking changes. static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33; From 29e5ec634c74d967a9cd7b79953e4db07b364c72 Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Sat, 7 Aug 2021 22:28:48 +0300 Subject: [PATCH 4/5] Add litter entity to scripting --- distribution/openrct2.d.ts | 28 ++++++++++++ src/openrct2/scripting/ScEntity.hpp | 66 +++++++++++++++++++++++++++++ src/openrct2/scripting/ScMap.hpp | 4 +- 3 files changed, 97 insertions(+), 1 deletion(-) diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index 9701d00821..88ba2f9378 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -1470,6 +1470,34 @@ declare global { type StaffType = "handyman" | "mechanic" | "security" | "entertainer"; + /** + * Represents litter entity. + */ + interface Litter extends Entity { + /** + * The type of the litter. + */ + litterType: LitterType; + + /** + * The tick number this entity was created. + */ + creationTime: number; + } + + type LitterType = "vomit" | + "vomit_alt" | + "empty_can" | + "rubbish" | + "burger_box" | + "empty_cup" | + "empty_box" | + "empty_bottle" | + "empty_bowl_red" | + "empty_drink_carton" | + "empty_juice_cup" | + "empty_bowl_blue"; + /** * Network APIs * Use `network.status` to determine whether the current game is a client, server or in single player mode. diff --git a/src/openrct2/scripting/ScEntity.hpp b/src/openrct2/scripting/ScEntity.hpp index 34e3f4ba12..656efd69c7 100644 --- a/src/openrct2/scripting/ScEntity.hpp +++ b/src/openrct2/scripting/ScEntity.hpp @@ -17,6 +17,7 @@ # include "../peep/Staff.h" # include "../util/Util.h" # include "../world/EntityList.h" +# include "../world/Litter.h" # include "../world/Sprite.h" # include "Duktape.hpp" # include "ScRide.hpp" @@ -1244,6 +1245,71 @@ namespace OpenRCT2::Scripting } }; + static const DukEnumMap LitterTypeMap({ + { "vomit", Litter::Type::Vomit }, + { "vomit_alt", Litter::Type::VomitAlt }, + { "empty_can", Litter::Type::EmptyCan }, + { "rubbish", Litter::Type::Rubbish }, + { "burger_box", Litter::Type::BurgerBox }, + { "empty_cup", Litter::Type::EmptyCup }, + { "empty_box", Litter::Type::EmptyBox }, + { "empty_bottle", Litter::Type::EmptyBottle }, + { "empty_bowl_red", Litter::Type::EmptyBowlRed }, + { "empty_drink_carton", Litter::Type::EmptyDrinkCarton }, + { "empty_juice_cup", Litter::Type::EmptyJuiceCup }, + { "empty_bowl_blue", Litter::Type::EmptyBowlBlue }, + }); + + class ScLitter : public ScEntity + { + public: + ScLitter(uint16_t Id) + : ScEntity(Id) + { + } + + static void Register(duk_context* ctx) + { + dukglue_set_base_class(ctx); + dukglue_register_property(ctx, &ScLitter::litterType_get, &ScLitter::litterType_set, "litterType"); + dukglue_register_property(ctx, &ScLitter::creationTick_get, nullptr, "creationTick"); + } + + private: + Litter* GetLitter() const + { + return ::GetEntity(_id); + } + + std::string litterType_get() const + { + auto* litter = GetLitter(); + auto it = LitterTypeMap.find(litter->SubType); + if (it == LitterTypeMap.end()) + return ""; + return std::string{ it->first }; + } + + void litterType_set(const std::string& litterType) + { + ThrowIfGameStateNotMutable(); + + auto it = LitterTypeMap.find(litterType); + if (it == LitterTypeMap.end()) + return; + auto* litter = GetLitter(); + litter->SubType = it->second; + } + + uint32_t creationTick_get() const + { + auto* litter = GetLitter(); + if (litter == nullptr) + return 0; + return litter->creationTick; + } + }; + } // namespace OpenRCT2::Scripting #endif diff --git a/src/openrct2/scripting/ScMap.hpp b/src/openrct2/scripting/ScMap.hpp index d4f90f7220..78e87b0b22 100644 --- a/src/openrct2/scripting/ScMap.hpp +++ b/src/openrct2/scripting/ScMap.hpp @@ -230,7 +230,7 @@ namespace OpenRCT2::Scripting } else if (type == "litter") { - return createEntityType(initializer); + return createEntityType(initializer); } else { @@ -263,6 +263,8 @@ namespace OpenRCT2::Scripting return GetObjectAsDukValue(_context, std::make_shared(spriteId)); case EntityType::Guest: return GetObjectAsDukValue(_context, std::make_shared(spriteId)); + case EntityType::Litter: + return GetObjectAsDukValue(_context, std::make_shared(spriteId)); default: return GetObjectAsDukValue(_context, std::make_shared(spriteId)); } From 30739de7cc0bddf6f7d1dba72515d021a75eda84 Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Sat, 7 Aug 2021 22:31:37 +0300 Subject: [PATCH 5/5] Update changelog.txt --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 51f8f05898..387f922a1c 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -2,6 +2,7 @@ ------------------------------------------------------------------------ - Feature: [#15084] [Plugin] Add "vehicle.crash" hook. - Feature: [#15143] Added a shortcut key for Giant Screenshot. +- Feature: [#15165] [Plugin] Add the ability to create entities using "map.createEntity". - Fix: [#13465] Creating a scenario based on a won save game results in a scenario that’s instantly won. - Fix: [#14316] Closing the Track Designs Manager window causes broken state. - Fix: [#14667] “Extreme Hawaiian Island” has unpurchaseable land tiles (original bug).