From e820956a59b5654629bc6ba0718e4ddf34fff61e Mon Sep 17 00:00:00 2001 From: Ted John Date: Thu, 20 Apr 2023 21:56:43 +0100 Subject: [PATCH] Move research API to .cpp file --- src/openrct2/libopenrct2.vcxproj | 1 + .../scripting/bindings/world/ScResearch.cpp | 286 ++++++++++++++++++ .../scripting/bindings/world/ScResearch.hpp | 276 ++--------------- 3 files changed, 308 insertions(+), 255 deletions(-) create mode 100644 src/openrct2/scripting/bindings/world/ScResearch.cpp diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index e9293bae1b..51a3fccbb8 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -993,6 +993,7 @@ + diff --git a/src/openrct2/scripting/bindings/world/ScResearch.cpp b/src/openrct2/scripting/bindings/world/ScResearch.cpp new file mode 100644 index 0000000000..4e6995c4ae --- /dev/null +++ b/src/openrct2/scripting/bindings/world/ScResearch.cpp @@ -0,0 +1,286 @@ +/***************************************************************************** + * Copyright (c) 2014-2023 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. + *****************************************************************************/ + +#ifdef ENABLE_SCRIPTING + +# include "ScResearch.hpp" + +# include "../../../Context.h" +# include "../../../common.h" +# include "../../../core/String.hpp" +# include "../../../management/Research.h" +# include "../../../ride/RideData.h" +# include "../../Duktape.hpp" +# include "../../ScriptEngine.h" +# include "../object/ScObject.hpp" + +namespace OpenRCT2::Scripting +{ + static const DukEnumMap ResearchStageMap({ + { "initial_research", RESEARCH_STAGE_INITIAL_RESEARCH }, + { "designing", RESEARCH_STAGE_DESIGNING }, + { "completing_design", RESEARCH_STAGE_COMPLETING_DESIGN }, + { "unknown", RESEARCH_STAGE_UNKNOWN }, + { "finished_all", RESEARCH_STAGE_FINISHED_ALL }, + }); + + static const DukEnumMap ResearchCategoryMap({ + { "transport", ResearchCategory::Transport }, + { "gentle", ResearchCategory::Gentle }, + { "rollercoaster", ResearchCategory::Rollercoaster }, + { "thrill", ResearchCategory::Thrill }, + { "water", ResearchCategory::Water }, + { "shop", ResearchCategory::Shop }, + { "scenery", ResearchCategory::SceneryGroup }, + }); + + static const DukEnumMap ResearchEntryTypeMap({ + { "ride", Research::EntryType::Ride }, + { "scenery", Research::EntryType::Scenery }, + }); + + template<> inline DukValue ToDuk(duk_context* ctx, const ResearchItem& value) + { + DukObject obj(ctx); + obj.Set("category", ResearchCategoryMap[value.category]); + obj.Set("type", ResearchEntryTypeMap[value.type]); + if (value.type == Research::EntryType::Ride) + { + obj.Set("rideType", value.baseRideType); + } + obj.Set("object", value.entryIndex); + return obj.Take(); + } + + template<> Research::EntryType inline FromDuk(const DukValue& d) + { + if (d.type() == DukValue::STRING) + { + auto it = ResearchEntryTypeMap.find(d.as_string()); + if (it != ResearchEntryTypeMap.end()) + { + return it->second; + } + } + return Research::EntryType::Scenery; + } + + template<> ResearchItem inline FromDuk(const DukValue& d) + { + ResearchItem result; + result.baseRideType = 0; + result.category = {}; // We ignore category because it will be derived from ride type + result.flags = 0; + result.type = FromDuk(d["type"]); + auto baseRideType = d["rideType"]; + if (baseRideType.type() == DukValue::NUMBER) + result.baseRideType = baseRideType.as_int(); + result.entryIndex = d["object"].as_int(); + return result; + } + + ScResearch::ScResearch(duk_context* ctx) + : _context(ctx) + { + } + + uint8_t ScResearch::funding_get() const + { + return gResearchFundingLevel; + } + + void ScResearch::funding_set(uint8_t value) + { + ThrowIfGameStateNotMutable(); + gResearchFundingLevel = std::clamp(value, RESEARCH_FUNDING_NONE, RESEARCH_FUNDING_MAXIMUM); + } + + std::vector ScResearch::priorities_get() const + { + std::vector result; + for (auto i = EnumValue(ResearchCategory::Transport); i <= EnumValue(ResearchCategory::SceneryGroup); i++) + { + auto category = static_cast(i); + if (gResearchPriorities & EnumToFlag(category)) + { + result.emplace_back(ResearchCategoryMap[category]); + } + } + return result; + } + + void ScResearch::priorities_set(const std::vector& values) + { + ThrowIfGameStateNotMutable(); + + auto priorities = 0; + for (const auto& value : values) + { + auto category = ResearchCategoryMap.TryGet(value); + if (category) + { + priorities |= EnumToFlag(*category); + } + } + gResearchPriorities = priorities; + } + + std::string ScResearch::stage_get() const + { + return std::string(ResearchStageMap[gResearchProgressStage]); + } + + void ScResearch::stage_set(const std::string& value) + { + ThrowIfGameStateNotMutable(); + auto it = ResearchStageMap.find(value); + if (it != ResearchStageMap.end()) + { + gResearchProgressStage = it->second; + } + } + + uint16_t ScResearch::progress_get() const + { + return gResearchProgress; + } + + void ScResearch::progress_set(uint16_t value) + { + ThrowIfGameStateNotMutable(); + gResearchProgress = value; + } + + DukValue ScResearch::expectedMonth_get() const + { + if (gResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH || gResearchExpectedDay == 255) + return ToDuk(_context, nullptr); + return ToDuk(_context, gResearchExpectedMonth); + } + + DukValue ScResearch::expectedDay_get() const + { + if (gResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH || gResearchExpectedDay == 255) + return ToDuk(_context, nullptr); + return ToDuk(_context, gResearchExpectedDay + 1); + } + + DukValue ScResearch::lastResearchedItem_get() const + { + if (!gResearchLastItem) + return ToDuk(_context, nullptr); + return ToDuk(_context, *gResearchLastItem); + } + + DukValue ScResearch::expectedItem_get() const + { + if (gResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH || !gResearchNextItem) + return ToDuk(_context, nullptr); + return ToDuk(_context, *gResearchNextItem); + } + + std::vector ScResearch::inventedItems_get() const + { + std::vector result; + for (auto& item : gResearchItemsInvented) + { + result.push_back(ToDuk(_context, item)); + } + return result; + } + + void ScResearch::inventedItems_set(const std::vector& value) + { + ThrowIfGameStateNotMutable(); + auto list = ConvertResearchList(value); + gResearchItemsInvented = std::move(list); + ResearchFix(); + } + + std::vector ScResearch::uninventedItems_get() const + { + std::vector result; + for (auto& item : gResearchItemsUninvented) + { + result.push_back(ToDuk(_context, item)); + } + return result; + } + + void ScResearch::uninventedItems_set(const std::vector& value) + { + ThrowIfGameStateNotMutable(); + auto list = ConvertResearchList(value); + gResearchItemsUninvented = std::move(list); + ResearchFix(); + } + + bool ScResearch::isObjectResearched(const std::string& typez, ObjectEntryIndex index) + { + auto result = false; + auto type = ScObject::StringToObjectType(typez); + if (type) + { + result = ResearchIsInvented(*type, index); + } + else + { + duk_error(_context, DUK_ERR_ERROR, "Invalid object type."); + } + return result; + } + + void ScResearch::Register(duk_context* ctx) + { + dukglue_register_property(ctx, &ScResearch::funding_get, &ScResearch::funding_set, "funding"); + dukglue_register_property(ctx, &ScResearch::priorities_get, &ScResearch::priorities_set, "priorities"); + dukglue_register_property(ctx, &ScResearch::stage_get, &ScResearch::stage_set, "stage"); + dukglue_register_property(ctx, &ScResearch::progress_get, &ScResearch::progress_set, "progress"); + dukglue_register_property(ctx, &ScResearch::expectedMonth_get, nullptr, "expectedMonth"); + dukglue_register_property(ctx, &ScResearch::expectedDay_get, nullptr, "expectedDay"); + dukglue_register_property(ctx, &ScResearch::lastResearchedItem_get, nullptr, "lastResearchedItem"); + dukglue_register_property(ctx, &ScResearch::expectedItem_get, nullptr, "expectedItem"); + dukglue_register_property(ctx, &ScResearch::inventedItems_get, &ScResearch::inventedItems_set, "inventedItems"); + dukglue_register_property(ctx, &ScResearch::uninventedItems_get, &ScResearch::uninventedItems_set, "uninventedItems"); + dukglue_register_method(ctx, &ScResearch::isObjectResearched, "isObjectResearched"); + } + + std::vector ScResearch::ConvertResearchList(const std::vector& value) + { + auto& objManager = GetContext()->GetObjectManager(); + std::vector result; + for (auto& item : value) + { + auto researchItem = FromDuk(item); + researchItem.flags = 0; + if (researchItem.type == Research::EntryType::Ride) + { + auto rideEntry = GetRideEntryByIndex(researchItem.entryIndex); + if (rideEntry != nullptr) + { + researchItem.category = GetRideTypeDescriptor(researchItem.baseRideType).GetResearchCategory(); + result.push_back(researchItem); + } + } + else + { + auto sceneryGroup = objManager.GetLoadedObject(ObjectType::SceneryGroup, researchItem.entryIndex); + if (sceneryGroup != nullptr) + { + researchItem.baseRideType = 0; + researchItem.category = ResearchCategory::SceneryGroup; + result.push_back(researchItem); + } + } + } + return result; + } +} // namespace OpenRCT2::Scripting + +#endif diff --git a/src/openrct2/scripting/bindings/world/ScResearch.hpp b/src/openrct2/scripting/bindings/world/ScResearch.hpp index daa3433d27..652d2eebae 100644 --- a/src/openrct2/scripting/bindings/world/ScResearch.hpp +++ b/src/openrct2/scripting/bindings/world/ScResearch.hpp @@ -11,281 +11,47 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Context.h" -# include "../../../common.h" -# include "../../../core/String.hpp" -# include "../../../management/Research.h" -# include "../../../ride/RideData.h" -# include "../../Duktape.hpp" # include "../../ScriptEngine.h" -# include "../object/ScObject.hpp" namespace OpenRCT2::Scripting { - static const DukEnumMap ResearchStageMap({ - { "initial_research", RESEARCH_STAGE_INITIAL_RESEARCH }, - { "designing", RESEARCH_STAGE_DESIGNING }, - { "completing_design", RESEARCH_STAGE_COMPLETING_DESIGN }, - { "unknown", RESEARCH_STAGE_UNKNOWN }, - { "finished_all", RESEARCH_STAGE_FINISHED_ALL }, - }); - - static const DukEnumMap ResearchCategoryMap({ - { "transport", ResearchCategory::Transport }, - { "gentle", ResearchCategory::Gentle }, - { "rollercoaster", ResearchCategory::Rollercoaster }, - { "thrill", ResearchCategory::Thrill }, - { "water", ResearchCategory::Water }, - { "shop", ResearchCategory::Shop }, - { "scenery", ResearchCategory::SceneryGroup }, - }); - - static const DukEnumMap ResearchEntryTypeMap({ - { "ride", Research::EntryType::Ride }, - { "scenery", Research::EntryType::Scenery }, - }); - - template<> inline DukValue ToDuk(duk_context* ctx, const ResearchItem& value) - { - DukObject obj(ctx); - obj.Set("category", ResearchCategoryMap[value.category]); - obj.Set("type", ResearchEntryTypeMap[value.type]); - if (value.type == Research::EntryType::Ride) - { - obj.Set("rideType", value.baseRideType); - } - obj.Set("object", value.entryIndex); - return obj.Take(); - } - - template<> Research::EntryType inline FromDuk(const DukValue& d) - { - if (d.type() == DukValue::STRING) - { - auto it = ResearchEntryTypeMap.find(d.as_string()); - if (it != ResearchEntryTypeMap.end()) - { - return it->second; - } - } - return Research::EntryType::Scenery; - } - - template<> ResearchItem inline FromDuk(const DukValue& d) - { - ResearchItem result; - result.baseRideType = 0; - result.category = {}; // We ignore category because it will be derived from ride type - result.flags = 0; - result.type = FromDuk(d["type"]); - auto baseRideType = d["rideType"]; - if (baseRideType.type() == DukValue::NUMBER) - result.baseRideType = baseRideType.as_int(); - result.entryIndex = d["object"].as_int(); - return result; - } - class ScResearch { private: duk_context* _context; public: - ScResearch(duk_context* ctx) - : _context(ctx) - { - } + ScResearch(duk_context* ctx); - uint8_t funding_get() const - { - return gResearchFundingLevel; - } + static void Register(duk_context* ctx); - void funding_set(uint8_t value) - { - ThrowIfGameStateNotMutable(); - gResearchFundingLevel = std::clamp(value, RESEARCH_FUNDING_NONE, RESEARCH_FUNDING_MAXIMUM); - } + private: + uint8_t funding_get() const; + void funding_set(uint8_t value); - std::vector priorities_get() const - { - std::vector result; - for (auto i = EnumValue(ResearchCategory::Transport); i <= EnumValue(ResearchCategory::SceneryGroup); i++) - { - auto category = static_cast(i); - if (gResearchPriorities & EnumToFlag(category)) - { - result.emplace_back(ResearchCategoryMap[category]); - } - } - return result; - } + std::vector priorities_get() const; + void priorities_set(const std::vector& values); - void priorities_set(const std::vector& values) - { - ThrowIfGameStateNotMutable(); + std::string stage_get() const; + void stage_set(const std::string& value); - auto priorities = 0; - for (const auto& value : values) - { - auto category = ResearchCategoryMap.TryGet(value); - if (category) - { - priorities |= EnumToFlag(*category); - } - } - gResearchPriorities = priorities; - } + uint16_t progress_get() const; + void progress_set(uint16_t value); - std::string stage_get() const - { - return std::string(ResearchStageMap[gResearchProgressStage]); - } + DukValue expectedMonth_get() const; + DukValue expectedDay_get() const; + DukValue lastResearchedItem_get() const; + DukValue expectedItem_get() const; - void stage_set(const std::string& value) - { - ThrowIfGameStateNotMutable(); - auto it = ResearchStageMap.find(value); - if (it != ResearchStageMap.end()) - { - gResearchProgressStage = it->second; - } - } + std::vector inventedItems_get() const; + void inventedItems_set(const std::vector& value); - uint16_t progress_get() const - { - return gResearchProgress; - } + std::vector uninventedItems_get() const; + void uninventedItems_set(const std::vector& value); - void progress_set(uint16_t value) - { - ThrowIfGameStateNotMutable(); - gResearchProgress = value; - } + bool isObjectResearched(const std::string& typez, ObjectEntryIndex index); - DukValue expectedMonth_get() const - { - if (gResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH || gResearchExpectedDay == 255) - return ToDuk(_context, nullptr); - return ToDuk(_context, gResearchExpectedMonth); - } - - DukValue expectedDay_get() const - { - if (gResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH || gResearchExpectedDay == 255) - return ToDuk(_context, nullptr); - return ToDuk(_context, gResearchExpectedDay + 1); - } - - DukValue lastResearchedItem_get() const - { - if (!gResearchLastItem) - return ToDuk(_context, nullptr); - return ToDuk(_context, *gResearchLastItem); - } - - DukValue expectedItem_get() const - { - if (gResearchProgressStage == RESEARCH_STAGE_INITIAL_RESEARCH || !gResearchNextItem) - return ToDuk(_context, nullptr); - return ToDuk(_context, *gResearchNextItem); - } - - std::vector inventedItems_get() const - { - std::vector result; - for (auto& item : gResearchItemsInvented) - { - result.push_back(ToDuk(_context, item)); - } - return result; - } - - void inventedItems_set(const std::vector& value) - { - auto list = ConvertResearchList(value); - gResearchItemsInvented = std::move(list); - ResearchFix(); - } - - std::vector uninventedItems_get() const - { - std::vector result; - for (auto& item : gResearchItemsUninvented) - { - result.push_back(ToDuk(_context, item)); - } - return result; - } - - void uninventedItems_set(const std::vector& value) - { - auto list = ConvertResearchList(value); - gResearchItemsUninvented = std::move(list); - ResearchFix(); - } - - bool isObjectResearched(const std::string& typez, ObjectEntryIndex index) - { - auto result = false; - auto type = ScObject::StringToObjectType(typez); - if (type) - { - result = ResearchIsInvented(*type, index); - } - else - { - duk_error(_context, DUK_ERR_ERROR, "Invalid object type."); - } - return result; - } - - static void Register(duk_context* ctx) - { - dukglue_register_property(ctx, &ScResearch::funding_get, &ScResearch::funding_set, "funding"); - dukglue_register_property(ctx, &ScResearch::priorities_get, &ScResearch::priorities_set, "priorities"); - dukglue_register_property(ctx, &ScResearch::stage_get, &ScResearch::stage_set, "stage"); - dukglue_register_property(ctx, &ScResearch::progress_get, &ScResearch::progress_set, "progress"); - dukglue_register_property(ctx, &ScResearch::expectedMonth_get, nullptr, "expectedMonth"); - dukglue_register_property(ctx, &ScResearch::expectedDay_get, nullptr, "expectedDay"); - dukglue_register_property(ctx, &ScResearch::lastResearchedItem_get, nullptr, "lastResearchedItem"); - dukglue_register_property(ctx, &ScResearch::expectedItem_get, nullptr, "expectedItem"); - dukglue_register_property(ctx, &ScResearch::inventedItems_get, &ScResearch::inventedItems_set, "inventedItems"); - dukglue_register_property( - ctx, &ScResearch::uninventedItems_get, &ScResearch::uninventedItems_set, "uninventedItems"); - dukglue_register_method(ctx, &ScResearch::isObjectResearched, "isObjectResearched"); - } - - static std::vector ConvertResearchList(const std::vector& value) - { - auto& objManager = GetContext()->GetObjectManager(); - std::vector result; - for (auto& item : value) - { - auto researchItem = FromDuk(item); - researchItem.flags = 0; - if (researchItem.type == Research::EntryType::Ride) - { - auto rideEntry = GetRideEntryByIndex(researchItem.entryIndex); - if (rideEntry != nullptr) - { - researchItem.category = GetRideTypeDescriptor(researchItem.baseRideType).GetResearchCategory(); - result.push_back(researchItem); - } - } - else - { - auto sceneryGroup = objManager.GetLoadedObject(ObjectType::SceneryGroup, researchItem.entryIndex); - if (sceneryGroup != nullptr) - { - researchItem.baseRideType = 0; - researchItem.category = ResearchCategory::SceneryGroup; - result.push_back(researchItem); - } - } - } - return result; - } + static std::vector ConvertResearchList(const std::vector& value); }; } // namespace OpenRCT2::Scripting