1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-18 05:22:42 +01:00

Update object manager API to access new object types (#24009)

* Update object manager API to access new object types

* Use separate mapping for scripting due to different type names

* Amend changelog
This commit is contained in:
Aaron van Geffen
2025-03-20 00:16:08 +01:00
committed by GitHub
parent 1ea87b93f1
commit 0a3e9fdfd9
9 changed files with 134 additions and 130 deletions

View File

@@ -23,6 +23,7 @@
- Fix: [#23960] Corner path fences can draw over adjacent sloped land (original bug). - Fix: [#23960] Corner path fences can draw over adjacent sloped land (original bug).
- Fix: [#23961] Lamps and queue line tvs draw incorrectly on paths with fences. - Fix: [#23961] Lamps and queue line tvs draw incorrectly on paths with fences.
- Fix: [#23983] Ordering files by size does not work and occasionally crashes the game. - Fix: [#23983] Ordering files by size does not work and occasionally crashes the game.
- Fix: [#24009] [Plugin] The object manager API does not identify recently introduced object types.
0.4.20 (2025-02-25) 0.4.20 (2025-02-25)
------------------------------------------------------------------------ ------------------------------------------------------------------------

View File

@@ -620,12 +620,17 @@ declare global {
"scenery_group" | "scenery_group" |
"park_entrance" | "park_entrance" |
"water" | "water" |
"scenario_text" |
"terrain_surface" | "terrain_surface" |
"terrain_edge" | "terrain_edge" |
"station" | "station" |
"music" | "music" |
"footpath_surface" | "footpath_surface" |
"footpath_railings"; "footpath_railings" |
"audio" |
"peep_names" |
"peep_animations" |
"climate";
type HookType = type HookType =
"action.execute" | "action.execute" |
@@ -5362,7 +5367,6 @@ declare global {
getObject(type: "footpath_addition", index: number): FootpathAdditionObject; getObject(type: "footpath_addition", index: number): FootpathAdditionObject;
getObject(type: "banner", index: number): BannerObject; getObject(type: "banner", index: number): BannerObject;
getObject(type: "scenery_group", index: number): SceneryGroupObject; getObject(type: "scenery_group", index: number): SceneryGroupObject;
getObject(type: "music", index: number): LoadedObject;
/** /**
* Gets all the currently loaded objects for a given object type. * Gets all the currently loaded objects for a given object type.
@@ -5376,7 +5380,6 @@ declare global {
getAllObjects(type: "footpath_addition"): FootpathAdditionObject[]; getAllObjects(type: "footpath_addition"): FootpathAdditionObject[];
getAllObjects(type: "banner"): BannerObject[]; getAllObjects(type: "banner"): BannerObject[];
getAllObjects(type: "scenery_group"): SceneryGroupObject[]; getAllObjects(type: "scenery_group"): SceneryGroupObject[];
getAllObjects(type: "music"): LoadedObject[];
} }
/** /**

View File

@@ -560,45 +560,45 @@
<ClInclude Include="scenes\title\TitleSequence.h" /> <ClInclude Include="scenes\title\TitleSequence.h" />
<ClInclude Include="scenes\title\TitleSequenceManager.h" /> <ClInclude Include="scenes\title\TitleSequenceManager.h" />
<ClInclude Include="scenes\title\TitleSequencePlayer.h" /> <ClInclude Include="scenes\title\TitleSequencePlayer.h" />
<ClInclude Include="scripting\bindings\entity\ScEntity.hpp" />
<ClInclude Include="scripting\bindings\entity\ScGuest.hpp" /> <ClInclude Include="scripting\bindings\entity\ScGuest.hpp" />
<ClInclude Include="scripting\bindings\entity\ScLitter.hpp" /> <ClInclude Include="scripting\bindings\entity\ScLitter.hpp" />
<ClInclude Include="scripting\bindings\entity\ScParticle.hpp" /> <ClInclude Include="scripting\bindings\entity\ScParticle.hpp" />
<ClInclude Include="scripting\bindings\entity\ScPeep.hpp" /> <ClInclude Include="scripting\bindings\entity\ScPeep.hpp" />
<ClInclude Include="scripting\bindings\entity\ScStaff.hpp" /> <ClInclude Include="scripting\bindings\entity\ScStaff.hpp" />
<ClInclude Include="scripting\bindings\entity\ScVehicle.hpp" /> <ClInclude Include="scripting\bindings\entity\ScVehicle.hpp" />
<ClInclude Include="scripting\bindings\game\ScPlugin.hpp" />
<ClInclude Include="scripting\bindings\game\ScProfiler.hpp" />
<ClInclude Include="scripting\bindings\network\ScPlayer.hpp" />
<ClInclude Include="scripting\bindings\network\ScPlayerGroup.hpp" />
<ClInclude Include="scripting\bindings\object\ScInstalledObject.hpp" />
<ClInclude Include="scripting\bindings\object\ScObjectManager.h" />
<ClInclude Include="scripting\bindings\ride\ScRideStation.hpp" />
<ClInclude Include="scripting\bindings\ride\ScTrackIterator.h" />
<ClInclude Include="scripting\bindings\ride\ScTrackSegment.h" />
<ClInclude Include="scripting\bindings\world\ScParkMessage.hpp" />
<ClInclude Include="scripting\bindings\world\ScResearch.hpp" />
<ClInclude Include="scripting\bindings\world\ScTileElement.hpp" />
<ClInclude Include="scripting\Duktape.hpp" />
<ClInclude Include="scripting\IconNames.hpp" />
<ClInclude Include="scripting\HookEngine.h" />
<ClInclude Include="scripting\Plugin.h" />
<ClInclude Include="scripting\bindings\game\ScCheats.hpp" /> <ClInclude Include="scripting\bindings\game\ScCheats.hpp" />
<ClInclude Include="scripting\bindings\world\ScClimate.hpp" />
<ClInclude Include="scripting\bindings\game\ScConfiguration.hpp" /> <ClInclude Include="scripting\bindings\game\ScConfiguration.hpp" />
<ClInclude Include="scripting\bindings\game\ScConsole.hpp" /> <ClInclude Include="scripting\bindings\game\ScConsole.hpp" />
<ClInclude Include="scripting\bindings\game\ScContext.hpp" /> <ClInclude Include="scripting\bindings\game\ScContext.hpp" />
<ClInclude Include="scripting\bindings\world\ScDate.hpp" />
<ClInclude Include="scripting\bindings\game\ScDisposable.hpp" /> <ClInclude Include="scripting\bindings\game\ScDisposable.hpp" />
<ClInclude Include="scripting\bindings\entity\ScEntity.hpp" /> <ClInclude Include="scripting\bindings\game\ScPlugin.hpp" />
<ClInclude Include="scripting\bindings\world\ScMap.hpp" /> <ClInclude Include="scripting\bindings\game\ScProfiler.hpp" />
<ClInclude Include="scripting\bindings\network\ScNetwork.hpp" /> <ClInclude Include="scripting\bindings\network\ScNetwork.hpp" />
<ClInclude Include="scripting\bindings\object\ScObject.hpp" /> <ClInclude Include="scripting\bindings\network\ScPlayer.hpp" />
<ClInclude Include="scripting\bindings\world\ScPark.hpp" /> <ClInclude Include="scripting\bindings\network\ScPlayerGroup.hpp" />
<ClInclude Include="scripting\bindings\ride\ScRide.hpp" />
<ClInclude Include="scripting\ScriptEngine.h" />
<ClInclude Include="scripting\bindings\world\ScScenario.hpp" />
<ClInclude Include="scripting\bindings\network\ScSocket.hpp" /> <ClInclude Include="scripting\bindings\network\ScSocket.hpp" />
<ClInclude Include="scripting\bindings\object\ScInstalledObject.hpp" />
<ClInclude Include="scripting\bindings\object\ScObject.hpp" />
<ClInclude Include="scripting\bindings\object\ScObjectManager.h" />
<ClInclude Include="scripting\bindings\ride\ScRide.hpp" />
<ClInclude Include="scripting\bindings\ride\ScRideStation.hpp" />
<ClInclude Include="scripting\bindings\ride\ScTrackIterator.h" />
<ClInclude Include="scripting\bindings\ride\ScTrackSegment.h" />
<ClInclude Include="scripting\bindings\world\ScClimate.hpp" />
<ClInclude Include="scripting\bindings\world\ScDate.hpp" />
<ClInclude Include="scripting\bindings\world\ScMap.hpp" />
<ClInclude Include="scripting\bindings\world\ScPark.hpp" />
<ClInclude Include="scripting\bindings\world\ScParkMessage.hpp" />
<ClInclude Include="scripting\bindings\world\ScResearch.hpp" />
<ClInclude Include="scripting\bindings\world\ScScenario.hpp" />
<ClInclude Include="scripting\bindings\world\ScTile.hpp" /> <ClInclude Include="scripting\bindings\world\ScTile.hpp" />
<ClInclude Include="scripting\bindings\world\ScTileElement.hpp" />
<ClInclude Include="scripting\Duktape.hpp" />
<ClInclude Include="scripting\HookEngine.h" />
<ClInclude Include="scripting\IconNames.hpp" />
<ClInclude Include="scripting\Plugin.h" />
<ClInclude Include="scripting\ScriptEngine.h" />
<ClInclude Include="SpriteIds.h" /> <ClInclude Include="SpriteIds.h" />
<ClInclude Include="System.hpp" /> <ClInclude Include="System.hpp" />
<ClInclude Include="TrackImporter.h" /> <ClInclude Include="TrackImporter.h" />
@@ -1095,6 +1095,7 @@
<ClCompile Include="scripting\bindings\network\ScNetwork.cpp" /> <ClCompile Include="scripting\bindings\network\ScNetwork.cpp" />
<ClCompile Include="scripting\bindings\network\ScPlayer.cpp" /> <ClCompile Include="scripting\bindings\network\ScPlayer.cpp" />
<ClCompile Include="scripting\bindings\network\ScPlayerGroup.cpp" /> <ClCompile Include="scripting\bindings\network\ScPlayerGroup.cpp" />
<ClCompile Include="scripting\bindings\object\ScInstalledObject.cpp" />
<ClCompile Include="scripting\bindings\object\ScObjectManager.cpp" /> <ClCompile Include="scripting\bindings\object\ScObjectManager.cpp" />
<ClCompile Include="scripting\bindings\ride\ScRide.cpp" /> <ClCompile Include="scripting\bindings\ride\ScRide.cpp" />
<ClCompile Include="scripting\bindings\ride\ScRideStation.cpp" /> <ClCompile Include="scripting\bindings\ride\ScRideStation.cpp" />
@@ -1152,4 +1153,4 @@
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project> </Project>

View File

@@ -15,6 +15,7 @@
#include "../PlatformEnvironment.h" #include "../PlatformEnvironment.h"
#include "../audio/Audio.h" #include "../audio/Audio.h"
#include "../core/Console.hpp" #include "../core/Console.hpp"
#include "../core/EnumMap.hpp"
#include "../core/File.h" #include "../core/File.h"
#include "../core/FileStream.h" #include "../core/FileStream.h"
#include "../core/Json.hpp" #include "../core/Json.hpp"
@@ -404,50 +405,29 @@ namespace OpenRCT2::ObjectFactory
return result; return result;
} }
static ObjectType ParseObjectType(const std::string& s) static const EnumMap<ObjectType> kObjectTypeMap = {
{ { "ride", ObjectType::ride },
if (s == "ride") { "scenery_small", ObjectType::smallScenery },
return ObjectType::ride; { "scenery_large", ObjectType::largeScenery },
if (s == "footpath_banner") { "scenery_wall", ObjectType::walls },
return ObjectType::banners; { "footpath_banner", ObjectType::banners },
if (s == "footpath_item") { "footpath_legacy", ObjectType::paths },
return ObjectType::pathAdditions; { "footpath_item", ObjectType::pathAdditions },
if (s == "scenery_small") { "scenery_group", ObjectType::sceneryGroup },
return ObjectType::smallScenery; { "park_entrance", ObjectType::parkEntrance },
if (s == "scenery_large") { "water", ObjectType::water },
return ObjectType::largeScenery; { "scenario_text", ObjectType::scenarioText },
if (s == "scenery_wall") { "terrain_surface", ObjectType::terrainSurface },
return ObjectType::walls; { "terrain_edge", ObjectType::terrainEdge },
if (s == "scenery_group") { "station", ObjectType::station },
return ObjectType::sceneryGroup; { "music", ObjectType::music },
if (s == "park_entrance") { "footpath_surface", ObjectType::footpathSurface },
return ObjectType::parkEntrance; { "footpath_railings", ObjectType::footpathRailings },
if (s == "water") { "audio", ObjectType::audio },
return ObjectType::water; { "peep_names", ObjectType::peepNames },
if (s == "scenario_text") { "peep_animations", ObjectType::peepAnimations },
return ObjectType::scenarioText; { "climate", ObjectType::climate },
if (s == "terrain_surface") };
return ObjectType::terrainSurface;
if (s == "terrain_edge")
return ObjectType::terrainEdge;
if (s == "station")
return ObjectType::station;
if (s == "music")
return ObjectType::music;
if (s == "footpath_surface")
return ObjectType::footpathSurface;
if (s == "footpath_railings")
return ObjectType::footpathRailings;
if (s == "audio")
return ObjectType::audio;
if (s == "peep_names")
return ObjectType::peepNames;
if (s == "peep_animations")
return ObjectType::peepAnimations;
if (s == "climate")
return ObjectType::climate;
return ObjectType::none;
}
std::unique_ptr<Object> CreateObjectFromZipFile(IObjectRepository& objectRepository, std::string_view path, bool loadImages) std::unique_ptr<Object> CreateObjectFromZipFile(IObjectRepository& objectRepository, std::string_view path, bool loadImages)
{ {
@@ -544,9 +524,10 @@ namespace OpenRCT2::ObjectFactory
std::unique_ptr<Object> result; std::unique_ptr<Object> result;
auto objectType = ParseObjectType(Json::GetString(jRoot["objectType"])); auto lookup = kObjectTypeMap.find(Json::GetString(jRoot["objectType"]));
if (objectType != ObjectType::none) if (lookup != kObjectTypeMap.end())
{ {
auto objectType = lookup->second;
auto id = Json::GetString(jRoot["id"]); auto id = Json::GetString(jRoot["id"]);
// Base audio files are renamed to a common, virtual name so asset packs can override it correctly. // Base audio files are renamed to a common, virtual name so asset packs can override it correctly.

View File

@@ -0,0 +1,53 @@
/*****************************************************************************
* Copyright (c) 2014-2025 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 "ScObject.hpp"
namespace OpenRCT2::Scripting
{
static const EnumMap<ObjectType> kObjectTypeMap = {
{ "ride", ObjectType::ride },
{ "small_scenery", ObjectType::smallScenery },
{ "large_scenery", ObjectType::largeScenery },
{ "wall", ObjectType::walls },
{ "banner", ObjectType::banners },
{ "footpath", ObjectType::paths },
{ "footpath_addition", ObjectType::pathAdditions },
{ "scenery_group", ObjectType::sceneryGroup },
{ "park_entrance", ObjectType::parkEntrance },
{ "water", ObjectType::water },
{ "scenario_text", ObjectType::scenarioText },
{ "terrain_surface", ObjectType::terrainSurface },
{ "terrain_edge", ObjectType::terrainEdge },
{ "station", ObjectType::station },
{ "music", ObjectType::music },
{ "footpath_surface", ObjectType::footpathSurface },
{ "footpath_railings", ObjectType::footpathRailings },
{ "audio", ObjectType::audio },
{ "peep_names", ObjectType::peepNames },
{ "peep_animations", ObjectType::peepAnimations },
{ "climate", ObjectType::climate },
};
std::string_view objectTypeToString(ObjectType type)
{
auto result = kObjectTypeMap.find(type);
return result != kObjectTypeMap.end() ? result->first : "";
}
ObjectType objectTypeFromString(std::string_view string)
{
auto result = kObjectTypeMap.find(string);
return result != kObjectTypeMap.end() ? result->second : ObjectType::none;
}
} // namespace OpenRCT2::Scripting
#endif

View File

@@ -17,34 +17,12 @@
#include "../../ScriptEngine.h" #include "../../ScriptEngine.h"
#include <optional> #include <optional>
#include <string_view>
namespace OpenRCT2::Scripting namespace OpenRCT2::Scripting
{ {
inline std::string_view ObjectTypeToString(uint8_t type) std::string_view objectTypeToString(ObjectType type);
{ ObjectType objectTypeFromString(std::string_view string);
static constexpr std::string_view Types[] = {
"ride",
"small_scenery",
"large_scenery",
"wall",
"banner",
"footpath",
"footpath_addition",
"scenery_group",
"park_entrance",
"water",
"stex",
"terrain_surface",
"terrain_edge",
"station",
"music",
"footpath_surface",
"footpath_railings",
};
if (type >= std::size(Types))
return "unknown";
return Types[type];
}
inline std::string_view ObjectSourceGameToString(ObjectSourceGame sourceGame) inline std::string_view ObjectSourceGameToString(ObjectSourceGame sourceGame)
{ {
@@ -122,7 +100,7 @@ namespace OpenRCT2::Scripting
auto installedObject = GetInstalledObject(); auto installedObject = GetInstalledObject();
if (installedObject != nullptr) if (installedObject != nullptr)
{ {
return std::string(ObjectTypeToString(EnumValue(installedObject->Type))); return std::string(objectTypeToString(installedObject->Type));
} }
return {}; return {};
} }

View File

@@ -51,19 +51,6 @@ namespace OpenRCT2::Scripting
dukglue_register_property(ctx, &ScObject::numImages_get, nullptr, "numImages"); dukglue_register_property(ctx, &ScObject::numImages_get, nullptr, "numImages");
} }
static std::optional<ObjectType> StringToObjectType(std::string_view type)
{
for (uint8_t i = 0; i < EnumValue(ObjectType::count); i++)
{
auto s = ObjectTypeToString(i);
if (s == type)
{
return static_cast<ObjectType>(i);
}
}
return std::nullopt;
}
private: private:
std::shared_ptr<ScInstalledObject> installedObject_get() const std::shared_ptr<ScInstalledObject> installedObject_get() const
{ {
@@ -82,7 +69,7 @@ namespace OpenRCT2::Scripting
std::string type_get() const std::string type_get() const
{ {
return std::string(ObjectTypeToString(EnumValue(_type))); return std::string(objectTypeToString(_type));
} }
int32_t index_get() const int32_t index_get() const

View File

@@ -157,15 +157,15 @@ void ScObjectManager::unload(const DukValue& p1, const DukValue& p2)
if (p1.type() == DukValue::STRING) if (p1.type() == DukValue::STRING)
{ {
const auto& szP1 = p1.as_string(); const auto& szP1 = p1.as_string();
auto objType = ScObject::StringToObjectType(szP1); auto objType = objectTypeFromString(szP1);
if (objType) if (objType != ObjectType::none)
{ {
// unload(type, index) // unload(type, index)
if (p2.type() != DukValue::NUMBER) if (p2.type() != DukValue::NUMBER)
throw DukException() << "'index' is invalid."; throw DukException() << "'index' is invalid.";
auto objIndex = p2.as_uint(); auto objIndex = p2.as_uint();
auto obj = objectManager.GetLoadedObject(*objType, objIndex); auto obj = objectManager.GetLoadedObject(objType, objIndex);
if (obj != nullptr) if (obj != nullptr)
{ {
objectManager.UnloadObjects({ obj->GetDescriptor() }); objectManager.UnloadObjects({ obj->GetDescriptor() });
@@ -198,13 +198,13 @@ DukValue ScObjectManager::getObject(const std::string& typez, int32_t index) con
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
auto& objManager = GetContext()->GetObjectManager(); auto& objManager = GetContext()->GetObjectManager();
auto type = ScObject::StringToObjectType(typez); auto type = objectTypeFromString(typez);
if (type) if (type != ObjectType::none)
{ {
auto obj = objManager.GetLoadedObject(*type, index); auto obj = objManager.GetLoadedObject(type, index);
if (obj != nullptr) if (obj != nullptr)
{ {
return CreateScObject(ctx, *type, index); return CreateScObject(ctx, type, index);
} }
} }
else else
@@ -220,16 +220,16 @@ std::vector<DukValue> ScObjectManager::getAllObjects(const std::string& typez) c
auto& objManager = GetContext()->GetObjectManager(); auto& objManager = GetContext()->GetObjectManager();
std::vector<DukValue> result; std::vector<DukValue> result;
auto type = ScObject::StringToObjectType(typez); auto type = objectTypeFromString(typez);
if (type) if (type != ObjectType::none)
{ {
auto count = getObjectEntryGroupCount(*type); auto count = getObjectEntryGroupCount(type);
for (auto i = 0u; i < count; i++) for (auto i = 0u; i < count; i++)
{ {
auto obj = objManager.GetLoadedObject(*type, i); auto obj = objManager.GetLoadedObject(type, i);
if (obj != nullptr) if (obj != nullptr)
{ {
result.push_back(CreateScObject(ctx, *type, i)); result.push_back(CreateScObject(ctx, type, i));
} }
} }
} }

View File

@@ -233,10 +233,10 @@ namespace OpenRCT2::Scripting
bool ScResearch::isObjectResearched(const std::string& typez, ObjectEntryIndex index) bool ScResearch::isObjectResearched(const std::string& typez, ObjectEntryIndex index)
{ {
auto result = false; auto result = false;
auto type = ScObject::StringToObjectType(typez); auto type = objectTypeFromString(typez);
if (type) if (type != ObjectType::none)
{ {
result = ResearchIsInvented(*type, index); result = ResearchIsInvented(type, index);
} }
else else
{ {