1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-17 21:12:34 +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: [#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: [#24009] [Plugin] The object manager API does not identify recently introduced object types.
0.4.20 (2025-02-25)
------------------------------------------------------------------------

View File

@@ -620,12 +620,17 @@ declare global {
"scenery_group" |
"park_entrance" |
"water" |
"scenario_text" |
"terrain_surface" |
"terrain_edge" |
"station" |
"music" |
"footpath_surface" |
"footpath_railings";
"footpath_railings" |
"audio" |
"peep_names" |
"peep_animations" |
"climate";
type HookType =
"action.execute" |
@@ -5362,7 +5367,6 @@ declare global {
getObject(type: "footpath_addition", index: number): FootpathAdditionObject;
getObject(type: "banner", index: number): BannerObject;
getObject(type: "scenery_group", index: number): SceneryGroupObject;
getObject(type: "music", index: number): LoadedObject;
/**
* Gets all the currently loaded objects for a given object type.
@@ -5376,7 +5380,6 @@ declare global {
getAllObjects(type: "footpath_addition"): FootpathAdditionObject[];
getAllObjects(type: "banner"): BannerObject[];
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\TitleSequenceManager.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\ScLitter.hpp" />
<ClInclude Include="scripting\bindings\entity\ScParticle.hpp" />
<ClInclude Include="scripting\bindings\entity\ScPeep.hpp" />
<ClInclude Include="scripting\bindings\entity\ScStaff.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\world\ScClimate.hpp" />
<ClInclude Include="scripting\bindings\game\ScConfiguration.hpp" />
<ClInclude Include="scripting\bindings\game\ScConsole.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\entity\ScEntity.hpp" />
<ClInclude Include="scripting\bindings\world\ScMap.hpp" />
<ClInclude Include="scripting\bindings\game\ScPlugin.hpp" />
<ClInclude Include="scripting\bindings\game\ScProfiler.hpp" />
<ClInclude Include="scripting\bindings\network\ScNetwork.hpp" />
<ClInclude Include="scripting\bindings\object\ScObject.hpp" />
<ClInclude Include="scripting\bindings\world\ScPark.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\ScPlayer.hpp" />
<ClInclude Include="scripting\bindings\network\ScPlayerGroup.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\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="System.hpp" />
<ClInclude Include="TrackImporter.h" />
@@ -1095,6 +1095,7 @@
<ClCompile Include="scripting\bindings\network\ScNetwork.cpp" />
<ClCompile Include="scripting\bindings\network\ScPlayer.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\ride\ScRide.cpp" />
<ClCompile Include="scripting\bindings\ride\ScRideStation.cpp" />
@@ -1152,4 +1153,4 @@
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
</Project>

View File

@@ -15,6 +15,7 @@
#include "../PlatformEnvironment.h"
#include "../audio/Audio.h"
#include "../core/Console.hpp"
#include "../core/EnumMap.hpp"
#include "../core/File.h"
#include "../core/FileStream.h"
#include "../core/Json.hpp"
@@ -404,50 +405,29 @@ namespace OpenRCT2::ObjectFactory
return result;
}
static ObjectType ParseObjectType(const std::string& s)
{
if (s == "ride")
return ObjectType::ride;
if (s == "footpath_banner")
return ObjectType::banners;
if (s == "footpath_item")
return ObjectType::pathAdditions;
if (s == "scenery_small")
return ObjectType::smallScenery;
if (s == "scenery_large")
return ObjectType::largeScenery;
if (s == "scenery_wall")
return ObjectType::walls;
if (s == "scenery_group")
return ObjectType::sceneryGroup;
if (s == "park_entrance")
return ObjectType::parkEntrance;
if (s == "water")
return ObjectType::water;
if (s == "scenario_text")
return ObjectType::scenarioText;
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;
}
static const EnumMap<ObjectType> kObjectTypeMap = {
{ "ride", ObjectType::ride },
{ "scenery_small", ObjectType::smallScenery },
{ "scenery_large", ObjectType::largeScenery },
{ "scenery_wall", ObjectType::walls },
{ "footpath_banner", ObjectType::banners },
{ "footpath_legacy", ObjectType::paths },
{ "footpath_item", 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::unique_ptr<Object> CreateObjectFromZipFile(IObjectRepository& objectRepository, std::string_view path, bool loadImages)
{
@@ -544,9 +524,10 @@ namespace OpenRCT2::ObjectFactory
std::unique_ptr<Object> result;
auto objectType = ParseObjectType(Json::GetString(jRoot["objectType"]));
if (objectType != ObjectType::none)
auto lookup = kObjectTypeMap.find(Json::GetString(jRoot["objectType"]));
if (lookup != kObjectTypeMap.end())
{
auto objectType = lookup->second;
auto id = Json::GetString(jRoot["id"]);
// 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 <optional>
#include <string_view>
namespace OpenRCT2::Scripting
{
inline std::string_view ObjectTypeToString(uint8_t type)
{
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];
}
std::string_view objectTypeToString(ObjectType type);
ObjectType objectTypeFromString(std::string_view string);
inline std::string_view ObjectSourceGameToString(ObjectSourceGame sourceGame)
{
@@ -122,7 +100,7 @@ namespace OpenRCT2::Scripting
auto installedObject = GetInstalledObject();
if (installedObject != nullptr)
{
return std::string(ObjectTypeToString(EnumValue(installedObject->Type)));
return std::string(objectTypeToString(installedObject->Type));
}
return {};
}

View File

@@ -51,19 +51,6 @@ namespace OpenRCT2::Scripting
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:
std::shared_ptr<ScInstalledObject> installedObject_get() const
{
@@ -82,7 +69,7 @@ namespace OpenRCT2::Scripting
std::string type_get() const
{
return std::string(ObjectTypeToString(EnumValue(_type)));
return std::string(objectTypeToString(_type));
}
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)
{
const auto& szP1 = p1.as_string();
auto objType = ScObject::StringToObjectType(szP1);
if (objType)
auto objType = objectTypeFromString(szP1);
if (objType != ObjectType::none)
{
// unload(type, index)
if (p2.type() != DukValue::NUMBER)
throw DukException() << "'index' is invalid.";
auto objIndex = p2.as_uint();
auto obj = objectManager.GetLoadedObject(*objType, objIndex);
auto obj = objectManager.GetLoadedObject(objType, objIndex);
if (obj != nullptr)
{
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& objManager = GetContext()->GetObjectManager();
auto type = ScObject::StringToObjectType(typez);
if (type)
auto type = objectTypeFromString(typez);
if (type != ObjectType::none)
{
auto obj = objManager.GetLoadedObject(*type, index);
auto obj = objManager.GetLoadedObject(type, index);
if (obj != nullptr)
{
return CreateScObject(ctx, *type, index);
return CreateScObject(ctx, type, index);
}
}
else
@@ -220,16 +220,16 @@ std::vector<DukValue> ScObjectManager::getAllObjects(const std::string& typez) c
auto& objManager = GetContext()->GetObjectManager();
std::vector<DukValue> result;
auto type = ScObject::StringToObjectType(typez);
if (type)
auto type = objectTypeFromString(typez);
if (type != ObjectType::none)
{
auto count = getObjectEntryGroupCount(*type);
auto count = getObjectEntryGroupCount(type);
for (auto i = 0u; i < count; i++)
{
auto obj = objManager.GetLoadedObject(*type, i);
auto obj = objManager.GetLoadedObject(type, i);
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)
{
auto result = false;
auto type = ScObject::StringToObjectType(typez);
if (type)
auto type = objectTypeFromString(typez);
if (type != ObjectType::none)
{
result = ResearchIsInvented(*type, index);
result = ResearchIsInvented(type, index);
}
else
{