diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index 7cc0da29f2..0b3f305d33 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -234,6 +234,8 @@ declare global { */ getTrackSegment(type: number): TrackSegment | null; + getAllTrackSegments(): TrackSegment[]; + /** * Gets the image number for the given icon. * @param iconName The name of the icon. @@ -1953,62 +1955,58 @@ declare global { readonly description: string; /** - * The relative starting Z position. + * The relative starting Z position from the base of the first track sequence block. */ readonly beginZ: number; + /** + * The relative ending Z position from the base of the first track sequence block. + */ + readonly endZ: number; + + /** + * The relative ending X position. BeginX is always 0. + */ + readonly endX: number; + + /** + * The relative ending Y position. BeginY is always 0. + */ + readonly endY: number; + /** * The relative starting direction. Usually 0, but will be 4 * for diagonal segments. */ readonly beginDirection: Direction8; + /** + * The relative ending direction. + */ + readonly endDirection: Direction8; + /** * The slope angle the segment starts with. */ - readonly beginAngle: TrackSlope; + readonly beginSlope: TrackSlope; + + /** + * The slope angle the segment ends with. + */ + readonly endSlope: TrackSlope; /** * The kind of banking the segment starts with. */ readonly beginBank: TrackBanking; - /** - * The relative ending X position. - */ - readonly endX: number; - - /** - * The relative ending Y position. - */ - readonly endY: number; - - /** - * The relative ending Z position. Negative numbers indicate - * that the track ends upside down. - */ - readonly endZ: number; - - /** - * The relative ending direction. - */ - readonly endDirection: Direction8; - - - /** - * The slope angle the segment ends with. - */ - readonly endAngle: TrackSlope; - /** * The kind of banking the segment ends with. */ readonly endBank: TrackBanking; /** - * The length of the segment in RCT track length units. - * - * *1 metre = 1 / (2 ^ 16)* + * The rough length of the segment. */ readonly length: number; @@ -2017,6 +2015,97 @@ declare global { */ readonly elements: TrackSegmentElement[]; + /** + * The curve direction of the suggested following piece, or track segment if it is specified. + */ + readonly nextSuggestedSegment: TrackCurveType | number; + + /** + * The curve direction of the suggested preceding piece, or track segment if it is specified. + */ + readonly previousSuggestedSegment: TrackCurveType | number; + + /** + * The base price of the track segment. + */ + readonly priceModifier: number; + + /** + * Track segment representing the mirror image of the track segment. + */ + readonly mirrorSegment: number | null; + + /** + * Track segment representing the covered/flume variant of the track segment. + */ + readonly alternateTypeSegment: number | null; + + /** + * The group the track element belongs to. Ride types allow or disallow track groups to limit the + * buildable track segments. + */ + readonly trackGroup: number; + + /** + * Which direction the track curves towards. + */ + readonly turnDirection: TrackCurveType; + + /** + * Which direction the track slopes towards. + */ + readonly slopeDirection: TrackSlopeType; + + readonly onlyAllowedUnderwater: boolean; + readonly onlyAllowedAboveGround: boolean; + readonly allowsChainLift: boolean; + + /** + * The track segment counts as banked for vehicles with "no banked track" behaviour. + */ + readonly isBanked: boolean; + + /** + * The track segment counts as an inversion for vehicles with "no inversions" behaviour. + */ + readonly isInversion: boolean; + + /** + * Pevents steep forward chainlifts but allows steep reverse chainlifts for reverse incline + * shuttle mode for ride types which do not normally allow steep chainlifts. + */ + readonly isSteepUp: boolean; + + /** + * The track segment begins one height unit above normal track height units. + */ + readonly startsHalfHeightUp: boolean; + + /** + * The track segment adds to golf hole counter. + */ + readonly countsAsGolfHole: boolean; + + /** + * The track segment adds to banked turn counter. + */ + readonly isBankedTurn: boolean; + + /** + * The track segment adds to sloped turn counter. + */ + readonly isSlopedTurn: boolean; + + /** + * The track segment adds to helix counter. + */ + readonly isHelix: boolean; + + /** + * The track segment adds to inversion counter. Usually applied to the first half of inversions. + */ + readonly countsAsInversion: boolean; + /** * Gets a length of the subpositions list for this track segment. */ @@ -2046,6 +2135,9 @@ declare global { UpsideDown = 15 } + type TrackCurveType = "straight" | "left" | "right"; + type TrackSlopeType = "flat" | "up" | "down"; + interface TrackSegmentElement extends Readonly { } diff --git a/src/openrct2/scripting/ScriptEngine.h b/src/openrct2/scripting/ScriptEngine.h index 26680b3b60..295a52c47a 100644 --- a/src/openrct2/scripting/ScriptEngine.h +++ b/src/openrct2/scripting/ScriptEngine.h @@ -47,7 +47,7 @@ namespace OpenRCT2 namespace OpenRCT2::Scripting { - static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 69; + static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 70; // Versions marking breaking changes. static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33; diff --git a/src/openrct2/scripting/bindings/game/ScContext.hpp b/src/openrct2/scripting/bindings/game/ScContext.hpp index 5a33723767..73a2009e5f 100644 --- a/src/openrct2/scripting/bindings/game/ScContext.hpp +++ b/src/openrct2/scripting/bindings/game/ScContext.hpp @@ -233,6 +233,22 @@ namespace OpenRCT2::Scripting } } + std::vector getAllTrackSegments() + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + + std::vector result; + for (track_type_t type = 0; type < TrackElemType::Count; type++) + { + auto obj = std::make_shared(type); + if (obj != nullptr) + { + result.push_back(GetObjectAsDukValue(ctx, obj)); + } + } + return result; + } + int32_t getRandom(int32_t min, int32_t max) { ThrowIfGameStateNotMutable(); @@ -455,6 +471,7 @@ namespace OpenRCT2::Scripting dukglue_register_method(ctx, &ScContext::getObject, "getObject"); dukglue_register_method(ctx, &ScContext::getAllObjects, "getAllObjects"); dukglue_register_method(ctx, &ScContext::getTrackSegment, "getTrackSegment"); + dukglue_register_method(ctx, &ScContext::getAllTrackSegments, "getAllTrackSegments"); dukglue_register_method(ctx, &ScContext::getRandom, "getRandom"); dukglue_register_method_varargs(ctx, &ScContext::formatString, "formatString"); dukglue_register_method(ctx, &ScContext::subscribe, "subscribe"); diff --git a/src/openrct2/scripting/bindings/ride/ScTrackSegment.cpp b/src/openrct2/scripting/bindings/ride/ScTrackSegment.cpp index 180313a390..916e2c87b4 100644 --- a/src/openrct2/scripting/bindings/ride/ScTrackSegment.cpp +++ b/src/openrct2/scripting/bindings/ride/ScTrackSegment.cpp @@ -29,13 +29,43 @@ void ScTrackSegment::Register(duk_context* ctx) dukglue_register_property(ctx, &ScTrackSegment::type_get, nullptr, "type"); dukglue_register_property(ctx, &ScTrackSegment::description_get, nullptr, "description"); dukglue_register_property(ctx, &ScTrackSegment::elements_get, nullptr, "elements"); - dukglue_register_property(ctx, &ScTrackSegment::beginZ_get, nullptr, "beginZ"); dukglue_register_property(ctx, &ScTrackSegment::beginDirection_get, nullptr, "beginDirection"); + dukglue_register_property(ctx, &ScTrackSegment::endDirection_get, nullptr, "endDirection"); + dukglue_register_property(ctx, &ScTrackSegment::beginSlope_get, nullptr, "beginSlope"); + dukglue_register_property(ctx, &ScTrackSegment::endSlope_get, nullptr, "endSlope"); + dukglue_register_property(ctx, &ScTrackSegment::beginBank_get, nullptr, "beginBank"); + dukglue_register_property(ctx, &ScTrackSegment::endBank_get, nullptr, "endBank"); + dukglue_register_property(ctx, &ScTrackSegment::beginZ_get, nullptr, "beginZ"); + dukglue_register_property(ctx, &ScTrackSegment::endZ_get, nullptr, "endZ"); dukglue_register_property(ctx, &ScTrackSegment::endX_get, nullptr, "endX"); dukglue_register_property(ctx, &ScTrackSegment::endY_get, nullptr, "endY"); - dukglue_register_property(ctx, &ScTrackSegment::endZ_get, nullptr, "endZ"); - dukglue_register_property(ctx, &ScTrackSegment::endDirection_get, nullptr, "endDirection"); dukglue_register_property(ctx, &ScTrackSegment::length_get, nullptr, "length"); + dukglue_register_property(ctx, &ScTrackSegment::nextCurveElement_get, nullptr, "nextSuggestedSegment"); + dukglue_register_property(ctx, &ScTrackSegment::previousCurveElement_get, nullptr, "previousSuggestedSegment"); + dukglue_register_property(ctx, &ScTrackSegment::getMirrorElement, nullptr, "mirrorSegment"); + dukglue_register_property(ctx, &ScTrackSegment::getAlternativeElement, nullptr, "alternateTypeSegment"); + dukglue_register_property(ctx, &ScTrackSegment::getPriceModifier, nullptr, "priceModifier"); + dukglue_register_property(ctx, &ScTrackSegment::getTrackGroup, nullptr, "trackGroup"); + dukglue_register_property(ctx, &ScTrackSegment::getTrackCurvature, nullptr, "turnDirection"); + dukglue_register_property(ctx, &ScTrackSegment::getTrackSlopeDirection, nullptr, "slopeDirection"); + + dukglue_register_property( + ctx, &ScTrackSegment::getTrackFlag, nullptr, "onlyAllowedUnderwater"); + dukglue_register_property( + ctx, &ScTrackSegment::getTrackFlag, nullptr, "onlyAllowedAboveGround"); + dukglue_register_property(ctx, &ScTrackSegment::getTrackFlag, nullptr, "allowsChainLift"); + dukglue_register_property(ctx, &ScTrackSegment::getTrackFlag, nullptr, "isBanked"); + dukglue_register_property(ctx, &ScTrackSegment::getTrackFlag, nullptr, "isInversion"); + dukglue_register_property(ctx, &ScTrackSegment::getTrackFlag, nullptr, "isSteepUp"); + dukglue_register_property( + ctx, &ScTrackSegment::getTrackFlag, nullptr, "startsHalfHeightUp"); + dukglue_register_property(ctx, &ScTrackSegment::getTrackFlag, nullptr, "countsAsInversion"); + dukglue_register_property(ctx, &ScTrackSegment::getTrackFlag, nullptr, "isBankedTurn"); + dukglue_register_property(ctx, &ScTrackSegment::getTrackFlag, nullptr, "isSlopedTurn"); + dukglue_register_property(ctx, &ScTrackSegment::getTrackFlag, nullptr, "isHelix"); + dukglue_register_property( + ctx, &ScTrackSegment::getTrackFlag, nullptr, "countsAsInversion"); + dukglue_register_method(ctx, &ScTrackSegment::getSubpositionLength, "getSubpositionLength"); dukglue_register_method(ctx, &ScTrackSegment::getSubpositions, "getSubpositions"); } @@ -63,7 +93,7 @@ int32_t ScTrackSegment::beginDirection_get() const return ted.Coordinates.rotation_begin; } -int32_t ScTrackSegment::beginAngle_get() const +int32_t ScTrackSegment::beginSlope_get() const { const auto& ted = GetTrackElementDescriptor(_type); return ted.Definition.vangle_start; @@ -99,7 +129,7 @@ int32_t ScTrackSegment::endDirection_get() const return ted.Coordinates.rotation_end; } -int32_t ScTrackSegment::endAngle_get() const +int32_t ScTrackSegment::endSlope_get() const { const auto& ted = GetTrackElementDescriptor(_type); return ted.Definition.vangle_end; @@ -165,4 +195,101 @@ std::vector ScTrackSegment::getSubpositions(uint8_t trackSubposition, return result; } +DukValue ScTrackSegment::nextCurveElement_get() const +{ + const auto ctx = GetContext()->GetScriptEngine().GetContext(); + const auto& ted = GetTrackElementDescriptor(_type); + + int32_t curve = ted.CurveChain.next; + if (curve & RideConstructionSpecialPieceSelected) + return ToDuk(ctx, curve & (~RideConstructionSpecialPieceSelected)); + switch (curve) + { + case 1: + return ToDuk(ctx, "left"); + case 2: + return ToDuk(ctx, "right"); + default: + return ToDuk(ctx, "straight"); + } +} + +DukValue ScTrackSegment::previousCurveElement_get() const +{ + const auto ctx = GetContext()->GetScriptEngine().GetContext(); + const auto& ted = GetTrackElementDescriptor(_type); + + int32_t curve = ted.CurveChain.previous; + if (curve & RideConstructionSpecialPieceSelected) + return ToDuk(ctx, curve & (~RideConstructionSpecialPieceSelected)); + switch (curve) + { + case 1: + return ToDuk(ctx, "left"); + case 2: + return ToDuk(ctx, "right"); + default: + return ToDuk(ctx, "straight"); + } +} + +DukValue ScTrackSegment::getMirrorElement() const +{ + const auto ctx = GetContext()->GetScriptEngine().GetContext(); + const auto& ted = GetTrackElementDescriptor(_type); + if (ted.MirrorElement == TrackElemType::None) + return ToDuk(ctx, nullptr); + return ToDuk(ctx, ted.MirrorElement); +} + +DukValue ScTrackSegment::getAlternativeElement() const +{ + const auto ctx = GetContext()->GetScriptEngine().GetContext(); + const auto& ted = GetTrackElementDescriptor(_type); + if (ted.AlternativeType == TrackElemType::None) + return ToDuk(ctx, nullptr); + return ToDuk(ctx, ted.AlternativeType); +} + +int32_t ScTrackSegment::getPriceModifier() const +{ + const auto& ted = GetTrackElementDescriptor(_type); + + return ted.PriceModifier; +} + +template bool ScTrackSegment::getTrackFlag() const +{ + const auto& ted = GetTrackElementDescriptor(_type); + + return ted.Flags & flag; +} + +int32_t ScTrackSegment::getTrackGroup() const +{ + const auto& ted = GetTrackElementDescriptor(_type); + + return ted.Definition.type; +} + +std::string ScTrackSegment::getTrackCurvature() const +{ + const auto& ted = GetTrackElementDescriptor(_type); + if (ted.Flags & TRACK_ELEM_FLAG_TURN_LEFT) + return "left"; + if (ted.Flags & TRACK_ELEM_FLAG_TURN_RIGHT) + return "right"; + return "straight"; +} + +std::string ScTrackSegment::getTrackSlopeDirection() const +{ + const auto& ted = GetTrackElementDescriptor(_type); + if (ted.Flags & TRACK_ELEM_FLAG_UP) + return "up"; + if (ted.Flags & TRACK_ELEM_FLAG_DOWN) + return "down"; + return "flat"; +} + #endif diff --git a/src/openrct2/scripting/bindings/ride/ScTrackSegment.h b/src/openrct2/scripting/bindings/ride/ScTrackSegment.h index f5d24c9ccc..7ab34f7936 100644 --- a/src/openrct2/scripting/bindings/ride/ScTrackSegment.h +++ b/src/openrct2/scripting/bindings/ride/ScTrackSegment.h @@ -46,18 +46,28 @@ namespace OpenRCT2::Scripting std::string description_get() const; int32_t beginZ_get() const; int32_t beginDirection_get() const; - int32_t beginAngle_get() const; + int32_t beginSlope_get() const; int32_t beginBank_get() const; int32_t endX_get() const; int32_t endY_get() const; int32_t endZ_get() const; int32_t endDirection_get() const; - int32_t endAngle_get() const; + int32_t endSlope_get() const; int32_t endBank_get() const; int32_t length_get() const; DukValue elements_get() const; uint16_t getSubpositionLength(uint8_t trackSubposition, uint8_t direction) const; std::vector getSubpositions(uint8_t trackSubposition, uint8_t direction) const; + DukValue nextCurveElement_get() const; + DukValue previousCurveElement_get() const; + DukValue getMirrorElement() const; + DukValue getAlternativeElement() const; + int32_t getPriceModifier() const; + int32_t getPreviewZOffset() const; + int32_t getTrackGroup() const; + template bool getTrackFlag() const; + std::string getTrackCurvature() const; + std::string getTrackSlopeDirection() const; }; } // namespace OpenRCT2::Scripting