Sanitize all track element properties

This commit is contained in:
Hielke Morsink 2022-05-08 19:54:33 +02:00
parent 813618d30b
commit 2bf5f1040a
No known key found for this signature in database
GPG Key ID: FE0B343DF883E7F2
1 changed files with 370 additions and 192 deletions

View File

@ -393,20 +393,28 @@ namespace OpenRCT2::Scripting
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el != nullptr) if (el != nullptr)
{
duk_push_int(ctx, el->GetTrackType()); duk_push_int(ctx, el->GetTrackType());
}
else else
{
std::puts("Only TrackElement has the 'trackType' property.");
duk_push_null(ctx); duk_push_null(ctx);
}
return DukValue::take_from_stack(ctx); return DukValue::take_from_stack(ctx);
} }
void ScTileElement::trackType_set(uint16_t value) void ScTileElement::trackType_set(uint16_t value)
{ {
ThrowIfGameStateNotMutable(); ThrowIfGameStateNotMutable();
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el != nullptr) if (el == nullptr)
{ {
el->SetTrackType(value); std::puts("Cannot set 'trackType' property, tile element is not a TrackElement.");
Invalidate(); return;
} }
el->SetTrackType(value);
Invalidate();
} }
DukValue ScTileElement::rideType_get() const DukValue ScTileElement::rideType_get() const
@ -414,68 +422,88 @@ namespace OpenRCT2::Scripting
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el != nullptr) if (el != nullptr)
{
duk_push_int(ctx, el->GetRideType()); duk_push_int(ctx, el->GetRideType());
}
else else
{
std::puts("Only TrackElement has the 'rideType' property.");
duk_push_null(ctx); duk_push_null(ctx);
}
return DukValue::take_from_stack(ctx); return DukValue::take_from_stack(ctx);
} }
void ScTileElement::rideType_set(uint16_t value) void ScTileElement::rideType_set(uint16_t value)
{ {
ThrowIfGameStateNotMutable(); ThrowIfGameStateNotMutable();
if (value < RIDE_TYPE_COUNT)
try
{ {
if (value < RIDE_TYPE_COUNT)
throw DukException() << "'rideType' value is invalid.";
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el != nullptr) if (el == nullptr)
{ throw DukException() << "Cannot set 'rideType' property, tile element is not a TrackElement.";
el->SetRideType(value);
Invalidate(); el->SetRideType(value);
} Invalidate();
}
catch (const DukException& e)
{
std::puts(e.what());
} }
} }
DukValue ScTileElement::sequence_get() const DukValue ScTileElement::sequence_get() const
{ {
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
switch (_element->GetType()) try
{ {
case TileElementType::LargeScenery: switch (_element->GetType())
{ {
auto el = _element->AsLargeScenery(); case TileElementType::LargeScenery:
duk_push_int(ctx, el->GetSequenceIndex()); {
break; auto el = _element->AsLargeScenery();
}
case TileElementType::Track:
{
auto el = _element->AsTrack();
auto* ride = get_ride(el->GetRideIndex());
if (ride != nullptr && ride->type != RIDE_TYPE_MAZE)
duk_push_int(ctx, el->GetSequenceIndex()); duk_push_int(ctx, el->GetSequenceIndex());
else break;
duk_push_null(ctx); }
break; case TileElementType::Track:
} {
case TileElementType::Entrance: auto el = _element->AsTrack();
{ auto* ride = get_ride(el->GetRideIndex());
auto el = _element->AsEntrance(); if (ride != nullptr && ride->type == RIDE_TYPE_MAZE)
duk_push_int(ctx, el->GetSequenceIndex()); throw DukException() << "Cannot read 'sequence' property, TrackElement belongs to a maze.";
break;
} duk_push_int(ctx, el->GetSequenceIndex());
default: break;
{ }
duk_push_null(ctx); case TileElementType::Entrance:
break; {
auto el = _element->AsEntrance();
duk_push_int(ctx, el->GetSequenceIndex());
break;
}
default:
throw DukException() << "Cannot set 'sequence' property, tile element is not a TrackElement, "
"LargeSceneryElement, or EntranceElement.";
} }
} }
catch (const DukException& e)
{
std::puts(e.what());
duk_push_null(ctx);
}
return DukValue::take_from_stack(ctx); return DukValue::take_from_stack(ctx);
} }
void ScTileElement::sequence_set(const DukValue& value) void ScTileElement::sequence_set(const DukValue& value)
{ {
ThrowIfGameStateNotMutable();
try try
{ {
if (value.type() != DukValue::Type::NUMBER) if (value.type() != DukValue::Type::NUMBER)
throw DukException() << "sequence must be a number."; throw DukException() << "'sequence' must be a number.";
ThrowIfGameStateNotMutable();
switch (_element->GetType()) switch (_element->GetType())
{ {
case TileElementType::LargeScenery: case TileElementType::LargeScenery:
@ -489,14 +517,11 @@ namespace OpenRCT2::Scripting
{ {
auto el = _element->AsTrack(); auto el = _element->AsTrack();
auto ride = get_ride(el->GetRideIndex()); auto ride = get_ride(el->GetRideIndex());
if (ride == nullptr) if (ride != nullptr && ride->type == RIDE_TYPE_MAZE)
throw DukException() << "Cannot set sequence index for invalid ride."; throw DukException() << "Cannot set 'sequence' property, TrackElement belongs to a maze.";
if (ride->type != RIDE_TYPE_MAZE) el->SetSequenceIndex(value.as_uint());
{ Invalidate();
el->SetSequenceIndex(value.as_uint());
Invalidate();
}
break; break;
} }
case TileElementType::Entrance: case TileElementType::Entrance:
@ -507,8 +532,8 @@ namespace OpenRCT2::Scripting
break; break;
} }
default: default:
throw DukException() << "Element does not have a sequence property."; throw DukException() << "Cannot set 'rideType' property, tile element is not a TrackElement, "
break; "LargeSceneryElement, or EntranceElement.";
} }
} }
catch (const DukException& e) catch (const DukException& e)
@ -520,154 +545,196 @@ namespace OpenRCT2::Scripting
DukValue ScTileElement::ride_get() const DukValue ScTileElement::ride_get() const
{ {
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
switch (_element->GetType()) try
{ {
case TileElementType::Path: switch (_element->GetType())
{ {
auto el = _element->AsPath(); case TileElementType::Path:
if (el->IsQueue() && !el->GetRideIndex().IsNull()) {
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()); duk_push_int(ctx, el->GetRideIndex().ToUnderlying());
else break;
duk_push_null(ctx); }
break; case TileElementType::Entrance:
} {
case TileElementType::Track: auto el = _element->AsEntrance();
{ duk_push_int(ctx, el->GetRideIndex().ToUnderlying());
auto el = _element->AsTrack(); break;
duk_push_int(ctx, el->GetRideIndex().ToUnderlying()); }
break; default:
} throw DukException()
case TileElementType::Entrance: << "Cannot read 'ride' property, tile element is not PathElement, TrackElement, or EntranceElement";
{
auto el = _element->AsEntrance();
duk_push_int(ctx, el->GetRideIndex().ToUnderlying());
break;
}
default:
{
duk_push_null(ctx);
break;
} }
} }
catch (const DukException& e)
{
std::puts(e.what());
duk_push_null(ctx);
}
return DukValue::take_from_stack(ctx); return DukValue::take_from_stack(ctx);
} }
void ScTileElement::ride_set(const DukValue& value) void ScTileElement::ride_set(const DukValue& value)
{ {
ThrowIfGameStateNotMutable(); ThrowIfGameStateNotMutable();
switch (_element->GetType())
try
{ {
case TileElementType::Path: switch (_element->GetType())
{ {
auto el = _element->AsPath(); case TileElementType::Path:
if (el->IsQueue())
{ {
auto el = _element->AsPath();
if (!el->IsQueue())
throw DukException() << "Cannot set ride property, path is not a queue.";
if (value.type() == DukValue::Type::NUMBER) if (value.type() == DukValue::Type::NUMBER)
el->SetRideIndex(RideId::FromUnderlying(value.as_uint())); el->SetRideIndex(RideId::FromUnderlying(value.as_uint()));
else else if (value.type() == DukValue::Type::NULLREF)
el->SetRideIndex(RideId::GetNull()); el->SetRideIndex(RideId::GetNull());
else
throw DukException() << "'ride' must be a number or null.";
Invalidate(); Invalidate();
break;
} }
break; case TileElementType::Track:
}
case TileElementType::Track:
{
if (value.type() == DukValue::Type::NUMBER)
{ {
if (value.type() != DukValue::Type::NUMBER)
throw DukException() << "'ride' must be a number.";
auto el = _element->AsTrack(); auto el = _element->AsTrack();
el->SetRideIndex(RideId::FromUnderlying(value.as_uint())); el->SetRideIndex(RideId::FromUnderlying(value.as_uint()));
Invalidate(); Invalidate();
break;
} }
break; case TileElementType::Entrance:
}
case TileElementType::Entrance:
{
if (value.type() == DukValue::Type::NUMBER)
{ {
if (value.type() != DukValue::Type::NUMBER)
throw DukException() << "'ride' must be a number.";
auto el = _element->AsEntrance(); auto el = _element->AsEntrance();
el->SetRideIndex(RideId::FromUnderlying(value.as_uint())); el->SetRideIndex(RideId::FromUnderlying(value.as_uint()));
Invalidate(); Invalidate();
break;
} }
break; default:
throw DukException()
<< "Cannot set 'ride' property, tile element is not PathElement, TrackElement, or EntranceElement";
} }
default: }
break; catch (const DukException& e)
{
std::puts(e.what());
} }
} }
DukValue ScTileElement::station_get() const DukValue ScTileElement::station_get() const
{ {
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
switch (_element->GetType()) try
{ {
case TileElementType::Path: switch (_element->GetType())
{ {
auto el = _element->AsPath(); case TileElementType::Path:
if (el->IsQueue() && !el->GetRideIndex().IsNull() && !el->GetStationIndex().IsNull()) {
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()); duk_push_int(ctx, el->GetStationIndex().ToUnderlying());
else break;
duk_push_null(ctx); }
break; case TileElementType::Entrance:
} {
case TileElementType::Track: auto el = _element->AsEntrance();
{
auto el = _element->AsTrack();
if (el->IsStation())
duk_push_int(ctx, el->GetStationIndex().ToUnderlying()); duk_push_int(ctx, el->GetStationIndex().ToUnderlying());
else break;
duk_push_null(ctx); }
break; default:
} throw DukException()
case TileElementType::Entrance: << "Cannot set 'station' property, tile element is not PathElement, TrackElement, or EntranceElement";
{
auto el = _element->AsEntrance();
duk_push_int(ctx, el->GetStationIndex().ToUnderlying());
break;
}
default:
{
duk_push_null(ctx);
break;
} }
} }
catch (const DukException& e)
{
std::puts(e.what());
duk_push_null(ctx);
}
return DukValue::take_from_stack(ctx); return DukValue::take_from_stack(ctx);
} }
void ScTileElement::station_set(const DukValue& value) void ScTileElement::station_set(const DukValue& value)
{ {
ThrowIfGameStateNotMutable(); ThrowIfGameStateNotMutable();
switch (_element->GetType())
try
{ {
case TileElementType::Path: switch (_element->GetType())
{ {
auto el = _element->AsPath(); case TileElementType::Path:
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->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(); auto el = _element->AsTrack();
el->SetStationIndex(StationIndex::FromUnderlying(value.as_uint())); el->SetStationIndex(StationIndex::FromUnderlying(value.as_uint()));
Invalidate(); Invalidate();
break;
} }
break; case TileElementType::Entrance:
}
case TileElementType::Entrance:
{
if (value.type() == DukValue::Type::NUMBER)
{ {
if (value.type() != DukValue::Type::NUMBER)
throw DukException() << "'station' must be a number.";
auto el = _element->AsEntrance(); auto el = _element->AsEntrance();
el->SetStationIndex(StationIndex::FromUnderlying(value.as_uint())); el->SetStationIndex(StationIndex::FromUnderlying(value.as_uint()));
Invalidate(); Invalidate();
break;
} }
break; default:
break;
} }
default: }
break; catch (const DukException& e)
{
std::puts(e.what());
} }
} }
@ -676,52 +743,74 @@ namespace OpenRCT2::Scripting
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el != nullptr) if (el != nullptr)
{
duk_push_boolean(ctx, el->HasChain()); duk_push_boolean(ctx, el->HasChain());
}
else else
{
std::puts("Cannot set 'hasChainLift' property, tile element is not a TrackElement.");
duk_push_null(ctx); duk_push_null(ctx);
}
return DukValue::take_from_stack(ctx); return DukValue::take_from_stack(ctx);
} }
void ScTileElement::hasChainLift_set(bool value) void ScTileElement::hasChainLift_set(bool value)
{ {
ThrowIfGameStateNotMutable(); ThrowIfGameStateNotMutable();
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el != nullptr) if (el == nullptr)
{ {
el->SetHasChain(value); std::puts("Only TrackElement has the 'hasChainLift' property");
Invalidate(); return;
} }
el->SetHasChain(value);
Invalidate();
} }
DukValue ScTileElement::mazeEntry_get() const DukValue ScTileElement::mazeEntry_get() const
{ {
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
auto el = _element->AsTrack(); try
Ride* ride; {
if (el != nullptr && (ride = get_ride(el->GetRideIndex())) != nullptr && ride->type == RIDE_TYPE_MAZE) 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()); duk_push_int(ctx, el->GetMazeEntry());
else }
catch (const DukException& e)
{
std::puts(e.what());
duk_push_null(ctx); duk_push_null(ctx);
}
return DukValue::take_from_stack(ctx); return DukValue::take_from_stack(ctx);
} }
void ScTileElement::mazeEntry_set(const DukValue& value) void ScTileElement::mazeEntry_set(const DukValue& value)
{ {
ThrowIfGameStateNotMutable();
try try
{ {
if (value.type() != DukValue::Type::NUMBER) if (value.type() != DukValue::Type::NUMBER)
throw DukException() << "mazeEntry must be a number."; throw DukException() << "'mazeEntry' property must be a number.";
ThrowIfGameStateNotMutable();
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el == nullptr) if (el == nullptr)
throw DukException() << "Element is not a track."; throw DukException() << "Cannot set 'mazeEntry' property, tile element is not a TrackElement.";
auto* ride = get_ride(el->GetRideIndex()); auto* ride = get_ride(el->GetRideIndex());
if (ride == nullptr) if (ride == nullptr)
throw DukException() << "Ride is invalid."; throw DukException() << "Cannot set 'mazeEntry' property, ride is invalid.";
if (ride->type != RIDE_TYPE_MAZE) if (ride->type != RIDE_TYPE_MAZE)
throw DukException() << "Ride is not a maze."; throw DukException() << "Cannot set 'mazeEntry' property, ride is not a maze.";
el->SetMazeEntry(value.as_uint()); el->SetMazeEntry(value.as_uint());
Invalidate(); Invalidate();
@ -735,81 +824,154 @@ namespace OpenRCT2::Scripting
DukValue ScTileElement::colourScheme_get() const DukValue ScTileElement::colourScheme_get() const
{ {
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
auto el = _element->AsTrack(); try
if (el != nullptr && get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) {
auto el = _element->AsTrack();
if (el == nullptr)
throw DukException() << "Cannot get 'colourScheme' property, tile element is not a TrackElement.";
auto* ride = get_ride(el->GetRideIndex());
if (ride == nullptr)
throw DukException() << "Cannot get 'colourScheme' property, ride is invalid.";
if (ride->type == RIDE_TYPE_MAZE)
throw DukException() << "Cannot get 'colourScheme' property, TrackElement belongs to a maze.";
duk_push_int(ctx, el->GetColourScheme()); duk_push_int(ctx, el->GetColourScheme());
else }
catch (const DukException& e)
{
std::puts(e.what());
duk_push_null(ctx); duk_push_null(ctx);
}
return DukValue::take_from_stack(ctx); return DukValue::take_from_stack(ctx);
} }
void ScTileElement::colourScheme_set(const DukValue& value) void ScTileElement::colourScheme_set(const DukValue& value)
{ {
if (value.type() == DukValue::Type::NUMBER) ThrowIfGameStateNotMutable();
try
{ {
ThrowIfGameStateNotMutable(); if (value.type() != DukValue::Type::NUMBER)
throw DukException() << "'colourScheme' must be a number.";
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el != nullptr) if (el == nullptr)
{ throw DukException() << "Cannot set 'colourScheme', tile element is not a TrackElement.";
if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE)
{ auto* ride = get_ride(el->GetRideIndex());
el->SetColourScheme(value.as_uint()); if (ride == nullptr)
Invalidate(); 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)
{
std::puts(e.what());
} }
} }
DukValue ScTileElement::seatRotation_get() const DukValue ScTileElement::seatRotation_get() const
{ {
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
auto el = _element->AsTrack(); try
if (el != nullptr && get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE) {
auto el = _element->AsTrack();
if (el == nullptr)
throw DukException() << "Cannot read 'seatRotation', tile element is not a TrackElement.";
auto* ride = get_ride(el->GetRideIndex());
if (ride == nullptr)
throw DukException() << "Cannot read 'seatRotation', 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()); duk_push_int(ctx, el->GetSeatRotation());
else }
catch (const DukException& e)
{
std::puts(e.what());
duk_push_null(ctx); duk_push_null(ctx);
}
return DukValue::take_from_stack(ctx); return DukValue::take_from_stack(ctx);
} }
void ScTileElement::seatRotation_set(const DukValue& value) void ScTileElement::seatRotation_set(const DukValue& value)
{ {
if (value.type() == DukValue::Type::NUMBER) ThrowIfGameStateNotMutable();
try
{ {
ThrowIfGameStateNotMutable(); if (value.type() != DukValue::Type::NUMBER)
throw DukException() << "'seatRotation' must be a number.";
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el != nullptr) if (el == nullptr)
{ throw DukException() << "Cannot set 'seatRotation', tile element is not a TrackElement.";
if (get_ride(el->GetRideIndex())->type != RIDE_TYPE_MAZE)
{ auto* ride = get_ride(el->GetRideIndex());
el->SetSeatRotation(value.as_uint()); if (ride == nullptr)
Invalidate(); throw DukException() << "Cannot set 'seatRotation', 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)
{
std::puts(e.what());
} }
} }
DukValue ScTileElement::brakeBoosterSpeed_get() const DukValue ScTileElement::brakeBoosterSpeed_get() const
{ {
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
auto el = _element->AsTrack(); try
if (el != nullptr && TrackTypeHasSpeedSetting(el->GetTrackType())) {
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()); duk_push_int(ctx, el->GetBrakeBoosterSpeed());
else }
catch (const DukException& e)
{
std::puts(e.what());
duk_push_null(ctx); duk_push_null(ctx);
}
return DukValue::take_from_stack(ctx); return DukValue::take_from_stack(ctx);
} }
void ScTileElement::brakeBoosterSpeed_set(const DukValue& value) void ScTileElement::brakeBoosterSpeed_set(const DukValue& value)
{ {
if (value.type() == DukValue::Type::NUMBER) ThrowIfGameStateNotMutable();
try
{ {
ThrowIfGameStateNotMutable(); if (value.type() != DukValue::Type::NUMBER)
throw DukException() << "'brakeBoosterSpeed' must be a number.";
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el != nullptr) if (el == nullptr)
{ throw DukException() << "Cannot set 'brakeBoosterSpeed' property, tile element is not a TrackElement.";
if (TrackTypeHasSpeedSetting(el->GetTrackType()))
{ if (TrackTypeHasSpeedSetting(el->GetTrackType()))
el->SetBrakeBoosterSpeed(value.as_uint()); throw DukException() << "Cannot set 'brakeBoosterSpeed' property, track element has no speed setting.";
Invalidate();
} el->SetBrakeBoosterSpeed(value.as_uint());
} Invalidate();
}
catch (const DukException& e)
{
std::puts(e.what());
} }
} }
@ -818,20 +980,28 @@ namespace OpenRCT2::Scripting
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el != nullptr) if (el != nullptr)
{
duk_push_boolean(ctx, el->IsInverted()); duk_push_boolean(ctx, el->IsInverted());
}
else else
{
std::puts("Only TrackElement has the 'isInverted' property.");
duk_push_null(ctx); duk_push_null(ctx);
}
return DukValue::take_from_stack(ctx); return DukValue::take_from_stack(ctx);
} }
void ScTileElement::isInverted_set(bool value) void ScTileElement::isInverted_set(bool value)
{ {
ThrowIfGameStateNotMutable(); ThrowIfGameStateNotMutable();
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el != nullptr) if (el == nullptr)
{ {
el->SetInverted(value); std::puts("Cannot set 'isInverted' property, tile element is not a TrackElement.");
Invalidate(); return;
} }
el->SetInverted(value);
Invalidate();
} }
DukValue ScTileElement::hasCableLift_get() const DukValue ScTileElement::hasCableLift_get() const
@ -839,20 +1009,28 @@ namespace OpenRCT2::Scripting
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el != nullptr) if (el != nullptr)
{
duk_push_boolean(ctx, el->HasCableLift()); duk_push_boolean(ctx, el->HasCableLift());
}
else else
{
std::puts("Only TrackElement has the 'hasCableLift' property.");
duk_push_null(ctx); duk_push_null(ctx);
}
return DukValue::take_from_stack(ctx); return DukValue::take_from_stack(ctx);
} }
void ScTileElement::hasCableLift_set(bool value) void ScTileElement::hasCableLift_set(bool value)
{ {
ThrowIfGameStateNotMutable(); ThrowIfGameStateNotMutable();
auto el = _element->AsTrack(); auto el = _element->AsTrack();
if (el != nullptr) if (el == nullptr)
{ {
el->SetHasCableLift(value); std::puts("Cannot set 'hasCableLift' property, tile element is not a TrackElement.");
Invalidate(); return;
} }
el->SetHasCableLift(value);
Invalidate();
} }
DukValue ScTileElement::object_get() const DukValue ScTileElement::object_get() const