diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index 1b0fdff98c..6af3a75986 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -1701,11 +1701,22 @@ declare global { readonly slopes12Banked22?: SpriteGroup; readonly slopes8Banked22?: SpriteGroup; readonly slopes25Banked22?: SpriteGroup; + readonly slopes8Banked45?: SpriteGroup; + readonly slopes16Banked22?: SpriteGroup; + readonly slopes16Banked45?: SpriteGroup; readonly slopes25Banked45?: SpriteGroup; readonly slopes12Banked45?: SpriteGroup; + readonly slopes25Banked67?: SpriteGroup; + readonly slopes25Banked67?: SpriteGroup; + readonly slopes25InlineTwists?: SpriteGroup; + readonly slopes42Banked22?: SpriteGroup; + readonly slopes42Banked45?: SpriteGroup; + readonly slopes42Banked90?: SpriteGroup; + readonly slopes60Banked22?: SpriteGroup; readonly corkscrews?: SpriteGroup; readonly restraintAnimation?: SpriteGroup; - readonly curvedLiftHill?: SpriteGroup; + readonly curvedLiftHillUp?: SpriteGroup; + readonly curvedLiftHillDown?: SpriteGroup; } /** diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 577c3376a5..4d2586c18e 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -43,7 +43,7 @@ // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "16" +#define NETWORK_STREAM_VERSION "17" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION diff --git a/src/openrct2/object/RideObject.cpp b/src/openrct2/object/RideObject.cpp index 12fd88b6ff..ad2144c106 100644 --- a/src/openrct2/object/RideObject.cpp +++ b/src/openrct2/object/RideObject.cpp @@ -38,9 +38,25 @@ using namespace OpenRCT2; using namespace OpenRCT2::Entity::Yaw; +/* + * The number of sprites in the sprite group is the specified precision multiplied by this number. General rule is any slope or + * bank has its mirror included in the group: + * - flat unbanked is 1 + * - flat banked is 2 (left/right) + * - sloped unbanked is 2 (up/down) + * - sloped & banked is 4 (left/right * up/down) + * Exceptions: + * - slopesLoop is 10 (5 slope angles * up/down) + * - inlineTwists is 6 (3 bank angles * left/right) + * - slopes25InlineTwists is 12 (3 bank angles * left/right * up/down) + * - corkscrews is 20 (10 sprites for an entire corkscrew * left/right) + * - restraints is 3 + * - curvedLiftHillUp and curvedLiftHillDown are 1 (normally would be combined, but aren't due to RCT2) + */ static const uint8_t SpriteGroupMultiplier[EnumValue(SpriteGroupType::Count)] = { - 1, 2, 2, 2, 2, 2, 2, 10, 1, 2, 2, 2, 2, 2, 2, 2, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 20, 3, 1, + 1, 2, 2, 2, 2, 2, 2, 10, 1, 2, 2, 2, 2, 2, 2, 2, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 20, 3, 1, 1, }; +static_assert(std::size(SpriteGroupMultiplier) == EnumValue(SpriteGroupType::Count)); constexpr const uint8_t DefaultSteamSpawnPosition[] = { 11, 22 }; @@ -1103,7 +1119,7 @@ void RideObject::ReadLegacySpriteGroups(CarEntry* vehicle, uint16_t spriteGroups } if (spriteGroups & CAR_SPRITE_FLAG_CURVED_LIFT_HILL) { - vehicle->SpriteGroups[EnumValue(SpriteGroupType::CurvedLiftHill)].spritePrecision = baseSpritePrecision; + vehicle->SpriteGroups[EnumValue(SpriteGroupType::CurvedLiftHillUp)].spritePrecision = baseSpritePrecision; } } diff --git a/src/openrct2/ride/CarEntry.h b/src/openrct2/ride/CarEntry.h index 982ed87f8b..f91b4770d1 100644 --- a/src/openrct2/ride/CarEntry.h +++ b/src/openrct2/ride/CarEntry.h @@ -46,7 +46,7 @@ enum : uint32_t CAR_ENTRY_FLAG_REVERSER_BOGIE = 1 << 4, CAR_ENTRY_FLAG_REVERSER_PASSENGER_CAR = 1 << 5, CAR_ENTRY_FLAG_HAS_INVERTED_SPRITE_SET = 1 << 6, // Set on vehicles that support running inverted for extended periods - // of time, i.e. the Flying, Lay-down and Multi-dimension RCs. + // of time, i.e. the Flying, Lay-down and Multi-dimension RCs. CAR_ENTRY_FLAG_DODGEM_INUSE_LIGHTS = 1 << 7, // When set the vehicle has an additional frame for when in use. Used only by dodgems. CAR_ENTRY_FLAG_ALLOW_DOORS_DEPRECATED = 1 << 8, // Not used any more - every vehicle will now work with doors. @@ -56,13 +56,13 @@ enum : uint32_t << 11, // Instead of the default 32 rotation frames. Only used for boat hire and works only for non sloped sprites. CAR_ENTRY_FLAG_OVERRIDE_NUM_VERTICAL_FRAMES = 1 << 12, // Setting this will cause the game to set carEntry->num_vertical_frames to - // carEntry->num_vertical_frames_override, rather than determining it itself. + // carEntry->num_vertical_frames_override, rather than determining it itself. CAR_ENTRY_FLAG_SPRITE_BOUNDS_INCLUDE_INVERTED_SET = 1 << 13, // Used together with HAS_INVERTED_SPRITE_SET and RECALCULATE_SPRITE_BOUNDS and includes the inverted sprites - // into the function that recalculates the sprite bounds. + // into the function that recalculates the sprite bounds. CAR_ENTRY_FLAG_SPINNING_ADDITIONAL_FRAMES = 1 << 14, // 16x additional frames for vehicle. A spinning item with additional frames must always face forward to - // load/unload. Spinning without can load/unload at 4 rotations. + // load/unload. Spinning without can load/unload at 4 rotations. CAR_ENTRY_FLAG_LIFT = 1 << 15, CAR_ENTRY_FLAG_ENABLE_TRIM_COLOUR = 1 << 16, CAR_ENTRY_FLAG_SWINGING = 1 << 17, @@ -72,14 +72,14 @@ enum : uint32_t CAR_ENTRY_FLAG_SUSPENDED_SWING = 1 << 21, // Suspended swinging coaster, or bobsleigh if SLIDE_SWING is also enabled. CAR_ENTRY_FLAG_BOAT_HIRE_COLLISION_DETECTION = 1 << 22, CAR_ENTRY_FLAG_VEHICLE_ANIMATION = 1 << 23, // Set on animated vehicles like the Multi-dimension coaster trains, - // Miniature Railway locomotives and Helicycles. - CAR_ENTRY_FLAG_RIDER_ANIMATION = 1 << 24, // Set when the animation updates rider sprite positions. + // Miniature Railway locomotives and Helicycles. + CAR_ENTRY_FLAG_RIDER_ANIMATION = 1 << 24, // Set when the animation updates rider sprite positions. CAR_ENTRY_FLAG_WOODEN_WILD_MOUSE_SWING = 1 << 25, CAR_ENTRY_FLAG_LOADING_WAYPOINTS = 1 << 26, // Peep loading positions have x and y coordinates. Normal rides just have offsets. CAR_ENTRY_FLAG_SLIDE_SWING = 1 << 27, // Set on dingy slides. They have there own swing value calculations and have a different amount of images. - // Also set on bobsleighs together with the SUSPENDED_SWING flag. + // Also set on bobsleighs together with the SUSPENDED_SWING flag. CAR_ENTRY_FLAG_CHAIRLIFT = 1 << 28, CAR_ENTRY_FLAG_WATER_RIDE = 1 << 29, // Set on rides where water would provide continuous propulsion. CAR_ENTRY_FLAG_GO_KART = 1 << 30, @@ -107,6 +107,10 @@ enum : uint32_t CAR_SPRITE_FLAG_USE_4_ROTATION_FRAMES = (1 << 15), }; +/* + * When adding a sprite group, add multiplier to SpriteGroupMultiplier in RideObject.cpp and add sprite group data to cable + * lifthill vehicle in RideData.cpp and update the SpriteGroups interface in distribution/openrct2.d.ts + */ enum class SpriteGroupType : uint8_t { SlopeFlat = 0, @@ -144,20 +148,22 @@ enum class SpriteGroupType : uint8_t Slopes60Banked22, Corkscrews, RestraintAnimation, - CurvedLiftHill, + CurvedLiftHillUp, + CurvedLiftHillDown, Count }; static const std::string SpriteGroupNames[] = { - "slopeFlat", "slopes12", "slopes25", "slopes42", - "slopes60", "slopes75", "slopes90", "slopesLoop", - "slopeInverted", "slopes8", "slopes16", "slopes50", - "flatBanked22", "flatBanked45", "flatBanked67", "flatBanked90", - "inlineTwists", "slopes12Banked22", "slopes8Banked22", "slopes25Banked22", - "slopes8Banked45", "slopes16Banked22", "slopes16Banked45", "slopes25Banked45", - "slopes12Banked45", "slopes25Banked67", "slopes25Banked90", "slopes25InlineTwists", - "slopes42Banked22", "slopes42Banked45", "slopes42Banked67", "slopes42Banked90", - "slopes60Banked22", "corkscrews", "restraintAnimation", "curvedLiftHill", + "slopeFlat", "slopes12", "slopes25", "slopes42", + "slopes60", "slopes75", "slopes90", "slopesLoop", + "slopeInverted", "slopes8", "slopes16", "slopes50", + "flatBanked22", "flatBanked45", "flatBanked67", "flatBanked90", + "inlineTwists", "slopes12Banked22", "slopes8Banked22", "slopes25Banked22", + "slopes8Banked45", "slopes16Banked22", "slopes16Banked45", "slopes25Banked45", + "slopes12Banked45", "slopes25Banked67", "slopes25Banked90", "slopes25InlineTwists", + "slopes42Banked22", "slopes42Banked45", "slopes42Banked67", "slopes42Banked90", + "slopes60Banked22", "corkscrews", "restraintAnimation", "curvedLiftHillUp", + "curvedLiftHillDown", }; static_assert(std::size(SpriteGroupNames) == EnumValue(SpriteGroupType::Count)); @@ -203,7 +209,7 @@ struct CarEntry uint8_t effect_visual; uint8_t draw_order; uint8_t num_vertical_frames_override; // A custom number that can be used rather than letting RCT2 determine it. - // Needs the CAR_ENTRY_FLAG_OVERRIDE_NUM_VERTICAL_FRAMES flag to be set. + // Needs the CAR_ENTRY_FLAG_OVERRIDE_NUM_VERTICAL_FRAMES flag to be set. uint8_t peep_loading_waypoint_segments; uint16_t AnimationSpeed; uint8_t AnimationFrames; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 540feb5710..4d2471eb0e 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -4792,8 +4792,8 @@ OpenRCT2::BitSet RideEntryGetSupportedTrackPieces(const RideO SpritePrecision::Sprites4 }, // TRACK_SLOPE_STEEP_LONG { SpriteGroupType::Slopes90, SpritePrecision::Sprites16 }, // TRACK_CURVE_VERTICAL { SpriteGroupType::Slopes25, SpritePrecision::Sprites4, SpriteGroupType::Slopes60, - SpritePrecision::Sprites4 }, // TRACK_LIFT_HILL_CABLE - { SpriteGroupType::CurvedLiftHill, SpritePrecision::Sprites16 }, // TRACK_LIFT_HILL_CURVED + SpritePrecision::Sprites4 }, // TRACK_LIFT_HILL_CABLE + { SpriteGroupType::CurvedLiftHillUp, SpritePrecision::Sprites16 }, // TRACK_LIFT_HILL_CURVED { SpriteGroupType::Slopes90, SpritePrecision::Sprites4, SpriteGroupType::SlopesLoop, SpritePrecision::Sprites4, SpriteGroupType::SlopeInverted, SpritePrecision::Sprites4 }, // TRACK_QUARTER_LOOP { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites4 }, // TRACK_SPINNING_TUNNEL diff --git a/src/openrct2/ride/RideData.cpp b/src/openrct2/ride/RideData.cpp index 82b240f357..0e42cbbed9 100644 --- a/src/openrct2/ride/RideData.cpp +++ b/src/openrct2/ride/RideData.cpp @@ -172,7 +172,8 @@ const CarEntry CableLiftVehicle = { /* .SpriteGroups[Slopes60Banked22] = */ 0, SpritePrecision::None, /* .SpriteGroups[Corkscrews] = */ 0, SpritePrecision::None, /* .SpriteGroups[RestraintAnimation] = */ 0, SpritePrecision::None, - /* .SpriteGroups[CurvedLiftHill] = */ 0, SpritePrecision::None, + /* .SpriteGroups[CurvedLiftHillUp] = */ 0, SpritePrecision::None, + /* .SpriteGroups[CurvedLiftHillDown] = */ 0, SpritePrecision::None, /* .no_vehicle_images = */ 0, /* .no_seating_rows = */ 0, /* .spinning_inertia = */ 0, diff --git a/src/openrct2/ride/VehiclePaint.cpp b/src/openrct2/ride/VehiclePaint.cpp index 6a5921f0ae..134d075bd4 100644 --- a/src/openrct2/ride/VehiclePaint.cpp +++ b/src/openrct2/ride/VehiclePaint.cpp @@ -944,7 +944,7 @@ const uint8_t PitchInvertTable[] = { 0, 0, 0, 0, 0, 0, // Helices 53, 54, 55, 50, 51, 52, // Slopes 2 56, 57, 58, // Zero-G Rolls - 0 // 59 = Spiral Lift. This is the only pitch with no corresponding pitch down, so flat will be used instead + 60, 59 // Spiral Lift Hills }; // Opposite Bank values for reversed cars @@ -3674,13 +3674,28 @@ static void VehiclePitchInvertingDown60( #pragma region SpiralLiftSlopes // 6D4773 -static void VehiclePitchSpiralLift( +static void VehiclePitchSpiralLiftUp( PaintSession& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const CarEntry* carEntry) { - if (carEntry->GroupEnabled(SpriteGroupType::CurvedLiftHill)) + if (carEntry->GroupEnabled(SpriteGroupType::CurvedLiftHillUp)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = carEntry->SpriteOffset(SpriteGroupType::CurvedLiftHill, imageDirection, 0); + int32_t spriteNum = carEntry->SpriteOffset(SpriteGroupType::CurvedLiftHillUp, imageDirection, 0); + VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, carEntry); + } + else + { + VehiclePitchFlat(session, vehicle, imageDirection, z, carEntry); + } +} + +static void VehiclePitchSpiralLiftDown( + PaintSession& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const CarEntry* carEntry) +{ + if (carEntry->GroupEnabled(SpriteGroupType::CurvedLiftHillDown)) + { + int32_t boundingBoxNum = YawTo16(imageDirection); + int32_t spriteNum = carEntry->SpriteOffset(SpriteGroupType::CurvedLiftHillDown, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, carEntry); } else @@ -3756,7 +3771,8 @@ static constexpr const vehicle_sprite_func PaintFunctionsByPitch[] = { VehiclePitchInvertingDown25, VehiclePitchInvertingDown42, VehiclePitchInvertingDown60, - VehiclePitchSpiralLift, + VehiclePitchSpiralLiftUp, + VehiclePitchSpiralLiftDown, }; // clang-format on diff --git a/src/openrct2/scripting/ScriptEngine.h b/src/openrct2/scripting/ScriptEngine.h index fb53ae9220..113c6b834a 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 = 75; + static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 76; // Versions marking breaking changes. static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33;