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:
@@ -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)
|
||||
------------------------------------------------------------------------
|
||||
|
||||
9
distribution/openrct2.d.ts
vendored
9
distribution/openrct2.d.ts
vendored
@@ -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[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
|
||||
53
src/openrct2/scripting/bindings/object/ScInstalledObject.cpp
Normal file
53
src/openrct2/scripting/bindings/object/ScInstalledObject.cpp
Normal 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
|
||||
@@ -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 {};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user