diff --git a/distribution/changelog.txt b/distribution/changelog.txt index e01467c467..7111b55185 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -11,7 +11,7 @@ - Feature: [#15367] Individual track elements can now be drawn as another ride type. - Feature: [#16029] [Plugin] Add TrackElement.rideType to API. - Feature: [#16097] The Looping Roller Coaster can now draw all elements from the LIM Launched Roller Coaster. -- Feature: [#16132] The Corkscrew Roller Coaster can now draw inline twists. +- Feature: [#16132, #16389] The Corkscrew, Twister and Vertical Drop Roller Coasters can now draw inline twists. - Feature: [#16144] [Plugin] Add ImageManager to API. - Improved: [#3517] Cheats are now saved with the park. - Improved: [#10150] Ride stations are now properly checked if they’re sheltered. diff --git a/src/openrct2/ride/coaster/BolligerMabillardTrack.hpp b/src/openrct2/ride/coaster/BolligerMabillardTrack.hpp index aad467ecd2..3fdbca1f76 100644 --- a/src/openrct2/ride/coaster/BolligerMabillardTrack.hpp +++ b/src/openrct2/ride/coaster/BolligerMabillardTrack.hpp @@ -11819,6 +11819,435 @@ void bolliger_mabillard_track_booster( paint_util_set_general_support_height(session, height + 32, 0x20); } +template +static void bolliger_mabillard_track_left_twist_down_to_up( + paint_session& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27430, 0, 6, 32, 20, 3, height - 5); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27436, 0, 6, 32, 20, 3, height - 5); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27429, 0, 6, 32, 20, 3, height - 5); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27435, 0, 6, 32, 20, 3, height - 5); + break; + } + metal_a_supports_paint_setup(session, supportType, 4, 0, height - 5, session.TrackColours[SCHEME_SUPPORTS]); + if (direction == 0 || direction == 3) + { + paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_SQUARE_FLAT); + } + paint_util_set_segment_support_height( + session, + paint_util_rotate_segments( + SEGMENT_B4 | SEGMENT_B8 | SEGMENT_C4 | SEGMENT_C8 | SEGMENT_CC | SEGMENT_D0, direction), + 0xFFFF, 0); + paint_util_set_general_support_height(session, height + 32, 0x20); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27431, 0, 6, 32, 20, 3, height + 8); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27437, 0, 6, 32, 20, 3, height + 8); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27428, 0, 6, 32, 20, 3, height + 8); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27434, 0, 6, 32, 20, 3, height + 8); + break; + } + paint_util_set_segment_support_height( + session, + paint_util_rotate_segments( + SEGMENT_B4 | SEGMENT_B8 | SEGMENT_C4 | SEGMENT_C8 | SEGMENT_CC | SEGMENT_D0, direction), + 0xFFFF, 0); + paint_util_set_general_support_height(session, height + 32, 0x20); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27432, 0, 6, 32, 20, 3, height - 8); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27438, 0, 6, 32, 20, 3, height - 8); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27427, 0, 6, 32, 20, 3, height - 8); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27433, 0, 6, 32, 20, 3, height - 8); + break; + } + paint_util_set_segment_support_height( + session, + paint_util_rotate_segments( + SEGMENT_B4 | SEGMENT_B8 | SEGMENT_C4 | SEGMENT_C8 | SEGMENT_CC | SEGMENT_D0, direction), + 0xFFFF, 0); + metal_a_supports_paint_setup(session, supportType, 4, 0, height + 4, session.TrackColours[SCHEME_SUPPORTS]); + + switch (direction) + { + case 1: + paint_util_push_tunnel_right(session, height - 32, TUNNEL_SQUARE_FLAT); + break; + case 2: + paint_util_push_tunnel_left(session, height - 32, TUNNEL_SQUARE_FLAT); + break; + } + paint_util_set_general_support_height(session, height + 32, 0x20); + break; + } +} + +template +static void bolliger_mabillard_track_right_twist_down_to_up( + paint_session& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27442, 0, 6, 32, 20, 3, height - 5); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27448, 0, 6, 32, 20, 3, height - 5); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27441, 0, 6, 32, 20, 3, height - 5); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27447, 0, 6, 32, 20, 3, height - 5); + break; + } + metal_a_supports_paint_setup(session, supportType, 4, 0, height - 5, session.TrackColours[SCHEME_SUPPORTS]); + if (direction == 0 || direction == 3) + { + paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_SQUARE_FLAT); + } + paint_util_set_segment_support_height( + session, + paint_util_rotate_segments( + SEGMENT_BC | SEGMENT_C0 | SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0 | SEGMENT_D4, direction), + 0xFFFF, 0); + paint_util_set_general_support_height(session, height + 32, 0x20); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27443, 0, 6, 32, 20, 3, height + 8); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27449, 0, 6, 32, 20, 3, height + 8); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27440, 0, 6, 32, 20, 3, height + 8); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27446, 0, 6, 32, 20, 3, height + 8); + break; + } + paint_util_set_segment_support_height( + session, + paint_util_rotate_segments( + SEGMENT_BC | SEGMENT_C0 | SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0 | SEGMENT_D4, direction), + 0xFFFF, 0); + paint_util_set_general_support_height(session, height + 32, 0x20); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27444, 0, 6, 32, 20, 3, height - 8); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27450, 0, 6, 32, 20, 3, height - 8); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27439, 0, 6, 32, 20, 3, height - 8); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27445, 0, 6, 32, 20, 3, height - 8); + break; + } + paint_util_set_segment_support_height( + session, + paint_util_rotate_segments( + SEGMENT_BC | SEGMENT_C0 | SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0 | SEGMENT_D4, direction), + 0xFFFF, 0); + metal_a_supports_paint_setup(session, supportType, 4, 0, height + 4, session.TrackColours[SCHEME_SUPPORTS]); + + switch (direction) + { + case 1: + paint_util_push_tunnel_right(session, height - 16, TUNNEL_SQUARE_FLAT); + break; + case 2: + paint_util_push_tunnel_left(session, height - 16, TUNNEL_SQUARE_FLAT); + break; + } + paint_util_set_general_support_height(session, height + 32, 0x20); + break; + } +} + +template +static void bolliger_mabillard_track_left_twist_up_to_down( + paint_session& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27427, 0, 6, 32, 20, 3, height - 8); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27433, 0, 6, 32, 20, 3, height - 8); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27432, 0, 6, 32, 20, 3, height - 8); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27438, 0, 6, 32, 20, 3, height - 8); + break; + } + paint_util_set_segment_support_height( + session, + paint_util_rotate_segments( + SEGMENT_BC | SEGMENT_C0 | SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0 | SEGMENT_D4, direction), + 0xFFFF, 0); + metal_a_supports_paint_setup(session, supportType, 4, 0, height + 4, session.TrackColours[SCHEME_SUPPORTS]); + + if (direction == 0 || direction == 3) + { + paint_util_push_tunnel_rotated(session, direction, height - 24, TUNNEL_SQUARE_FLAT); + } + paint_util_set_general_support_height(session, height + 32, 0x20); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27428, 0, 6, 32, 20, 3, height + 8); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27434, 0, 6, 32, 20, 3, height + 8); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27431, 0, 6, 32, 20, 3, height + 8); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27437, 0, 6, 32, 20, 3, height + 8); + break; + } + paint_util_set_segment_support_height( + session, + paint_util_rotate_segments( + SEGMENT_BC | SEGMENT_C0 | SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0 | SEGMENT_D4, direction), + 0xFFFF, 0); + paint_util_set_general_support_height(session, height + 32, 0x20); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27429, 0, 6, 32, 20, 3, height - 5); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27435, 0, 6, 32, 20, 3, height - 5); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27430, 0, 6, 32, 20, 3, height - 5); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27436, 0, 6, 32, 20, 3, height - 5); + break; + } + metal_a_supports_paint_setup(session, supportType, 3, 2, height, session.TrackColours[SCHEME_SUPPORTS]); + metal_a_supports_paint_setup(session, supportType, 4, 0, height - 5, session.TrackColours[SCHEME_SUPPORTS]); + switch (direction) + { + case 1: + paint_util_push_tunnel_right(session, height, TUNNEL_SQUARE_FLAT); + break; + case 2: + paint_util_push_tunnel_left(session, height, TUNNEL_SQUARE_FLAT); + break; + } + paint_util_set_segment_support_height( + session, + paint_util_rotate_segments( + SEGMENT_BC | SEGMENT_C0 | SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0 | SEGMENT_D4, direction), + 0xFFFF, 0); + paint_util_set_general_support_height(session, height + 32, 0x20); + break; + } +} + +template +static void bolliger_mabillard_track_right_twist_up_to_down( + paint_session& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27439, 0, 6, 32, 20, 3, height - 8); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27445, 0, 6, 32, 20, 3, height - 8); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27444, 0, 6, 32, 20, 3, height - 8); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27450, 0, 6, 32, 20, 3, height - 8); + break; + } + paint_util_set_segment_support_height( + session, + paint_util_rotate_segments( + SEGMENT_B4 | SEGMENT_B8 | SEGMENT_C4 | SEGMENT_C8 | SEGMENT_CC | SEGMENT_D0, direction), + 0xFFFF, 0); + metal_a_supports_paint_setup(session, supportType, 4, 0, height + 4, session.TrackColours[SCHEME_SUPPORTS]); + + if (direction == 0 || direction == 3) + { + paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_SQUARE_FLAT); + } + paint_util_set_general_support_height(session, height + 32, 0x20); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27440, 0, 6, 32, 20, 3, height + 8); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27446, 0, 6, 32, 20, 3, height + 8); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27443, 0, 6, 32, 20, 3, height + 8); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27449, 0, 6, 32, 20, 3, height + 8); + break; + } + paint_util_set_segment_support_height( + session, + paint_util_rotate_segments( + SEGMENT_B4 | SEGMENT_B8 | SEGMENT_C4 | SEGMENT_C8 | SEGMENT_CC | SEGMENT_D0, direction), + 0xFFFF, 0); + paint_util_set_general_support_height(session, height + 32, 0x20); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27441, 0, 6, 32, 20, 3, height - 5); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27447, 0, 6, 32, 20, 3, height - 5); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27442, 0, 6, 32, 20, 3, height - 5); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours[SCHEME_TRACK] | 27448, 0, 6, 32, 20, 3, height - 5); + break; + } + metal_a_supports_paint_setup(session, supportType, 4, 0, height - 5, session.TrackColours[SCHEME_SUPPORTS]); + switch (direction) + { + case 1: + paint_util_push_tunnel_right(session, height - 16, TUNNEL_SQUARE_FLAT); + break; + case 2: + paint_util_push_tunnel_left(session, height - 16, TUNNEL_SQUARE_FLAT); + break; + } + paint_util_set_segment_support_height( + session, + paint_util_rotate_segments( + SEGMENT_B4 | SEGMENT_B8 | SEGMENT_C4 | SEGMENT_C8 | SEGMENT_CC | SEGMENT_D0, direction), + 0xFFFF, 0); + paint_util_set_general_support_height(session, height + 32, 0x20); + break; + } +} + template TRACK_PAINT_FUNCTION get_track_paint_function_bolliger_mabillard(int32_t trackType) { switch (trackType) @@ -12186,6 +12615,14 @@ template TRACK_PAINT_FUNCTION get_track_paint_function_boll case TrackElemType::Booster: return bolliger_mabillard_track_booster; + case TrackElemType::LeftTwistDownToUp: + return bolliger_mabillard_track_left_twist_down_to_up; + case TrackElemType::RightTwistDownToUp: + return bolliger_mabillard_track_right_twist_down_to_up; + case TrackElemType::LeftTwistUpToDown: + return bolliger_mabillard_track_left_twist_up_to_down; + case TrackElemType::RightTwistUpToDown: + return bolliger_mabillard_track_right_twist_up_to_down; } return nullptr; } diff --git a/src/openrct2/ride/coaster/meta/TwisterRollerCoaster.h b/src/openrct2/ride/coaster/meta/TwisterRollerCoaster.h index 0381a235e9..2ee294dee2 100644 --- a/src/openrct2/ride/coaster/meta/TwisterRollerCoaster.h +++ b/src/openrct2/ride/coaster/meta/TwisterRollerCoaster.h @@ -21,7 +21,7 @@ constexpr const RideTypeDescriptor TwisterRollerCoasterRTD = { SET_FIELD(AlternateType, RIDE_TYPE_NULL), SET_FIELD(Category, RIDE_CATEGORY_ROLLERCOASTER), - SET_FIELD(EnabledTrackPieces, {TRACK_FLAT, TRACK_STRAIGHT, TRACK_STATION_END, TRACK_LIFT_HILL, TRACK_FLAT_ROLL_BANKING, TRACK_VERTICAL_LOOP, TRACK_SLOPE, TRACK_SLOPE_STEEP, TRACK_SLOPE_CURVE, TRACK_SLOPE_CURVE_STEEP, TRACK_S_BEND, TRACK_CURVE_SMALL, TRACK_CURVE, TRACK_HALF_LOOP, TRACK_CORKSCREW, TRACK_HELIX_SMALL, TRACK_BRAKES, TRACK_ON_RIDE_PHOTO, TRACK_SLOPE_VERTICAL, TRACK_BARREL_ROLL, TRACK_POWERED_LIFT, TRACK_HALF_LOOP_LARGE, TRACK_SLOPE_CURVE_BANKED, TRACK_BLOCK_BRAKES, TRACK_SLOPE_ROLL_BANKING, TRACK_SLOPE_STEEP_LONG, TRACK_CURVE_VERTICAL, TRACK_QUARTER_LOOP, TRACK_BOOSTER}), + SET_FIELD(EnabledTrackPieces, {TRACK_FLAT, TRACK_STRAIGHT, TRACK_STATION_END, TRACK_LIFT_HILL, TRACK_FLAT_ROLL_BANKING, TRACK_VERTICAL_LOOP, TRACK_SLOPE, TRACK_SLOPE_STEEP, TRACK_SLOPE_CURVE, TRACK_SLOPE_CURVE_STEEP, TRACK_S_BEND, TRACK_CURVE_SMALL, TRACK_CURVE, TRACK_HALF_LOOP, TRACK_CORKSCREW, TRACK_HELIX_SMALL, TRACK_BRAKES, TRACK_ON_RIDE_PHOTO, TRACK_SLOPE_VERTICAL, TRACK_BARREL_ROLL, TRACK_POWERED_LIFT, TRACK_HALF_LOOP_LARGE, TRACK_SLOPE_CURVE_BANKED, TRACK_BLOCK_BRAKES, TRACK_SLOPE_ROLL_BANKING, TRACK_SLOPE_STEEP_LONG, TRACK_CURVE_VERTICAL, TRACK_QUARTER_LOOP, TRACK_BOOSTER, TRACK_TWIST}), SET_FIELD(ExtraTrackPieces, {TRACK_LIFT_HILL_STEEP, TRACK_BRAKE_FOR_DROP}), SET_FIELD(CoveredTrackPieces, {}), SET_FIELD(StartTrackPiece, TrackElemType::EndStation), diff --git a/src/openrct2/ride/coaster/meta/VerticalDropCoaster.h b/src/openrct2/ride/coaster/meta/VerticalDropCoaster.h index 3a1c296fb3..d84e8df7dd 100644 --- a/src/openrct2/ride/coaster/meta/VerticalDropCoaster.h +++ b/src/openrct2/ride/coaster/meta/VerticalDropCoaster.h @@ -22,7 +22,7 @@ constexpr const RideTypeDescriptor VerticalDropCoasterRTD = SET_FIELD(AlternateType, RIDE_TYPE_NULL), SET_FIELD(Category, RIDE_CATEGORY_ROLLERCOASTER), SET_FIELD(EnabledTrackPieces, {TRACK_FLAT, TRACK_STRAIGHT, TRACK_STATION_END, TRACK_LIFT_HILL, TRACK_LIFT_HILL_STEEP, TRACK_FLAT_ROLL_BANKING, TRACK_VERTICAL_LOOP, TRACK_SLOPE, TRACK_SLOPE_STEEP, TRACK_SLOPE_LONG, TRACK_SLOPE_CURVE, TRACK_SLOPE_CURVE_STEEP, TRACK_S_BEND, TRACK_CURVE_SMALL, TRACK_CURVE, TRACK_HELIX_SMALL, TRACK_BRAKES, TRACK_ON_RIDE_PHOTO, TRACK_SLOPE_VERTICAL, TRACK_SLOPE_CURVE_BANKED, TRACK_BLOCK_BRAKES, TRACK_SLOPE_ROLL_BANKING, TRACK_CURVE_VERTICAL, TRACK_HALF_LOOP_LARGE, TRACK_BRAKE_FOR_DROP}), - SET_FIELD(ExtraTrackPieces, {TRACK_HALF_LOOP, TRACK_CORKSCREW, TRACK_BARREL_ROLL, TRACK_POWERED_LIFT, TRACK_HALF_LOOP_LARGE, TRACK_QUARTER_LOOP, TRACK_BOOSTER}), + SET_FIELD(ExtraTrackPieces, {TRACK_HALF_LOOP, TRACK_CORKSCREW, TRACK_BARREL_ROLL, TRACK_POWERED_LIFT, TRACK_HALF_LOOP_LARGE, TRACK_QUARTER_LOOP, TRACK_BOOSTER, TRACK_TWIST}), SET_FIELD(CoveredTrackPieces, {}), SET_FIELD(StartTrackPiece, TrackElemType::EndStation), SET_FIELD(TrackPaintFunction, get_track_paint_function_bolliger_mabillard),