diff --git a/distribution/changelog.txt b/distribution/changelog.txt index c9a0712f93..e6f4063956 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -12,6 +12,7 @@ - Fix: [#16934] Park size displayed incorrectly in Park window. - Fix: [#16974] Small scenery ghosts can be deleted. - Fix: [#17005] Unable to set patrol area for first staff member in park. +- Fix: [#17017] [Plugin] Crash when using tile element properties that require a valid ride to be linked. - Fix: [#17073] Corrupt ride window and random crashes when trains have more than 144 cars. - Fix: [#17080] “Remove litter” cheat does not empty litter bins. - Fix: [#17099] Object selection thumbnail box is one pixel too tall. diff --git a/src/openrct2/scripting/ScriptEngine.cpp b/src/openrct2/scripting/ScriptEngine.cpp index 52b8987b51..070f611806 100644 --- a/src/openrct2/scripting/ScriptEngine.cpp +++ b/src/openrct2/scripting/ScriptEngine.cpp @@ -915,6 +915,12 @@ DukValue ScriptEngine::ExecutePluginCall( return DukValue(); } +void ScriptEngine::LogPluginInfo(std::string_view message) +{ + auto plugin = _execInfo.GetCurrentPlugin(); + LogPluginInfo(plugin, message); +} + void ScriptEngine::LogPluginInfo(const std::shared_ptr& plugin, std::string_view message) { if (plugin == nullptr) diff --git a/src/openrct2/scripting/ScriptEngine.h b/src/openrct2/scripting/ScriptEngine.h index ffae1f169f..cdf95effe2 100644 --- a/src/openrct2/scripting/ScriptEngine.h +++ b/src/openrct2/scripting/ScriptEngine.h @@ -46,7 +46,7 @@ namespace OpenRCT2 namespace OpenRCT2::Scripting { - static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 52; + static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 53; // Versions marking breaking changes. static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33; @@ -224,6 +224,7 @@ namespace OpenRCT2::Scripting std::shared_ptr plugin, const DukValue& func, const DukValue& thisValue, const std::vector& args, bool isGameStateMutable); + void LogPluginInfo(std::string_view message); void LogPluginInfo(const std::shared_ptr& plugin, std::string_view message); void SubscribeToPluginStoppedEvent(std::function)> callback) diff --git a/src/openrct2/scripting/bindings/world/ScTileElement.cpp b/src/openrct2/scripting/bindings/world/ScTileElement.cpp index e595fd6e5d..37a12f6326 100644 --- a/src/openrct2/scripting/bindings/world/ScTileElement.cpp +++ b/src/openrct2/scripting/bindings/world/ScTileElement.cpp @@ -80,7 +80,8 @@ namespace OpenRCT2::Scripting _element->SetType(TileElementType::Banner); else { - std::puts("Element type not recognised!"); + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo("Element type not recognised!"); return; } @@ -133,23 +134,26 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::slope_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); switch (_element->GetType()) { case TileElementType::Surface: { - auto el = _element->AsSurface(); + auto* el = _element->AsSurface(); duk_push_int(ctx, el->GetSlope()); break; } case TileElementType::Wall: { - auto el = _element->AsWall(); + auto* el = _element->AsWall(); duk_push_int(ctx, el->GetSlope()); break; } default: { + scriptEngine.LogPluginInfo( + "Cannot read 'slope' property, tile element is not a SurfaceElement or WallElement."); duk_push_null(ctx); break; } @@ -163,619 +167,923 @@ namespace OpenRCT2::Scripting if (type == TileElementType::Surface) { - auto el = _element->AsSurface(); + auto* el = _element->AsSurface(); el->SetSlope(value); Invalidate(); } else if (type == TileElementType::Wall) { - auto el = _element->AsWall(); + auto* el = _element->AsWall(); el->SetSlope(value); Invalidate(); } + else + { + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo("Cannot set 'slope' property, tile element is not a SurfaceElement or WallElement."); + } } DukValue ScTileElement::waterHeight_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsSurface(); if (el != nullptr) + { duk_push_int(ctx, el->GetWaterHeight()); + } else + { + scriptEngine.LogPluginInfo("Cannot read 'waterHeight' property, tile element is not a SurfaceElement."); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::waterHeight_set(int32_t value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsSurface(); - if (el != nullptr) + auto* el = _element->AsSurface(); + if (el == nullptr) { - el->SetWaterHeight(value); - Invalidate(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo("Cannot set 'waterHeight' property, tile element is not a SurfaceElement."); + return; } + + el->SetWaterHeight(value); + Invalidate(); } DukValue ScTileElement::surfaceStyle_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsSurface(); if (el != nullptr) + { duk_push_int(ctx, el->GetSurfaceStyle()); + } else + { + scriptEngine.LogPluginInfo("Cannot read 'surfaceStyle' property, tile element is not a SurfaceElement."); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::surfaceStyle_set(uint32_t value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsSurface(); - if (el != nullptr) + auto* el = _element->AsSurface(); + if (el == nullptr) { - el->SetSurfaceStyle(value); - Invalidate(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo("Cannot set 'surfaceStyle' property, tile element is not a SurfaceElement."); + return; } + + el->SetSurfaceStyle(value); + Invalidate(); } DukValue ScTileElement::edgeStyle_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsSurface(); if (el != nullptr) + { duk_push_int(ctx, el->GetEdgeStyle()); + } else + { + scriptEngine.LogPluginInfo("Cannot read 'edgeStyle' property, tile element is not a SurfaceElement."); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::edgeStyle_set(uint32_t value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsSurface(); - if (el != nullptr) + auto* el = _element->AsSurface(); + if (el == nullptr) { - el->SetEdgeStyle(value); - Invalidate(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo("Cannot set 'edgeStyle' property, tile element is not a SurfaceElement."); + return; } + + el->SetEdgeStyle(value); + Invalidate(); } DukValue ScTileElement::grassLength_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsSurface(); if (el != nullptr) + { duk_push_int(ctx, el->GetGrassLength()); + } else + { + scriptEngine.LogPluginInfo("Cannot read 'grassLength' property, tile element is not a SurfaceElement."); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::grassLength_set(uint8_t value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsSurface(); - if (el != nullptr) + auto* el = _element->AsSurface(); + if (el == nullptr) { - // TODO: Give warning when value > GRASS_LENGTH_CLUMPS_2 - el->SetGrassLengthAndInvalidate(value, _coords); - Invalidate(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo("Cannot set 'grassLength' property, tile element is not a SurfaceElement."); + return; } + + // TODO: Give warning when value > GRASS_LENGTH_CLUMPS_2 + el->SetGrassLengthAndInvalidate(value, _coords); + Invalidate(); } DukValue ScTileElement::hasOwnership_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsSurface(); if (el != nullptr) + { duk_push_boolean(ctx, el->GetOwnership() & OWNERSHIP_OWNED); + } else + { + scriptEngine.LogPluginInfo("Cannot read 'hasOwnership' property, tile element is not a SurfaceElement."); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } DukValue ScTileElement::hasConstructionRights_get() { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsSurface(); if (el != nullptr) { auto ownership = el->GetOwnership(); duk_push_boolean(ctx, (ownership & OWNERSHIP_OWNED) || (ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)); } else + { + scriptEngine.LogPluginInfo("Cannot read 'hasConstructionRights' property, tile element is not a SurfaceElement."); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } DukValue ScTileElement::ownership_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsSurface(); if (el != nullptr) + { duk_push_int(ctx, el->GetOwnership()); + } else + { + scriptEngine.LogPluginInfo("Cannot read 'ownership' property, tile element is not a SurfaceElement."); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::ownership_set(uint8_t value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsSurface(); - if (el != nullptr) + auto* el = _element->AsSurface(); + if (el == nullptr) { - el->SetOwnership(value); - Invalidate(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo("Cannot set 'ownership' property, tile element is not a SurfaceElement."); + return; } + + el->SetOwnership(value); + Invalidate(); } DukValue ScTileElement::parkFences_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSurface(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsSurface(); if (el != nullptr) + { duk_push_int(ctx, el->GetParkFences()); + } else + { + scriptEngine.LogPluginInfo("Cannot read 'parkFences' property, tile element is not a SurfaceElement."); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::parkFences_set(uint8_t value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsSurface(); - if (el != nullptr) + auto* el = _element->AsSurface(); + if (el == nullptr) { - el->SetParkFences(value); - Invalidate(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo("Cannot set 'parkFences' property, tile element is not a SurfaceElement."); + return; } + + el->SetParkFences(value); + Invalidate(); } DukValue ScTileElement::trackType_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsTrack(); if (el != nullptr) + { duk_push_int(ctx, el->GetTrackType()); + } else + { + scriptEngine.LogPluginInfo("Cannot read 'trackType' property, tile element is not a TrackElement."); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::trackType_set(uint16_t value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) + auto* el = _element->AsTrack(); + if (el == nullptr) { - el->SetTrackType(value); - Invalidate(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo("Cannot set 'trackType' property, tile element is not a TrackElement."); + return; } + + el->SetTrackType(value); + Invalidate(); } DukValue ScTileElement::rideType_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsTrack(); if (el != nullptr) + { duk_push_int(ctx, el->GetRideType()); + } else + { + scriptEngine.LogPluginInfo("Cannot set 'rideType' property, tile element is not a TrackElement."); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::rideType_set(uint16_t value) { ThrowIfGameStateNotMutable(); - if (value < RIDE_TYPE_COUNT) + + try { - auto el = _element->AsTrack(); - if (el != nullptr) - { - el->SetRideType(value); - Invalidate(); - } + if (value < RIDE_TYPE_COUNT) + throw DukException() << "'rideType' value is invalid."; + + auto* el = _element->AsTrack(); + if (el == nullptr) + throw DukException() << "Cannot set 'rideType' property, tile element is not a TrackElement."; + + el->SetRideType(value); + Invalidate(); + } + catch (const DukException& e) + { + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo(e.what()); } } DukValue ScTileElement::sequence_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - switch (_element->GetType()) + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + try { - case TileElementType::LargeScenery: + switch (_element->GetType()) { - auto el = _element->AsLargeScenery(); - duk_push_int(ctx, el->GetSequenceIndex()); - break; - } - case TileElementType::Track: - { - auto el = _element->AsTrack(); - if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) + case TileElementType::LargeScenery: + { + auto* el = _element->AsLargeScenery(); duk_push_int(ctx, el->GetSequenceIndex()); - else - duk_push_null(ctx); - break; - } - case TileElementType::Entrance: - { - auto el = _element->AsEntrance(); - duk_push_int(ctx, el->GetSequenceIndex()); - break; - } - default: - { - duk_push_null(ctx); - break; + break; + } + case TileElementType::Track: + { + auto* el = _element->AsTrack(); + auto* ride = get_ride(el->GetRideIndex()); + if (ride != nullptr && ride->type == RIDE_TYPE_MAZE) + throw DukException() << "Cannot read 'sequence' property, TrackElement belongs to a maze."; + + duk_push_int(ctx, el->GetSequenceIndex()); + break; + } + case TileElementType::Entrance: + { + auto* el = _element->AsEntrance(); + duk_push_int(ctx, el->GetSequenceIndex()); + break; + } + default: + throw DukException() << "Cannot read 'sequence' property, tile element is not a TrackElement, " + "LargeSceneryElement, or EntranceElement."; } } + catch (const DukException& e) + { + scriptEngine.LogPluginInfo(e.what()); + duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::sequence_set(const DukValue& value) { - if (value.type() == DukValue::Type::NUMBER) + ThrowIfGameStateNotMutable(); + + try { - ThrowIfGameStateNotMutable(); + if (value.type() != DukValue::Type::NUMBER) + throw DukException() << "'sequence' must be a number."; + switch (_element->GetType()) { case TileElementType::LargeScenery: { - auto el = _element->AsLargeScenery(); + auto* el = _element->AsLargeScenery(); el->SetSequenceIndex(value.as_uint()); Invalidate(); break; } case TileElementType::Track: { - auto el = _element->AsTrack(); - if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) - { - el->SetSequenceIndex(value.as_uint()); - Invalidate(); - } + auto* el = _element->AsTrack(); + auto ride = get_ride(el->GetRideIndex()); + if (ride != nullptr && ride->type == RIDE_TYPE_MAZE) + throw DukException() << "Cannot set 'sequence' property, TrackElement belongs to a maze."; + + el->SetSequenceIndex(value.as_uint()); + Invalidate(); break; } case TileElementType::Entrance: { - auto el = _element->AsEntrance(); + auto* el = _element->AsEntrance(); el->SetSequenceIndex(value.as_uint()); Invalidate(); break; } + default: + throw DukException() << "Cannot set 'rideType' property, tile element is not a TrackElement, " + "LargeSceneryElement, or EntranceElement."; + } + } + catch (const DukException& e) + { + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo(e.what()); + } + } + + DukValue ScTileElement::ride_get() const + { + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + try + { + switch (_element->GetType()) + { + case TileElementType::Path: + { + auto* el = _element->AsPath(); + if (!el->IsQueue()) + throw DukException() << "Cannot read 'ride' property, path is not a queue."; + + if (!el->GetRideIndex().IsNull()) + duk_push_int(ctx, el->GetRideIndex().ToUnderlying()); + else + duk_push_null(ctx); + break; + } + case TileElementType::Track: + { + auto* el = _element->AsTrack(); + duk_push_int(ctx, el->GetRideIndex().ToUnderlying()); + break; + } + case TileElementType::Entrance: + { + auto* el = _element->AsEntrance(); + duk_push_int(ctx, el->GetRideIndex().ToUnderlying()); + break; + } + default: + throw DukException() + << "Cannot read 'ride' property, tile element is not PathElement, TrackElement, or EntranceElement"; + } + } + catch (const DukException& e) + { + scriptEngine.LogPluginInfo(e.what()); + duk_push_null(ctx); + } + return DukValue::take_from_stack(ctx); + } + void ScTileElement::ride_set(const DukValue& value) + { + ThrowIfGameStateNotMutable(); + + try + { + switch (_element->GetType()) + { + case TileElementType::Path: + { + auto* el = _element->AsPath(); + if (!el->IsQueue()) + throw DukException() << "Cannot set ride property, path is not a queue."; + + if (value.type() == DukValue::Type::NUMBER) + el->SetRideIndex(RideId::FromUnderlying(value.as_uint())); + else if (value.type() == DukValue::Type::NULLREF) + el->SetRideIndex(RideId::GetNull()); + else + throw DukException() << "'ride' must be a number or null."; + Invalidate(); + break; + } + case TileElementType::Track: + { + if (value.type() != DukValue::Type::NUMBER) + throw DukException() << "'ride' must be a number."; + + auto* el = _element->AsTrack(); + el->SetRideIndex(RideId::FromUnderlying(value.as_uint())); + Invalidate(); + break; + } + case TileElementType::Entrance: + { + if (value.type() != DukValue::Type::NUMBER) + throw DukException() << "'ride' must be a number."; + + auto* el = _element->AsEntrance(); + el->SetRideIndex(RideId::FromUnderlying(value.as_uint())); + Invalidate(); + break; + } + default: + throw DukException() + << "Cannot set 'ride' property, tile element is not PathElement, TrackElement, or EntranceElement"; + } + } + catch (const DukException& e) + { + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo(e.what()); + } + } + + DukValue ScTileElement::station_get() const + { + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + try + { + switch (_element->GetType()) + { + case TileElementType::Path: + { + auto* el = _element->AsPath(); + if (!el->IsQueue()) + throw DukException() << "Cannot read 'station' property, path is not a queue."; + + if (el->GetRideIndex().IsNull()) + throw DukException() << "Cannot read 'station' property, queue is not linked to a ride."; + + if (!el->GetStationIndex().IsNull()) + duk_push_int(ctx, el->GetStationIndex().ToUnderlying()); + else + duk_push_null(ctx); + break; + } + case TileElementType::Track: + { + auto* el = _element->AsTrack(); + if (!el->IsStation()) + throw DukException() << "Cannot read 'station' property, track is not a station."; + + duk_push_int(ctx, el->GetStationIndex().ToUnderlying()); + break; + } + case TileElementType::Entrance: + { + auto* el = _element->AsEntrance(); + duk_push_int(ctx, el->GetStationIndex().ToUnderlying()); + break; + } + default: + throw DukException() + << "Cannot set 'station' property, tile element is not PathElement, TrackElement, or EntranceElement"; + } + } + catch (const DukException& e) + { + scriptEngine.LogPluginInfo(e.what()); + duk_push_null(ctx); + } + return DukValue::take_from_stack(ctx); + } + void ScTileElement::station_set(const DukValue& value) + { + ThrowIfGameStateNotMutable(); + + try + { + switch (_element->GetType()) + { + case TileElementType::Path: + { + auto* el = _element->AsPath(); + if (value.type() == DukValue::Type::NUMBER) + el->SetStationIndex(StationIndex::FromUnderlying(value.as_uint())); + else if (value.type() == DukValue::Type::NULLREF) + el->SetStationIndex(StationIndex::GetNull()); + else + throw DukException() << "'station' must be a number or null."; + Invalidate(); + break; + } + case TileElementType::Track: + { + if (value.type() != DukValue::Type::NUMBER) + throw DukException() << "'station' must be a number."; + + auto* el = _element->AsTrack(); + el->SetStationIndex(StationIndex::FromUnderlying(value.as_uint())); + Invalidate(); + break; + } + case TileElementType::Entrance: + { + if (value.type() != DukValue::Type::NUMBER) + throw DukException() << "'station' must be a number."; + + auto* el = _element->AsEntrance(); + el->SetStationIndex(StationIndex::FromUnderlying(value.as_uint())); + Invalidate(); + break; + } default: break; } } - } - - DukValue ScTileElement::ride_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - switch (_element->GetType()) + catch (const DukException& e) { - case TileElementType::Path: - { - auto el = _element->AsPath(); - if (el->IsQueue() && !el->GetRideIndex().IsNull()) - duk_push_int(ctx, el->GetRideIndex().ToUnderlying()); - else - duk_push_null(ctx); - break; - } - case TileElementType::Track: - { - auto el = _element->AsTrack(); - duk_push_int(ctx, el->GetRideIndex().ToUnderlying()); - break; - } - case TileElementType::Entrance: - { - auto el = _element->AsEntrance(); - duk_push_int(ctx, el->GetRideIndex().ToUnderlying()); - break; - } - default: - { - duk_push_null(ctx); - break; - } - } - return DukValue::take_from_stack(ctx); - } - void ScTileElement::ride_set(const DukValue& value) - { - ThrowIfGameStateNotMutable(); - switch (_element->GetType()) - { - case TileElementType::Path: - { - auto el = _element->AsPath(); - if (el->IsQueue()) - { - if (value.type() == DukValue::Type::NUMBER) - el->SetRideIndex(RideId::FromUnderlying(value.as_uint())); - else - el->SetRideIndex(RideId::GetNull()); - Invalidate(); - } - break; - } - case TileElementType::Track: - { - if (value.type() == DukValue::Type::NUMBER) - { - auto el = _element->AsTrack(); - el->SetRideIndex(RideId::FromUnderlying(value.as_uint())); - Invalidate(); - } - break; - } - case TileElementType::Entrance: - { - if (value.type() == DukValue::Type::NUMBER) - { - auto el = _element->AsEntrance(); - el->SetRideIndex(RideId::FromUnderlying(value.as_uint())); - Invalidate(); - } - break; - } - default: - break; - } - } - - DukValue ScTileElement::station_get() const - { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - switch (_element->GetType()) - { - case TileElementType::Path: - { - auto el = _element->AsPath(); - if (el->IsQueue() && !el->GetRideIndex().IsNull() && !el->GetStationIndex().IsNull()) - duk_push_int(ctx, el->GetStationIndex().ToUnderlying()); - else - duk_push_null(ctx); - break; - } - case TileElementType::Track: - { - auto el = _element->AsTrack(); - if (el->IsStation()) - duk_push_int(ctx, el->GetStationIndex().ToUnderlying()); - else - duk_push_null(ctx); - break; - } - case TileElementType::Entrance: - { - auto el = _element->AsEntrance(); - duk_push_int(ctx, el->GetStationIndex().ToUnderlying()); - break; - } - default: - { - duk_push_null(ctx); - break; - } - } - return DukValue::take_from_stack(ctx); - } - void ScTileElement::station_set(const DukValue& value) - { - ThrowIfGameStateNotMutable(); - switch (_element->GetType()) - { - case TileElementType::Path: - { - auto el = _element->AsPath(); - if (value.type() == DukValue::Type::NUMBER) - el->SetStationIndex(StationIndex::FromUnderlying(value.as_uint())); - else - el->SetStationIndex(StationIndex::GetNull()); - Invalidate(); - break; - } - case TileElementType::Track: - { - if (value.type() == DukValue::Type::NUMBER) - { - auto el = _element->AsTrack(); - el->SetStationIndex(StationIndex::FromUnderlying(value.as_uint())); - Invalidate(); - } - break; - } - case TileElementType::Entrance: - { - if (value.type() == DukValue::Type::NUMBER) - { - auto el = _element->AsEntrance(); - el->SetStationIndex(StationIndex::FromUnderlying(value.as_uint())); - Invalidate(); - } - break; - } - default: - break; + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo(e.what()); } } DukValue ScTileElement::hasChainLift_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsTrack(); if (el != nullptr) + { duk_push_boolean(ctx, el->HasChain()); + } else + { + scriptEngine.LogPluginInfo("Cannot read 'hasChainLift' property, tile element is not a TrackElement."); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::hasChainLift_set(bool value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) + auto* el = _element->AsTrack(); + if (el == nullptr) { - el->SetHasChain(value); - Invalidate(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo("Cannot set 'hasChainLift' property, tile element is not a TrackElement."); + return; } + + el->SetHasChain(value); + Invalidate(); } DukValue ScTileElement::mazeEntry_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); - if (el != nullptr && get_ride(el->GetRideIndex())->type == RIDE_TYPE_MAZE) + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + try + { + auto* el = _element->AsTrack(); + if (el == nullptr) + throw DukException() << "Cannot read 'mazeEntry' property, element is not a TrackElement."; + + Ride* ride = get_ride(el->GetRideIndex()); + if (ride == nullptr) + throw DukException() << "Cannot read 'mazeEntry' property, ride is invalid."; + + if (ride->type != RIDE_TYPE_MAZE) + throw DukException() << "Cannot read 'mazeEntry' property, ride is not a maze."; + duk_push_int(ctx, el->GetMazeEntry()); - else + } + catch (const DukException& e) + { + scriptEngine.LogPluginInfo(e.what()); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::mazeEntry_set(const DukValue& value) { - if (value.type() == DukValue::Type::NUMBER) + ThrowIfGameStateNotMutable(); + + try { - ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) - { - if (get_ride(el->GetRideIndex())->type == RIDE_TYPE_MAZE) - { - el->SetMazeEntry(value.as_uint()); - Invalidate(); - } - } + if (value.type() != DukValue::Type::NUMBER) + throw DukException() << "'mazeEntry' property must be a number."; + + auto* el = _element->AsTrack(); + if (el == nullptr) + throw DukException() << "Cannot set 'mazeEntry' property, tile element is not a TrackElement."; + + auto* ride = get_ride(el->GetRideIndex()); + if (ride == nullptr) + throw DukException() << "Cannot set 'mazeEntry' property, ride is invalid."; + + if (ride->type != RIDE_TYPE_MAZE) + throw DukException() << "Cannot set 'mazeEntry' property, ride is not a maze."; + + el->SetMazeEntry(value.as_uint()); + Invalidate(); + } + catch (const DukException& e) + { + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo(e.what()); } } DukValue ScTileElement::colourScheme_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); - if (el != nullptr && get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + try + { + auto* el = _element->AsTrack(); + if (el == nullptr) + throw DukException() << "Cannot read 'colourScheme' property, tile element is not a TrackElement."; + + auto* ride = get_ride(el->GetRideIndex()); + if (ride == nullptr) + throw DukException() << "Cannot read 'colourScheme' property, ride is invalid."; + + if (ride->type == RIDE_TYPE_MAZE) + throw DukException() << "Cannot read 'colourScheme' property, TrackElement belongs to a maze."; + duk_push_int(ctx, el->GetColourScheme()); - else + } + catch (const DukException& e) + { + scriptEngine.LogPluginInfo(e.what()); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::colourScheme_set(const DukValue& value) { - if (value.type() == DukValue::Type::NUMBER) + ThrowIfGameStateNotMutable(); + + try { - ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) - { - if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) - { - el->SetColourScheme(value.as_uint()); - Invalidate(); - } - } + if (value.type() != DukValue::Type::NUMBER) + throw DukException() << "'colourScheme' must be a number."; + + auto* el = _element->AsTrack(); + if (el == nullptr) + throw DukException() << "Cannot set 'colourScheme' property, tile element is not a TrackElement."; + + auto* ride = get_ride(el->GetRideIndex()); + if (ride == nullptr) + throw DukException() << "Cannot set 'colourScheme', ride is invalid."; + + if (ride->type == RIDE_TYPE_MAZE) + throw DukException() << "Cannot set 'colourScheme' property, TrackElement belongs to a maze."; + + el->SetColourScheme(value.as_uint()); + Invalidate(); + } + catch (const DukException& e) + { + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo(e.what()); } } DukValue ScTileElement::seatRotation_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); - if (el != nullptr && get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + try + { + auto* el = _element->AsTrack(); + if (el == nullptr) + throw DukException() << "Cannot read 'seatRotation' property, tile element is not a TrackElement."; + + auto* ride = get_ride(el->GetRideIndex()); + if (ride == nullptr) + throw DukException() << "Cannot read 'seatRotation' property, ride is invalid."; + + if (ride->type == RIDE_TYPE_MAZE) + throw DukException() << "Cannot read 'seatRotation' property, TrackElement belongs to a maze."; + duk_push_int(ctx, el->GetSeatRotation()); - else + } + catch (const DukException& e) + { + scriptEngine.LogPluginInfo(e.what()); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::seatRotation_set(const DukValue& value) { - if (value.type() == DukValue::Type::NUMBER) + ThrowIfGameStateNotMutable(); + + try { - ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) - { - if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) - { - el->SetSeatRotation(value.as_uint()); - Invalidate(); - } - } + if (value.type() != DukValue::Type::NUMBER) + throw DukException() << "'seatRotation' must be a number."; + + auto* el = _element->AsTrack(); + if (el == nullptr) + throw DukException() << "Cannot set 'seatRotation' property, tile element is not a TrackElement."; + + auto* ride = get_ride(el->GetRideIndex()); + if (ride == nullptr) + throw DukException() << "Cannot set 'seatRotation' property, ride is invalid."; + + if (ride->type != RIDE_TYPE_MAZE) + throw DukException() << "Cannot set 'seatRotation' property, TrackElement belongs to a maze."; + + el->SetSeatRotation(value.as_uint()); + Invalidate(); + } + catch (const DukException& e) + { + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo(e.what()); } } DukValue ScTileElement::brakeBoosterSpeed_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); - if (el != nullptr && TrackTypeHasSpeedSetting(el->GetTrackType())) + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + try + { + auto* el = _element->AsTrack(); + if (el == nullptr) + throw DukException() << "Cannot read 'brakeBoosterSpeed' property, tile element is not a TrackElement."; + + if (!TrackTypeHasSpeedSetting(el->GetTrackType())) + throw DukException() << "Cannot read 'brakeBoosterSpeed' property, track element has no speed setting."; + duk_push_int(ctx, el->GetBrakeBoosterSpeed()); - else + } + catch (const DukException& e) + { + scriptEngine.LogPluginInfo(e.what()); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::brakeBoosterSpeed_set(const DukValue& value) { - if (value.type() == DukValue::Type::NUMBER) + ThrowIfGameStateNotMutable(); + + try { - ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) - { - if (TrackTypeHasSpeedSetting(el->GetTrackType())) - { - el->SetBrakeBoosterSpeed(value.as_uint()); - Invalidate(); - } - } + if (value.type() != DukValue::Type::NUMBER) + throw DukException() << "'brakeBoosterSpeed' must be a number."; + + auto* el = _element->AsTrack(); + if (el == nullptr) + throw DukException() << "Cannot set 'brakeBoosterSpeed' property, tile element is not a TrackElement."; + + if (TrackTypeHasSpeedSetting(el->GetTrackType())) + throw DukException() << "Cannot set 'brakeBoosterSpeed' property, track element has no speed setting."; + + el->SetBrakeBoosterSpeed(value.as_uint()); + Invalidate(); + } + catch (const DukException& e) + { + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo(e.what()); } } DukValue ScTileElement::isInverted_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsTrack(); if (el != nullptr) + { duk_push_boolean(ctx, el->IsInverted()); + } else + { + scriptEngine.LogPluginInfo("Cannot read 'isInverted' property, tile element is not a TrackElement."); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::isInverted_set(bool value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) + auto* el = _element->AsTrack(); + if (el == nullptr) { - el->SetInverted(value); - Invalidate(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo("Cannot set 'isInverted' property, tile element is not a TrackElement."); + return; } + + el->SetInverted(value); + Invalidate(); } DukValue ScTileElement::hasCableLift_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsTrack(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsTrack(); if (el != nullptr) + { duk_push_boolean(ctx, el->HasCableLift()); + } else + { + scriptEngine.LogPluginInfo("Cannot read 'hasCableLift' property, tile element is not a TrackElement."); duk_push_null(ctx); + } return DukValue::take_from_stack(ctx); } void ScTileElement::hasCableLift_set(bool value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsTrack(); - if (el != nullptr) + auto* el = _element->AsTrack(); + if (el == nullptr) { - el->SetHasCableLift(value); - Invalidate(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + scriptEngine.LogPluginInfo("Cannot set 'hasCableLift' property, tile element is not a TrackElement."); + return; } + + el->SetHasCableLift(value); + Invalidate(); } DukValue ScTileElement::object_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); switch (_element->GetType()) { case TileElementType::Path: { - auto el = _element->AsPath(); + auto* el = _element->AsPath(); auto index = el->GetLegacyPathEntryIndex(); if (index != OBJECT_ENTRY_INDEX_NULL) duk_push_int(ctx, index); @@ -785,25 +1093,25 @@ namespace OpenRCT2::Scripting } case TileElementType::SmallScenery: { - auto el = _element->AsSmallScenery(); + auto* el = _element->AsSmallScenery(); duk_push_int(ctx, el->GetEntryIndex()); break; } case TileElementType::LargeScenery: { - auto el = _element->AsLargeScenery(); + auto* el = _element->AsLargeScenery(); duk_push_int(ctx, el->GetEntryIndex()); break; } case TileElementType::Wall: { - auto el = _element->AsWall(); + auto* el = _element->AsWall(); duk_push_int(ctx, el->GetEntryIndex()); break; } case TileElementType::Entrance: { - auto el = _element->AsEntrance(); + auto* el = _element->AsEntrance(); duk_push_int(ctx, el->GetEntranceType()); break; } @@ -827,7 +1135,7 @@ namespace OpenRCT2::Scripting { if (value.type() == DukValue::Type::NUMBER) { - auto el = _element->AsPath(); + auto* el = _element->AsPath(); el->SetLegacyPathEntryIndex(index); Invalidate(); } @@ -835,28 +1143,28 @@ namespace OpenRCT2::Scripting } case TileElementType::SmallScenery: { - auto el = _element->AsSmallScenery(); + auto* el = _element->AsSmallScenery(); el->SetEntryIndex(index); Invalidate(); break; } case TileElementType::LargeScenery: { - auto el = _element->AsLargeScenery(); + auto* el = _element->AsLargeScenery(); el->SetEntryIndex(index); Invalidate(); break; } case TileElementType::Wall: { - auto el = _element->AsWall(); + auto* el = _element->AsWall(); el->SetEntryIndex(index); Invalidate(); break; } case TileElementType::Entrance: { - auto el = _element->AsEntrance(); + auto* el = _element->AsEntrance(); el->SetEntranceType(index); Invalidate(); break; @@ -880,8 +1188,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::age_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSmallScenery(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsSmallScenery(); if (el != nullptr) duk_push_int(ctx, el->GetAge()); else @@ -891,7 +1200,7 @@ namespace OpenRCT2::Scripting void ScTileElement::age_set(uint8_t value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsSmallScenery(); + auto* el = _element->AsSmallScenery(); if (el != nullptr) { el->SetAge(value); @@ -901,8 +1210,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::quadrant_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsSmallScenery(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsSmallScenery(); if (el != nullptr) duk_push_int(ctx, el->GetSceneryQuadrant()); else @@ -912,7 +1222,7 @@ namespace OpenRCT2::Scripting void ScTileElement::quadrant_set(uint8_t value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsSmallScenery(); + auto* el = _element->AsSmallScenery(); if (el != nullptr) { el->SetSceneryQuadrant(value); @@ -944,24 +1254,25 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::primaryColour_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); switch (_element->GetType()) { case TileElementType::SmallScenery: { - auto el = _element->AsSmallScenery(); + auto* el = _element->AsSmallScenery(); duk_push_int(ctx, el->GetPrimaryColour()); break; } case TileElementType::LargeScenery: { - auto el = _element->AsLargeScenery(); + auto* el = _element->AsLargeScenery(); duk_push_int(ctx, el->GetPrimaryColour()); break; } case TileElementType::Wall: { - auto el = _element->AsWall(); + auto* el = _element->AsWall(); duk_push_int(ctx, el->GetPrimaryColour()); break; } @@ -980,21 +1291,21 @@ namespace OpenRCT2::Scripting { case TileElementType::SmallScenery: { - auto el = _element->AsSmallScenery(); + auto* el = _element->AsSmallScenery(); el->SetPrimaryColour(value); Invalidate(); break; } case TileElementType::LargeScenery: { - auto el = _element->AsLargeScenery(); + auto* el = _element->AsLargeScenery(); el->SetPrimaryColour(value); Invalidate(); break; } case TileElementType::Wall: { - auto el = _element->AsWall(); + auto* el = _element->AsWall(); el->SetPrimaryColour(value); Invalidate(); break; @@ -1006,24 +1317,25 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::secondaryColour_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); switch (_element->GetType()) { case TileElementType::SmallScenery: { - auto el = _element->AsSmallScenery(); + auto* el = _element->AsSmallScenery(); duk_push_int(ctx, el->GetSecondaryColour()); break; } case TileElementType::LargeScenery: { - auto el = _element->AsLargeScenery(); + auto* el = _element->AsLargeScenery(); duk_push_int(ctx, el->GetSecondaryColour()); break; } case TileElementType::Wall: { - auto el = _element->AsWall(); + auto* el = _element->AsWall(); duk_push_int(ctx, el->GetSecondaryColour()); break; } @@ -1042,21 +1354,21 @@ namespace OpenRCT2::Scripting { case TileElementType::SmallScenery: { - auto el = _element->AsSmallScenery(); + auto* el = _element->AsSmallScenery(); el->SetSecondaryColour(value); Invalidate(); break; } case TileElementType::LargeScenery: { - auto el = _element->AsLargeScenery(); + auto* el = _element->AsLargeScenery(); el->SetSecondaryColour(value); Invalidate(); break; } case TileElementType::Wall: { - auto el = _element->AsWall(); + auto* el = _element->AsWall(); el->SetSecondaryColour(value); Invalidate(); break; @@ -1068,8 +1380,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::tertiaryColour_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsWall(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsWall(); if (el != nullptr) duk_push_int(ctx, el->GetTertiaryColour()); else @@ -1079,7 +1392,7 @@ namespace OpenRCT2::Scripting void ScTileElement::tertiaryColour_set(uint8_t value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsWall(); + auto* el = _element->AsWall(); if (el != nullptr) { el->SetTertiaryColour(value); @@ -1089,7 +1402,8 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::bannerIndex_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); BannerIndex idx = _element->GetBannerIndex(); if (idx == BannerIndex::GetNull()) duk_push_null(ctx); @@ -1104,7 +1418,7 @@ namespace OpenRCT2::Scripting { case TileElementType::LargeScenery: { - auto el = _element->AsLargeScenery(); + auto* el = _element->AsLargeScenery(); if (value.type() == DukValue::Type::NUMBER) el->SetBannerIndex(BannerIndex::FromUnderlying(value.as_uint())); else @@ -1114,7 +1428,7 @@ namespace OpenRCT2::Scripting } case TileElementType::Wall: { - auto el = _element->AsWall(); + auto* el = _element->AsWall(); if (value.type() == DukValue::Type::NUMBER) el->SetBannerIndex(BannerIndex::FromUnderlying(value.as_uint())); else @@ -1124,7 +1438,7 @@ namespace OpenRCT2::Scripting } case TileElementType::Banner: { - auto el = _element->AsBanner(); + auto* el = _element->AsBanner(); if (value.type() == DukValue::Type::NUMBER) el->SetIndex(BannerIndex::FromUnderlying(value.as_uint())); else @@ -1142,14 +1456,14 @@ namespace OpenRCT2::Scripting /** @deprecated */ uint8_t ScTileElement::edgesAndCorners_get() const { - auto el = _element->AsPath(); + auto* el = _element->AsPath(); return el != nullptr ? el->GetEdgesAndCorners() : 0; } /** @deprecated */ void ScTileElement::edgesAndCorners_set(uint8_t value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); + auto* el = _element->AsPath(); if (el != nullptr) { el->SetEdgesAndCorners(value); @@ -1159,8 +1473,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::edges_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsPath(); if (el != nullptr) duk_push_int(ctx, el->GetEdges()); else @@ -1170,7 +1485,7 @@ namespace OpenRCT2::Scripting void ScTileElement::edges_set(uint8_t value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); + auto* el = _element->AsPath(); if (el != nullptr) { el->SetEdges(value); @@ -1180,8 +1495,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::corners_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsPath(); if (el != nullptr) duk_push_int(ctx, el->GetCorners()); else @@ -1191,7 +1507,7 @@ namespace OpenRCT2::Scripting void ScTileElement::corners_set(uint8_t value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); + auto* el = _element->AsPath(); if (el != nullptr) { el->SetCorners(value); @@ -1201,8 +1517,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::slopeDirection_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsPath(); if (el != nullptr && el->IsSloped()) duk_push_int(ctx, el->GetSlopeDirection()); else @@ -1212,7 +1529,7 @@ namespace OpenRCT2::Scripting void ScTileElement::slopeDirection_set(const DukValue& value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); + auto* el = _element->AsPath(); if (el != nullptr) { if (value.type() == DukValue::Type::NUMBER) @@ -1231,8 +1548,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::isQueue_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsPath(); if (el != nullptr) duk_push_boolean(ctx, el->IsQueue()); else @@ -1242,7 +1560,7 @@ namespace OpenRCT2::Scripting void ScTileElement::isQueue_set(bool value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); + auto* el = _element->AsPath(); if (el != nullptr) { el->SetIsQueue(value); @@ -1252,8 +1570,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::queueBannerDirection_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsPath(); if (el != nullptr && el->HasQueueBanner()) duk_push_int(ctx, el->GetQueueBannerDirection()); else @@ -1263,7 +1582,7 @@ namespace OpenRCT2::Scripting void ScTileElement::queueBannerDirection_set(const DukValue& value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); + auto* el = _element->AsPath(); if (el != nullptr) { if (value.type() == DukValue::Type::NUMBER) @@ -1282,8 +1601,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::isBlockedByVehicle_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsPath(); if (el != nullptr) duk_push_boolean(ctx, el->IsBlockedByVehicle()); else @@ -1293,7 +1613,7 @@ namespace OpenRCT2::Scripting void ScTileElement::isBlockedByVehicle_set(bool value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); + auto* el = _element->AsPath(); if (el != nullptr) { el->SetIsBlockedByVehicle(value); @@ -1303,8 +1623,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::isWide_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsPath(); if (el != nullptr) duk_push_boolean(ctx, el->IsWide()); else @@ -1314,7 +1635,7 @@ namespace OpenRCT2::Scripting void ScTileElement::isWide_set(bool value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); + auto* el = _element->AsPath(); if (el != nullptr) { el->SetWide(value); @@ -1324,10 +1645,11 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::surfaceObject_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); if (_element->GetType() == TileElementType::Path) { - auto el = _element->AsPath(); + auto* el = _element->AsPath(); auto index = el->GetSurfaceEntryIndex(); if (index != OBJECT_ENTRY_INDEX_NULL) { @@ -1352,7 +1674,7 @@ namespace OpenRCT2::Scripting ThrowIfGameStateNotMutable(); if (_element->GetType() == TileElementType::Path) { - auto el = _element->AsPath(); + auto* el = _element->AsPath(); el->SetSurfaceEntryIndex(FromDuk(value)); Invalidate(); } @@ -1361,10 +1683,11 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::railingsObject_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); if (_element->GetType() == TileElementType::Path) { - auto el = _element->AsPath(); + auto* el = _element->AsPath(); auto index = el->GetRailingsEntryIndex(); if (index != OBJECT_ENTRY_INDEX_NULL) { @@ -1389,7 +1712,7 @@ namespace OpenRCT2::Scripting ThrowIfGameStateNotMutable(); if (_element->GetType() == TileElementType::Path) { - auto el = _element->AsPath(); + auto* el = _element->AsPath(); el->SetRailingsEntryIndex(FromDuk(value)); Invalidate(); } @@ -1398,8 +1721,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::addition_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsPath(); if (el != nullptr && el->HasAddition()) duk_push_int(ctx, el->GetAddition() - 1); else @@ -1409,7 +1733,7 @@ namespace OpenRCT2::Scripting void ScTileElement::addition_set(const DukValue& value) { ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); + auto* el = _element->AsPath(); if (el != nullptr) { if (value.type() == DukValue::Type::NUMBER) @@ -1430,8 +1754,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::additionStatus_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsPath(); if (el != nullptr && el->HasAddition() && !el->IsQueue()) duk_push_int(ctx, el->GetAdditionStatus()); else @@ -1443,7 +1768,7 @@ namespace OpenRCT2::Scripting if (value.type() == DukValue::Type::NUMBER) { ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); + auto* el = _element->AsPath(); if (el != nullptr) if (el->HasAddition() && !el->IsQueue()) { @@ -1455,8 +1780,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::isAdditionBroken_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsPath(); if (el != nullptr && el->HasAddition()) duk_push_boolean(ctx, el->IsBroken()); else @@ -1468,7 +1794,7 @@ namespace OpenRCT2::Scripting if (value.type() == DukValue::Type::BOOLEAN) { ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); + auto* el = _element->AsPath(); if (el != nullptr) { el->SetIsBroken(value.as_bool()); @@ -1479,8 +1805,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::isAdditionGhost_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsPath(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsPath(); if (el != nullptr && el->HasAddition()) duk_push_boolean(ctx, el->AdditionIsGhost()); else @@ -1492,7 +1819,7 @@ namespace OpenRCT2::Scripting if (value.type() == DukValue::Type::BOOLEAN) { ThrowIfGameStateNotMutable(); - auto el = _element->AsPath(); + auto* el = _element->AsPath(); if (el != nullptr) { el->SetAdditionIsGhost(value.as_bool()); @@ -1503,8 +1830,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::footpathObject_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsEntrance(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsEntrance(); if (el != nullptr) { auto index = el->GetLegacyPathEntryIndex(); @@ -1528,7 +1856,7 @@ namespace OpenRCT2::Scripting if (value.type() == DukValue::Type::NUMBER) { ThrowIfGameStateNotMutable(); - auto el = _element->AsEntrance(); + auto* el = _element->AsEntrance(); if (el != nullptr) { el->SetLegacyPathEntryIndex(FromDuk(value)); @@ -1539,8 +1867,9 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::footpathSurfaceObject_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); - auto el = _element->AsEntrance(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + auto* el = _element->AsEntrance(); if (el != nullptr) { auto index = el->GetSurfaceEntryIndex(); @@ -1565,7 +1894,7 @@ namespace OpenRCT2::Scripting if (value.type() == DukValue::Type::NUMBER) { ThrowIfGameStateNotMutable(); - auto el = _element->AsEntrance(); + auto* el = _element->AsEntrance(); if (el != nullptr) { el->SetSurfaceEntryIndex(FromDuk(value)); @@ -1576,12 +1905,13 @@ namespace OpenRCT2::Scripting DukValue ScTileElement::direction_get() const { - auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); switch (_element->GetType()) { case TileElementType::Banner: { - auto el = _element->AsBanner(); + auto* el = _element->AsBanner(); duk_push_int(ctx, el->GetPosition()); break; } @@ -1606,7 +1936,7 @@ namespace OpenRCT2::Scripting { case TileElementType::Banner: { - auto el = _element->AsBanner(); + auto* el = _element->AsBanner(); el->SetPosition(value); Invalidate(); break;