diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index 7f84063323..aa4bc78e17 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -720,20 +720,20 @@ declare global { * Represents a guest or staff member. */ interface Peep extends Entity { + /** + * Whether the peep is a guest or staff member. + */ + peepType: PeepType; + /** * Name of the peep. */ name: string; /** - * Colour of the peep's t-shirt. + * The peep's direct destination. */ - tshirtColour: number; - - /** - * Colour of the peep's trousers. - */ - trousersColour: number; + destination: CoordsXY; /** * How tired the guest is between 32 and 128 where lower is more tired. @@ -745,6 +745,78 @@ declare global { */ energyTarget: number; + /** + * Gets whether a given flag is set or not. + * @param key The flag to test. + */ + getFlag(key: PeepFlags): boolean; + + /** + * Sets the given flag to the given value. + * @param key The flag to set. + * @param value Whether to set or clear the flag. + */ + setFlag(key: PeepFlags, value: boolean): void; + } + + type PeepFlags = + "leavingPark" | + "slowWalk" | + "tracking" | + "waving" | + "hasPaidForParkEntry" | + "photo" | + "painting" | + "wow" | + "litter" | + "lost" | + "hunger" | + "toilet" | + "crowded" | + "happiness" | + "nausea" | + "purple" | + "pizza" | + "explode" | + "rideShouldBeMarkedAsFavourite" | + "parkEntranceChosen" | + "contagious" | + "joy" | + "angry" | + "iceCream" | + "hereWeAre"; + + type PeepType = "guest" | "staff"; + + /** + * Represents a guest. + */ + interface Guest extends Peep { + /** + * Colour of the guest's t-shirt. + */ + tshirtColour: number; + + /** + * Colour of the guest's trousers. + */ + trousersColour: number; + + /** + * Colour of the guest's balloon. + */ + balloonColour: number; + + /** + * Colour of the guest's hat. + */ + hatColour: number; + + /** + * Colour of the guest's umbrella. + */ + umbrellaColour: number; + /** * How happy the guest is between 0 and 255. */ @@ -806,6 +878,33 @@ declare global { cash: number; } + /** + * Represents a staff member. + */ + interface Staff extends Peep { + /** + * The type of staff member, e.g. handyman, mechanic. + */ + staffType: StaffType; + + /** + * Colour of the staff member. Not applicable for entertainers. + */ + colour: number; + + /** + * The entertainer's costume, only applicable for entertainers. + */ + costume: number; + + /** + * The enabled jobs the staff can do, e.g. sweep litter, water plants, inspect rides etc. + */ + orders: number; + } + + type StaffType = "handyman" | "mechanic" | "security" | "entertainer"; + /** * 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-ui/scripting/CustomMenu.cpp b/src/openrct2-ui/scripting/CustomMenu.cpp index 34333ad903..28c3b9d2bf 100644 --- a/src/openrct2-ui/scripting/CustomMenu.cpp +++ b/src/openrct2-ui/scripting/CustomMenu.cpp @@ -51,22 +51,6 @@ namespace OpenRCT2::Scripting return CURSOR_UNDEFINED; } - template<> DukValue ToDuk(duk_context* ctx, const CoordsXY& coords) - { - DukObject dukCoords(ctx); - dukCoords.Set("x", coords.x); - dukCoords.Set("y", coords.y); - return dukCoords.Take(); - } - - template<> DukValue ToDuk(duk_context* ctx, const ScreenCoordsXY& coords) - { - DukObject dukCoords(ctx); - dukCoords.Set("x", coords.x); - dukCoords.Set("y", coords.y); - return dukCoords.Take(); - } - static void RemoveMenuItemsAndTool(std::shared_ptr owner) { if (ActiveCustomTool) diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 6aa33c773d..c7f627d035 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -893,6 +893,8 @@ public: bool IsPatrolAreaSet(const CoordsXY& coords) const; bool IsLocationInPatrol(const CoordsXY& loc) const; bool DoPathFinding(); + uint8_t GetCostume() const; + void SetCostume(uint8_t value); private: void UpdatePatrolling(); diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 872fda74d8..04367258d0 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -1100,6 +1100,16 @@ bool Staff::DoPathFinding() } } +uint8_t Staff::GetCostume() const +{ + return sprite_type - PEEP_SPRITE_TYPE_ENTERTAINER_PANDA; +} + +void Staff::SetCostume(uint8_t value) +{ + sprite_type = static_cast(value + PEEP_SPRITE_TYPE_ENTERTAINER_PANDA); +} + colour_t staff_get_colour(uint8_t staffType) { switch (staffType) diff --git a/src/openrct2/scripting/Duktape.hpp b/src/openrct2/scripting/Duktape.hpp index c3b0e8bf0a..2563727885 100644 --- a/src/openrct2/scripting/Duktape.hpp +++ b/src/openrct2/scripting/Duktape.hpp @@ -11,6 +11,8 @@ #ifdef ENABLE_SCRIPTING +# include "../world/Map.h" + # include # include # include @@ -183,6 +185,46 @@ namespace OpenRCT2::Scripting DukStackFrame(DukStackFrame&&) = delete; }; + /** + * Bi-directional map for converting between strings and enums / numbers. + */ + template class DukEnumMap + { + private: + std::unordered_map _s2n; + std::unordered_map _n2s; + + public: + DukEnumMap(const std::initializer_list>& items) + { + _s2n = std::unordered_map(items.begin(), items.end()); + for (const auto& kvp : items) + { + _n2s.emplace(std::get<1>(kvp), std::get<0>(kvp)); + } + } + + std::string_view operator[](T k) const + { + auto it = _n2s.find(k); + if (it == _n2s.end()) + { + return ""; + } + return it->second; + } + + T operator[](const std::string_view& k) const + { + auto it = _s2n.find(k); + if (it == _s2n.end()) + { + return 0; + } + return it->second; + } + }; + inline duk_ret_t duk_json_decode_wrapper(duk_context* ctx, void*) { duk_json_decode(ctx, -1); @@ -232,6 +274,39 @@ namespace OpenRCT2::Scripting return value ? ToDuk(ctx, *value) : ToDuk(ctx, nullptr); } + template<> CoordsXY inline FromDuk(const DukValue& d) + { + CoordsXY result; + result.x = AsOrDefault(d["x"], 0); + result.y = AsOrDefault(d["y"], 0); + return result; + } + + template<> DukValue inline ToDuk(duk_context* ctx, const CoordsXY& coords) + { + DukObject dukCoords(ctx); + dukCoords.Set("x", coords.x); + dukCoords.Set("y", coords.y); + return dukCoords.Take(); + } + + template<> DukValue inline ToDuk(duk_context* ctx, const CoordsXYZ& coords) + { + DukObject dukCoords(ctx); + dukCoords.Set("x", coords.x); + dukCoords.Set("y", coords.y); + dukCoords.Set("z", coords.z); + return dukCoords.Take(); + } + + template<> DukValue inline ToDuk(duk_context* ctx, const ScreenCoordsXY& coords) + { + DukObject dukCoords(ctx); + dukCoords.Set("x", coords.x); + dukCoords.Set("y", coords.y); + return dukCoords.Take(); + } + } // namespace OpenRCT2::Scripting #endif diff --git a/src/openrct2/scripting/ScConfiguration.hpp b/src/openrct2/scripting/ScConfiguration.hpp index 4dc295a65c..8443cf182a 100644 --- a/src/openrct2/scripting/ScConfiguration.hpp +++ b/src/openrct2/scripting/ScConfiguration.hpp @@ -13,6 +13,7 @@ # include "../Context.h" # include "../config/Config.h" +# include "../localisation/LocalisationService.h" # include "Duktape.hpp" # include "ScriptEngine.h" @@ -138,6 +139,7 @@ namespace OpenRCT2::Scripting DukObject obj(ctx); if (ns == "general") { + obj.Set("general.language", gConfigGeneral.language); obj.Set("general.showFps", gConfigGeneral.show_fps); } result = obj.Take(); @@ -160,7 +162,19 @@ namespace OpenRCT2::Scripting auto ctx = GetContext()->GetScriptEngine().GetContext(); if (_isUserConfig) { - if (key == "general.showFps") + if (key == "general.language") + { + auto& localisationService = GetContext()->GetLocalisationService(); + auto language = localisationService.GetCurrentLanguage(); + auto locale = ""; + if (language >= 0 && static_cast(language) < std::size(LanguagesDescriptors)) + { + locale = LanguagesDescriptors[language].locale; + } + duk_push_string(ctx, locale); + return DukValue::take_from_stack(ctx); + } + else if (key == "general.showFps") { duk_push_boolean(ctx, gConfigGeneral.show_fps); return DukValue::take_from_stack(ctx); diff --git a/src/openrct2/scripting/ScEntity.hpp b/src/openrct2/scripting/ScEntity.hpp index d3c36ab107..4ddcc44528 100644 --- a/src/openrct2/scripting/ScEntity.hpp +++ b/src/openrct2/scripting/ScEntity.hpp @@ -13,11 +13,15 @@ # include "../Context.h" # include "../common.h" +# include "../peep/Peep.h" +# include "../peep/Staff.h" # include "../world/Sprite.h" # include "Duktape.hpp" # include "ScriptEngine.h" # include +# include +# include namespace OpenRCT2::Scripting { @@ -172,6 +176,34 @@ namespace OpenRCT2::Scripting } }; + static const DukEnumMap PeepFlagMap({ + { "leavingPark", PEEP_FLAGS_LEAVING_PARK }, + { "slowWalk", PEEP_FLAGS_SLOW_WALK }, + { "tracking", PEEP_FLAGS_TRACKING }, + { "waving", PEEP_FLAGS_WAVING }, + { "hasPaidForParkEntry", PEEP_FLAGS_HAS_PAID_FOR_PARK_ENTRY }, + { "photo", PEEP_FLAGS_PHOTO }, + { "painting", PEEP_FLAGS_PAINTING }, + { "wow", PEEP_FLAGS_WOW }, + { "litter", PEEP_FLAGS_LITTER }, + { "lost", PEEP_FLAGS_LOST }, + { "hunger", PEEP_FLAGS_HUNGER }, + { "toilet", PEEP_FLAGS_TOILET }, + { "crowded", PEEP_FLAGS_CROWDED }, + { "happiness", PEEP_FLAGS_HAPPINESS }, + { "nausea", PEEP_FLAGS_NAUSEA }, + { "purple", PEEP_FLAGS_PURPLE }, + { "pizza", PEEP_FLAGS_PIZZA }, + { "explode", PEEP_FLAGS_EXPLODE }, + { "rideShouldBeMarkedAsFavourite", PEEP_FLAGS_RIDE_SHOULD_BE_MARKED_AS_FAVOURITE }, + { "parkEntranceChosen", PEEP_FLAGS_PARK_ENTRANCE_CHOSEN }, + { "contagious", PEEP_FLAGS_CONTAGIOUS }, + { "joy", PEEP_FLAGS_JOY }, + { "angry", PEEP_FLAGS_ANGRY }, + { "iceCream", PEEP_FLAGS_ICE_CREAM }, + { "hereWeAre", PEEP_FLAGS_HERE_WE_ARE }, + }); + class ScPeep : public ScEntity { public: @@ -180,7 +212,29 @@ namespace OpenRCT2::Scripting { } + static void Register(duk_context* ctx) + { + dukglue_set_base_class(ctx); + dukglue_register_property(ctx, &ScPeep::peepType_get, nullptr, "peepType"); + dukglue_register_property(ctx, &ScPeep::name_get, &ScPeep::name_set, "name"); + dukglue_register_property(ctx, &ScPeep::destination_get, &ScPeep::destination_set, "destination"); + dukglue_register_property(ctx, &ScPeep::energy_get, &ScPeep::energy_set, "energy"); + dukglue_register_property(ctx, &ScPeep::energyTarget_get, &ScPeep::energyTarget_set, "energyTarget"); + dukglue_register_method(ctx, &ScPeep::getFlag, "getFlag"); + dukglue_register_method(ctx, &ScPeep::setFlag, "setFlag"); + } + private: + std::string peepType_get() const + { + auto peep = GetPeep(); + if (peep != nullptr) + { + return peep->type == PEEP_TYPE_STAFF ? "staff" : "guest"; + } + return ""; + } + std::string name_get() const { auto peep = GetPeep(); @@ -196,6 +250,134 @@ namespace OpenRCT2::Scripting } } + bool getFlag(const std::string& key) const + { + auto peep = GetPeep(); + if (peep != nullptr) + { + auto mask = PeepFlagMap[key]; + return (peep->peep_flags & mask) != 0; + } + return false; + } + + void setFlag(const std::string& key, bool value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetPeep(); + if (peep != nullptr) + { + auto mask = PeepFlagMap[key]; + if (value) + peep->peep_flags |= mask; + else + peep->peep_flags &= ~mask; + peep->Invalidate(); + } + } + + DukValue destination_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto peep = GetPeep(); + if (peep != nullptr) + { + return ToDuk(ctx, CoordsXY(peep->destination_x, peep->destination_y)); + } + return ToDuk(ctx, nullptr); + } + + void destination_set(const DukValue& value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetPeep(); + if (peep != nullptr) + { + auto pos = FromDuk(value); + peep->destination_x = pos.x; + peep->destination_y = pos.y; + peep->Invalidate(); + } + } + + uint8_t energy_get() const + { + auto peep = GetPeep(); + return peep != nullptr ? peep->energy : 0; + } + void energy_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetPeep(); + if (peep != nullptr) + { + peep->energy = value; + } + } + + uint8_t energyTarget_get() const + { + auto peep = GetPeep(); + return peep != nullptr ? peep->energy_target : 0; + } + void energyTarget_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetPeep(); + if (peep != nullptr) + { + peep->energy_target = value; + } + } + + protected: + Peep* GetPeep() const + { + return get_sprite(_id)->AsPeep(); + } + }; + + class ScGuest : public ScPeep + { + public: + ScGuest(uint16_t id) + : ScPeep(id) + { + } + + static void Register(duk_context* ctx) + { + dukglue_set_base_class(ctx); + dukglue_register_property(ctx, &ScGuest::tshirtColour_get, &ScGuest::tshirtColour_set, "tshirtColour"); + dukglue_register_property(ctx, &ScGuest::trousersColour_get, &ScGuest::trousersColour_set, "trousersColour"); + dukglue_register_property(ctx, &ScGuest::balloonColour_get, &ScGuest::balloonColour_set, "balloonColour"); + dukglue_register_property(ctx, &ScGuest::hatColour_get, &ScGuest::hatColour_set, "hatColour"); + dukglue_register_property(ctx, &ScGuest::umbrellaColour_get, &ScGuest::umbrellaColour_set, "umbrellaColour"); + dukglue_register_property(ctx, &ScGuest::happiness_get, &ScGuest::happiness_set, "happiness"); + dukglue_register_property(ctx, &ScGuest::happinessTarget_get, &ScGuest::happinessTarget_set, "happinessTarget"); + dukglue_register_property(ctx, &ScGuest::nausea_get, &ScGuest::nausea_set, "nausea"); + dukglue_register_property(ctx, &ScGuest::nauseaTarget_get, &ScGuest::nauseaTarget_set, "nauseaTarget"); + dukglue_register_property(ctx, &ScGuest::hunger_get, &ScGuest::hunger_set, "hunger"); + dukglue_register_property(ctx, &ScGuest::thirst_get, &ScGuest::thirst_set, "thirst"); + dukglue_register_property(ctx, &ScGuest::toilet_get, &ScGuest::toilet_set, "toilet"); + dukglue_register_property(ctx, &ScGuest::mass_get, &ScGuest::mass_set, "mass"); + dukglue_register_property(ctx, &ScGuest::minIntensity_get, &ScGuest::minIntensity_set, "minIntensity"); + dukglue_register_property(ctx, &ScGuest::maxIntensity_get, &ScGuest::maxIntensity_set, "maxIntensity"); + dukglue_register_property(ctx, &ScGuest::nauseaTolerance_get, &ScGuest::nauseaTolerance_set, "nauseaTolerance"); + dukglue_register_property(ctx, &ScGuest::cash_get, &ScGuest::cash_set, "cash"); + } + + private: + Guest* GetGuest() const + { + auto peep = GetPeep(); + if (peep != nullptr) + { + return peep->AsGuest(); + } + return nullptr; + } + uint8_t tshirtColour_get() const { auto peep = GetPeep(); @@ -228,33 +410,51 @@ namespace OpenRCT2::Scripting } } - uint8_t energy_get() const + uint8_t balloonColour_get() const { auto peep = GetPeep(); - return peep != nullptr ? peep->energy : 0; + return peep != nullptr ? peep->BalloonColour : 0; } - void energy_set(uint8_t value) + void balloonColour_set(uint8_t value) { ThrowIfGameStateNotMutable(); auto peep = GetPeep(); if (peep != nullptr) { - peep->energy = value; + peep->BalloonColour = value; + peep->Invalidate(); } } - uint8_t energyTarget_get() const + uint8_t hatColour_get() const { auto peep = GetPeep(); - return peep != nullptr ? peep->energy_target : 0; + return peep != nullptr ? peep->HatColour : 0; } - void energyTarget_set(uint8_t value) + void hatColour_set(uint8_t value) { ThrowIfGameStateNotMutable(); auto peep = GetPeep(); if (peep != nullptr) { - peep->energy_target = value; + peep->HatColour = value; + peep->Invalidate(); + } + } + + uint8_t umbrellaColour_get() const + { + auto peep = GetPeep(); + return peep != nullptr ? peep->UmbrellaColour : 0; + } + void umbrellaColour_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetPeep(); + if (peep != nullptr) + { + peep->UmbrellaColour = value; + peep->Invalidate(); } } @@ -437,33 +637,136 @@ namespace OpenRCT2::Scripting peep->cash_in_pocket = std::max(0, value); } } + }; - Peep* GetPeep() const + class ScStaff : public ScPeep + { + public: + ScStaff(uint16_t id) + : ScPeep(id) { - return get_sprite(_id)->AsPeep(); } - public: static void Register(duk_context* ctx) { - dukglue_set_base_class(ctx); - dukglue_register_property(ctx, &ScPeep::name_get, &ScPeep::name_set, "name"); - dukglue_register_property(ctx, &ScPeep::tshirtColour_get, &ScPeep::tshirtColour_set, "tshirtColour"); - dukglue_register_property(ctx, &ScPeep::trousersColour_get, &ScPeep::trousersColour_set, "trousersColour"); - dukglue_register_property(ctx, &ScPeep::energy_get, &ScPeep::energy_set, "energy"); - dukglue_register_property(ctx, &ScPeep::energyTarget_get, &ScPeep::energyTarget_set, "energyTarget"); - dukglue_register_property(ctx, &ScPeep::happiness_get, &ScPeep::happiness_set, "happiness"); - dukglue_register_property(ctx, &ScPeep::happinessTarget_get, &ScPeep::happinessTarget_set, "happinessTarget"); - dukglue_register_property(ctx, &ScPeep::nausea_get, &ScPeep::nausea_set, "nausea"); - dukglue_register_property(ctx, &ScPeep::nauseaTarget_get, &ScPeep::nauseaTarget_set, "nauseaTarget"); - dukglue_register_property(ctx, &ScPeep::hunger_get, &ScPeep::hunger_set, "hunger"); - dukglue_register_property(ctx, &ScPeep::thirst_get, &ScPeep::thirst_set, "thirst"); - dukglue_register_property(ctx, &ScPeep::toilet_get, &ScPeep::toilet_set, "toilet"); - dukglue_register_property(ctx, &ScPeep::mass_get, &ScPeep::mass_set, "mass"); - dukglue_register_property(ctx, &ScPeep::minIntensity_get, &ScPeep::minIntensity_set, "minIntensity"); - dukglue_register_property(ctx, &ScPeep::maxIntensity_get, &ScPeep::maxIntensity_set, "maxIntensity"); - dukglue_register_property(ctx, &ScPeep::nauseaTolerance_get, &ScPeep::nauseaTolerance_set, "nauseaTolerance"); - dukglue_register_property(ctx, &ScPeep::cash_get, &ScPeep::cash_set, "cash"); + dukglue_set_base_class(ctx); + dukglue_register_property(ctx, &ScStaff::staffType_get, &ScStaff::staffType_set, "staffType"); + dukglue_register_property(ctx, &ScStaff::colour_get, &ScStaff::colour_set, "colour"); + dukglue_register_property(ctx, &ScStaff::costume_get, &ScStaff::costume_set, "costume"); + dukglue_register_property(ctx, &ScStaff::orders_get, &ScStaff::orders_set, "orders"); + } + + private: + Staff* GetStaff() const + { + auto peep = GetPeep(); + if (peep != nullptr) + { + return peep->AsStaff(); + } + return nullptr; + } + + std::string staffType_get() const + { + auto peep = GetStaff(); + if (peep != nullptr) + { + switch (peep->staff_type) + { + case STAFF_TYPE_HANDYMAN: + return "handyman"; + case STAFF_TYPE_MECHANIC: + return "mechanic"; + case STAFF_TYPE_SECURITY: + return "security"; + case STAFF_TYPE_ENTERTAINER: + return "entertainer"; + } + } + return ""; + } + + void staffType_set(const std::string& value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetStaff(); + if (peep != nullptr) + { + if (value == "handyman" && peep->staff_type != STAFF_TYPE_HANDYMAN) + { + peep->staff_type = STAFF_TYPE_HANDYMAN; + peep->sprite_type = PeepSpriteType::PEEP_SPRITE_TYPE_HANDYMAN; + } + else if (value == "mechanic" && peep->staff_type != STAFF_TYPE_MECHANIC) + { + peep->staff_type = STAFF_TYPE_MECHANIC; + peep->sprite_type = PeepSpriteType::PEEP_SPRITE_TYPE_MECHANIC; + } + else if (value == "security" && peep->staff_type != STAFF_TYPE_SECURITY) + { + peep->staff_type = STAFF_TYPE_SECURITY; + peep->sprite_type = PeepSpriteType::PEEP_SPRITE_TYPE_SECURITY; + } + else if (value == "entertainer" && peep->staff_type != STAFF_TYPE_ENTERTAINER) + { + peep->staff_type = STAFF_TYPE_ENTERTAINER; + peep->sprite_type = PeepSpriteType::PEEP_SPRITE_TYPE_ENTERTAINER_PANDA; + } + } + } + + uint8_t colour_get() const + { + auto peep = GetStaff(); + return peep != nullptr ? peep->tshirt_colour : 0; + } + + void colour_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetStaff(); + if (peep != nullptr) + { + peep->tshirt_colour = value; + peep->trousers_colour = value; + } + } + + uint8_t costume_get() const + { + auto peep = GetStaff(); + if (peep != nullptr && peep->staff_type == STAFF_TYPE_ENTERTAINER) + { + return peep->GetCostume(); + } + return 0; + } + + void costume_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetStaff(); + if (peep != nullptr) + { + peep->SetCostume(value); + } + } + + uint8_t orders_get() const + { + auto peep = GetStaff(); + return peep != nullptr ? peep->staff_orders : 0; + } + + void orders_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + auto peep = GetStaff(); + if (peep != nullptr) + { + peep->staff_orders = value; + } } }; diff --git a/src/openrct2/scripting/ScMap.hpp b/src/openrct2/scripting/ScMap.hpp index bd549b8f8d..3f6088e906 100644 --- a/src/openrct2/scripting/ScMap.hpp +++ b/src/openrct2/scripting/ScMap.hpp @@ -146,7 +146,10 @@ namespace OpenRCT2::Scripting { if (targetList == SPRITE_LIST_PEEP) { - result.push_back(GetObjectAsDukValue(_context, std::make_shared(spriteId))); + if (sprite->peep.type == PEEP_TYPE_STAFF) + result.push_back(GetObjectAsDukValue(_context, std::make_shared(spriteId))); + else + result.push_back(GetObjectAsDukValue(_context, std::make_shared(spriteId))); } else if (targetList == SPRITE_LIST_TRAIN_HEAD) { @@ -195,7 +198,10 @@ namespace OpenRCT2::Scripting switch (sprite->generic.sprite_identifier) { case SPRITE_IDENTIFIER_PEEP: - return GetObjectAsDukValue(_context, std::make_shared(spriteId)); + if (sprite->peep.type == PEEP_TYPE_STAFF) + return GetObjectAsDukValue(_context, std::make_shared(spriteId)); + else + return GetObjectAsDukValue(_context, std::make_shared(spriteId)); default: return GetObjectAsDukValue(_context, std::make_shared(spriteId)); } diff --git a/src/openrct2/scripting/ScriptEngine.cpp b/src/openrct2/scripting/ScriptEngine.cpp index b09790e878..fc1da14adb 100644 --- a/src/openrct2/scripting/ScriptEngine.cpp +++ b/src/openrct2/scripting/ScriptEngine.cpp @@ -390,6 +390,8 @@ void ScriptEngine::Initialise() ScTileElement::Register(ctx); ScEntity::Register(ctx); ScPeep::Register(ctx); + ScGuest::Register(ctx); + ScStaff::Register(ctx); dukglue_register_global(ctx, std::make_shared(), "cheats"); dukglue_register_global(ctx, std::make_shared(_console), "console"); @@ -773,20 +775,6 @@ std::unique_ptr ScriptEngine::DukToGameActionResult(const DukV return result; } -DukValue ScriptEngine::PositionToDuk(const CoordsXYZ& position) -{ - DukStackFrame frame(_context); - duk_context* ctx = _context; - auto obj = duk_push_object(ctx); - duk_push_int(ctx, position.x); - duk_put_prop_string(ctx, obj, "x"); - duk_push_int(ctx, position.y); - duk_put_prop_string(ctx, obj, "y"); - duk_push_int(ctx, position.z); - duk_put_prop_string(ctx, obj, "z"); - return DukValue::take_from_stack(ctx); -} - constexpr static const char* ExpenditureTypes[] = { "ride_construction", "ride_runningcosts", @@ -840,7 +828,7 @@ DukValue ScriptEngine::GameActionResultToDuk(const GameAction& action, const std } if (!result->Position.isNull()) { - obj.Set("position", PositionToDuk(result->Position)); + obj.Set("position", ToDuk(_context, result->Position)); } if (result->Expenditure != ExpenditureType::Count) diff --git a/src/openrct2/scripting/ScriptEngine.h b/src/openrct2/scripting/ScriptEngine.h index 30466bce06..f2d771ef07 100644 --- a/src/openrct2/scripting/ScriptEngine.h +++ b/src/openrct2/scripting/ScriptEngine.h @@ -201,7 +201,6 @@ namespace OpenRCT2::Scripting void RemoveCustomGameActions(const std::shared_ptr& plugin); std::unique_ptr DukToGameActionResult(const DukValue& d); DukValue GameActionResultToDuk(const GameAction& action, const std::unique_ptr& result); - DukValue PositionToDuk(const CoordsXYZ& position); static std::string_view ExpenditureTypeToString(ExpenditureType expenditureType); static ExpenditureType StringToExpenditureType(const std::string_view& expenditureType);