diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index 98c0a1d734..5930928e20 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -876,13 +876,50 @@ declare global { readonly shopItemSecondary: number; } + /** + * Represents a VehicleSpriteGroup + */ + interface SpriteGroup { + readonly imageId: number; + readonly spriteNumImages: number; + } + + /** + * Represents the sprite groups of a vehicle + */ + interface SpriteGroups { + readonly slopeFlat?: SpriteGroup; + readonly slopes12?: SpriteGroup; + readonly slopes25?: SpriteGroup; + readonly slopes42?: SpriteGroup; + readonly slopes60?: SpriteGroup; + readonly slopes75?: SpriteGroup; + readonly slopes90?: SpriteGroup; + readonly slopesLoop?: SpriteGroup; + readonly slopeInverted?: SpriteGroup; + readonly slopes8?: SpriteGroup; + readonly slopes16?: SpriteGroup; + readonly slopes50?: SpriteGroup; + readonly flatBanked22?: SpriteGroup; + readonly flatBanked45?: SpriteGroup; + readonly flatBanked67?: SpriteGroup; + readonly flatBanked90?: SpriteGroup; + readonly inlineTwists?: SpriteGroup; + readonly slopes12Banked22?: SpriteGroup; + readonly slopes8Banked22?: SpriteGroup; + readonly slopes25Banked22?: SpriteGroup; + readonly slopes25Banked45?: SpriteGroup; + readonly slopes12Banked45?: SpriteGroup; + readonly corkscrews?: SpriteGroup; + readonly restraintAnimation?: SpriteGroup; + readonly curvedLiftHill?: SpriteGroup; + } + /** * Represents a defined vehicle within a Ride object definition. */ interface RideObjectVehicle { readonly rotationFrameMask: number; - readonly numVerticalFrames: number; - readonly numHorizontalFrames: number; readonly spacing: number; readonly carMass: number; readonly tabHeight: number; @@ -895,20 +932,7 @@ declare global { readonly flags: number; readonly baseNumFrames: number; readonly baseImageId: number; - readonly restraintImageId: number; - readonly gentleSlopeImageId: number; - readonly steepSlopeImageId: number; - readonly verticalSlopeImageId: number; - readonly diagonalSlopeImageId: number; - readonly bankedImageId: number; - readonly inlineTwistImageId: number; - readonly flatToGentleBankImageId: number; - readonly diagonalToGentleSlopeBankImageId: number; - readonly gentleSlopeToBankImageId: number; - readonly gentleSlopeBankTurnImageId: number; - readonly flatBankToGentleSlopeImageId: number; - readonly curvedLiftHillImageId: number; - readonly corkscrewImageId: number; + readonly spriteGroups: SpriteGroups; readonly noVehicleImages: number; readonly noSeatingRows: number; readonly spinningInertia: number; diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index f701c17ed7..fd0bc4671a 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -942,10 +942,11 @@ static void WindowRideDrawTabVehicle(rct_drawpixelinfo* dpi, rct_window* w) auto vehicleId = ((ride->colour_scheme_type & 3) == VEHICLE_COLOUR_SCHEME_PER_VEHICLE) ? rideEntry->tab_vehicle : 0; VehicleColour vehicleColour = ride_get_vehicle_colour(ride, vehicleId); - auto imageIndex = 32; + // imageIndex represents a precision of 64 + auto imageIndex = OpenRCT2::Entity::Yaw::YawFrom4(2) * 2; if (w->page == WINDOW_RIDE_PAGE_VEHICLE) imageIndex += w->frame_no; - imageIndex = rideVehicleEntry->SpriteByYaw(imageIndex / 2); + imageIndex = rideVehicleEntry->SpriteByYaw(imageIndex / 2, SpriteGroupType::SlopeFlat); imageIndex &= rideVehicleEntry->TabRotationMask; imageIndex *= rideVehicleEntry->base_num_frames; imageIndex += rideVehicleEntry->base_image_id; @@ -2959,7 +2960,8 @@ static void WindowRideVehicleScrollpaint(rct_window* w, rct_drawpixelinfo* dpi, } VehicleColour vehicleColour = ride_get_vehicle_colour(ride, vehicleColourIndex); - ImageIndex imageIndex = rideVehicleEntry->SpriteByYaw(16); + ImageIndex imageIndex = rideVehicleEntry->SpriteByYaw( + OpenRCT2::Entity::Yaw::BaseRotation / 2, SpriteGroupType::SlopeFlat); imageIndex &= rideVehicleEntry->TabRotationMask; imageIndex *= rideVehicleEntry->base_num_frames; imageIndex += rideVehicleEntry->base_image_id; @@ -4828,7 +4830,8 @@ static void WindowRideColourScrollpaint(rct_window* w, rct_drawpixelinfo* dpi, i screenCoords.y += rideVehicleEntry->tab_height; // Draw the coloured spinning vehicle - ImageIndex imageIndex = rideVehicleEntry->SpriteByYaw(w->frame_no / 2); + // w->frame_no represents a SpritePrecision of 64 + ImageIndex imageIndex = rideVehicleEntry->SpriteByYaw(w->frame_no / 2, SpriteGroupType::SlopeFlat); imageIndex &= rideVehicleEntry->TabRotationMask; imageIndex *= rideVehicleEntry->base_num_frames; imageIndex += rideVehicleEntry->base_image_id; diff --git a/src/openrct2/entity/Yaw.hpp b/src/openrct2/entity/Yaw.hpp index 90b14987b3..77a5ba6a4e 100644 --- a/src/openrct2/entity/Yaw.hpp +++ b/src/openrct2/entity/Yaw.hpp @@ -13,10 +13,24 @@ namespace OpenRCT2::Entity::Yaw { + enum class SpritePrecision : uint8_t + { + None = 0, + Sprites1, + Sprites2, + Sprites4, + Sprites8, + Sprites16, + Sprites32, + Sprites64 + }; + + // Sprites32 represents the precision of the base rotation precision. Base rotation is the precision of + // EntityBase.sprite_direction constexpr const int32_t BaseRotation = 32; - // smallest precision is 4 frames - constexpr const uint8_t PrecisionOffset[] = { 3, 2, 1, 0, 0, 0, 0, 0 }; + // The first value represents None, the last value represents 64 which has not yet been implemented + constexpr const uint8_t PrecisionOffset[] = { 5, 5, 4, 3, 2, 1, 0, 0 }; [[nodiscard]] constexpr int32_t Add(int32_t yaw1, int32_t yaw2) { @@ -42,12 +56,14 @@ namespace OpenRCT2::Entity::Yaw { return yaw; } - [[nodiscard]] constexpr int32_t YawToPrecision(int32_t yaw, uint8_t precision) + + [[nodiscard]] constexpr int32_t YawToPrecision(int32_t yaw, SpritePrecision precision) { - return yaw >> PrecisionOffset[precision]; + return yaw >> PrecisionOffset[static_cast(precision)]; } - [[nodiscard]] constexpr uint8_t NumSpritesPrecision(uint8_t precision) + + [[nodiscard]] constexpr uint8_t NumSpritesPrecision(SpritePrecision precision) { - return 4 << precision; + return (1 << static_cast(precision)) >> 1; } } // namespace OpenRCT2::Entity::Yaw diff --git a/src/openrct2/object/RideObject.cpp b/src/openrct2/object/RideObject.cpp index 40b009168a..3aab631540 100644 --- a/src/openrct2/object/RideObject.cpp +++ b/src/openrct2/object/RideObject.cpp @@ -20,6 +20,7 @@ #include "../core/String.hpp" #include "../drawing/Drawing.h" #include "../drawing/Image.h" +#include "../entity/Yaw.hpp" #include "../localisation/Language.h" #include "../rct2/DATLimits.h" #include "../rct2/RCT2.h" @@ -35,6 +36,19 @@ #include using namespace OpenRCT2; +using namespace OpenRCT2::Entity::Yaw; + +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, 20, 3, 1, +}; + +static constexpr SpritePrecision PrecisionFromNumFrames(uint8_t numRotationFrames) +{ + if (numRotationFrames == 0) + return SpritePrecision::None; + else + return static_cast(bitscanforward(numRotationFrames) + 1); +} static void RideObjectUpdateRideType(rct_ride_entry* rideEntry) { @@ -203,7 +217,7 @@ void RideObject::Load() for (int32_t i = 0; i < RCT2::ObjectLimits::MaxVehiclesPerRideEntry; i++) { rct_ride_entry_vehicle* vehicleEntry = &_legacyType.vehicles[i]; - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT) + if (vehicleEntry->GroupEnabled(SpriteGroupType::SlopeFlat)) { // RCT2 calculates num_vertical_frames and num_horizontal_frames and overwrites these properties on the vehicle // entry. Immediately afterwards, the two were multiplied in order to calculate base_num_frames and were never used @@ -212,134 +226,32 @@ void RideObject::Load() // 0x6DE946 vehicleEntry->base_num_frames = CalculateNumVerticalFrames(vehicleEntry) * CalculateNumHorizontalFrames(vehicleEntry); - vehicleEntry->base_image_id = cur_vehicle_images_offset; - uint32_t image_index = vehicleEntry->base_image_id; + uint32_t baseImageId = cur_vehicle_images_offset; + uint32_t imageIndex = baseImageId; + vehicleEntry->base_image_id = baseImageId; - if (vehicleEntry->PaintStyle != VEHICLE_VISUAL_RIVER_RAPIDS) + for (uint8_t spriteGroup = 0; spriteGroup < EnumValue(SpriteGroupType::Count); spriteGroup++) { - const auto numRotationFrames = vehicleEntry->NumRotationFrames(); - uint32_t b = vehicleEntry->base_num_frames * numRotationFrames; - - image_index += b; - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPES) + if (vehicleEntry->SpriteGroups[spriteGroup].Enabled()) { - vehicleEntry->gentle_slope_image_id = image_index; - b = vehicleEntry->base_num_frames * ((2 * numRotationFrames) + (2 * NumOrthogonalDirections)); - if (vehicleEntry->flags & VEHICLE_ENTRY_FLAG_SPINNING_ADDITIONAL_FRAMES) - { - b = vehicleEntry->base_num_frames * 16; - } - image_index += b; + vehicleEntry->SpriteGroups[spriteGroup].imageId = imageIndex; + const auto spriteCount = vehicleEntry->base_num_frames + * vehicleEntry->NumRotationSprites(static_cast(spriteGroup)) + * SpriteGroupMultiplier[spriteGroup]; + imageIndex += spriteCount; } - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_STEEP_SLOPES) - { - vehicleEntry->steep_slope_image_id = image_index; - b = vehicleEntry->base_num_frames * ((2 * numRotationFrames) + (4 * NumOrthogonalDirections)); - image_index += b; - } - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) - { - vehicleEntry->vertical_slope_image_id = image_index; - b = vehicleEntry->base_num_frames * ((2 * numRotationFrames) + (13 * NumOrthogonalDirections)); - image_index += b; - } - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES) - { - vehicleEntry->diagonal_slope_image_id = image_index; - b = vehicleEntry->base_num_frames * 24; - image_index += b; - } - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_BANKED) - { - vehicleEntry->banked_image_id = image_index; - b = vehicleEntry->base_num_frames * ((2 * numRotationFrames) + (4 * NumOrthogonalDirections)); - image_index += b; - } - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) - { - vehicleEntry->inline_twist_image_id = image_index; - b = vehicleEntry->base_num_frames * 40; - image_index += b; - } - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS) - { - vehicleEntry->flat_to_gentle_bank_image_id = image_index; - b = vehicleEntry->base_num_frames * (4 * numRotationFrames); - image_index += b; - } - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_GENTLE_SLOPE_BANKED_TRANSITIONS) - { - vehicleEntry->diagonal_to_gentle_slope_bank_image_id = image_index; - b = vehicleEntry->base_num_frames * 16; - image_index += b; - } - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TRANSITIONS) - { - vehicleEntry->gentle_slope_to_bank_image_id = image_index; - b = vehicleEntry->base_num_frames * 16; - image_index += b; - } - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TURNS) - { - vehicleEntry->gentle_slope_bank_turn_image_id = image_index; - b = vehicleEntry->base_num_frames * (4 * numRotationFrames); - image_index += b; - } - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_WHILE_BANKED_TRANSITIONS) - { - vehicleEntry->flat_bank_to_gentle_slope_image_id = image_index; - b = vehicleEntry->base_num_frames * 16; - image_index += b; - } - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_CORKSCREWS) - { - vehicleEntry->corkscrew_image_id = image_index; - b = vehicleEntry->base_num_frames * 80; - image_index += b; - } - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_RESTRAINT_ANIMATION) - { - vehicleEntry->restraint_image_id = image_index; - b = vehicleEntry->base_num_frames * 12; - image_index += b; - } - - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_CURVED_LIFT_HILL) - { - // Same offset as corkscrew - vehicleEntry->curved_lift_hill_image_id = image_index; - b = vehicleEntry->base_num_frames * numRotationFrames; - image_index += b; - } - } - else - { - image_index += vehicleEntry->base_num_frames * 36; } // No vehicle images - vehicleEntry->no_vehicle_images = image_index - cur_vehicle_images_offset; + vehicleEntry->no_vehicle_images = imageIndex - cur_vehicle_images_offset; // Move the offset over this vehicles images. Including peeps - cur_vehicle_images_offset = image_index + vehicleEntry->no_seating_rows * vehicleEntry->no_vehicle_images; + cur_vehicle_images_offset = imageIndex + vehicleEntry->no_seating_rows * vehicleEntry->no_vehicle_images; // 0x6DEB0D if (!(vehicleEntry->flags & VEHICLE_ENTRY_FLAG_RECALCULATE_SPRITE_BOUNDS)) { - int32_t num_images = cur_vehicle_images_offset - vehicleEntry->base_image_id; + int32_t num_images = cur_vehicle_images_offset - baseImageId; if (vehicleEntry->flags & VEHICLE_ENTRY_FLAG_SPRITE_BOUNDS_INCLUDE_INVERTED_SET) { num_images *= 2; @@ -440,7 +352,7 @@ void RideObject::ReadLegacyVehicle( vehicle->car_mass = stream->ReadValue(); vehicle->tab_height = stream->ReadValue(); vehicle->num_seats = stream->ReadValue(); - vehicle->sprite_flags = stream->ReadValue(); + uint16_t spriteGroups = stream->ReadValue(); vehicle->sprite_width = stream->ReadValue(); vehicle->sprite_height_negative = stream->ReadValue(); vehicle->sprite_height_positive = stream->ReadValue(); @@ -462,12 +374,7 @@ void RideObject::ReadLegacyVehicle( vehicle->draw_order = stream->ReadValue(); vehicle->num_vertical_frames_override = stream->ReadValue(); stream->Seek(4, STREAM_SEEK_CURRENT); - - vehicle->SpriteYawPrecision = 3; - if (vehicle->flags & VEHICLE_ENTRY_FLAG_USE_16_ROTATION_FRAMES) - vehicle->SpriteYawPrecision = 2; - if (vehicle->flags & VEHICLE_SPRITE_FLAG_USE_4_ROTATION_FRAMES) - vehicle->SpriteYawPrecision = 0; + ReadLegacySpriteGroups(vehicle, spriteGroups); } uint8_t RideObject::CalculateNumVerticalFrames(const rct_ride_entry_vehicle* vehicleEntry) @@ -589,7 +496,7 @@ void RideObject::ReadJson(IReadObjectContext* context, json_t& root) // Standard car info for a shop auto& car = _legacyType.vehicles[0]; car.spacing = 544; - car.sprite_flags = VEHICLE_SPRITE_FLAG_FLAT; + car.SpriteGroups[EnumValue(SpriteGroupType::SlopeFlat)].spritePrecision = SpritePrecision::Sprites4; car.sprite_width = 1; car.sprite_height_negative = 1; car.sprite_height_positive = 1; @@ -735,7 +642,6 @@ rct_ride_entry_vehicle RideObject::ReadJsonCar([[maybe_unused]] IReadObjectConte rct_ride_entry_vehicle car = {}; car.TabRotationMask = Json::GetNumber(jCar["rotationFrameMask"]); - car.SpriteYawPrecision = 3; car.spacing = Json::GetNumber(jCar["spacing"]); car.car_mass = Json::GetNumber(jCar["mass"]); car.tab_height = Json::GetNumber(jCar["tabOffset"]); @@ -804,35 +710,6 @@ rct_ride_entry_vehicle RideObject::ReadJsonCar([[maybe_unused]] IReadObjectConte } } - auto jFrames = jCar["frames"]; - if (jFrames.is_object()) - { - car.sprite_flags = Json::GetFlags( - jFrames, - { - { "flat", VEHICLE_SPRITE_FLAG_FLAT }, - { "gentleSlopes", VEHICLE_SPRITE_FLAG_GENTLE_SLOPES }, - { "steepSlopes", VEHICLE_SPRITE_FLAG_STEEP_SLOPES }, - { "verticalSlopes", VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES }, - { "diagonalSlopes", VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES }, - { "flatBanked", VEHICLE_SPRITE_FLAG_FLAT_BANKED }, - { "inlineTwists", VEHICLE_SPRITE_FLAG_INLINE_TWISTS }, - { "flatToGentleSlopeBankedTransitions", VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS }, - { "diagonalGentleSlopeBankedTransitions", VEHICLE_SPRITE_FLAG_DIAGONAL_GENTLE_SLOPE_BANKED_TRANSITIONS }, - { "gentleSlopeBankedTransitions", VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TRANSITIONS }, - { "gentleSlopeBankedTurns", VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TURNS }, - { "flatToGentleSlopeWhileBankedTransitions", - VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_WHILE_BANKED_TRANSITIONS }, - { "corkscrews", VEHICLE_SPRITE_FLAG_CORKSCREWS }, - { "restraintAnimation", VEHICLE_SPRITE_FLAG_RESTRAINT_ANIMATION }, - { "curvedLiftHill", VEHICLE_SPRITE_FLAG_CURVED_LIFT_HILL }, - }); - if (jFrames.contains("VEHICLE_SPRITE_FLAG_15") && Json::GetBoolean(jFrames, "VEHICLE_SPRITE_FLAG_15")) - { - car.SpriteYawPrecision = 0; - } - } - car.flags |= Json::GetFlags( jCar, { @@ -897,9 +774,56 @@ rct_ride_entry_vehicle RideObject::ReadJsonCar([[maybe_unused]] IReadObjectConte { "VEHICLE_ENTRY_FLAG_WATER_RIDE", VEHICLE_ENTRY_FLAG_WATER_RIDE }, { "VEHICLE_ENTRY_FLAG_GO_KART", VEHICLE_ENTRY_FLAG_GO_KART }, { "VEHICLE_ENTRY_FLAG_DODGEM_CAR_PLACEMENT", VEHICLE_ENTRY_FLAG_DODGEM_CAR_PLACEMENT }, + { "VEHICLE_ENTRY_FLAG_11", VEHICLE_ENTRY_FLAG_USE_16_ROTATION_FRAMES }, }); - if (jCar.contains("VEHICLE_ENTRY_FLAG_11") && Json::GetBoolean(jCar, "VEHICLE_ENTRY_FLAG_11")) - car.SpriteYawPrecision = 2; + + // legacy sprite groups + auto jFrames = jCar["frames"]; + if (jFrames.is_object()) + { + uint16_t spriteFlags = Json::GetFlags( + jFrames, + { + { "flat", VEHICLE_SPRITE_FLAG_FLAT }, + { "gentleSlopes", VEHICLE_SPRITE_FLAG_GENTLE_SLOPES }, + { "steepSlopes", VEHICLE_SPRITE_FLAG_STEEP_SLOPES }, + { "verticalSlopes", VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES }, + { "diagonalSlopes", VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES }, + { "flatBanked", VEHICLE_SPRITE_FLAG_FLAT_BANKED }, + { "inlineTwists", VEHICLE_SPRITE_FLAG_INLINE_TWISTS }, + { "flatToGentleSlopeBankedTransitions", VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS }, + { "diagonalGentleSlopeBankedTransitions", VEHICLE_SPRITE_FLAG_DIAGONAL_GENTLE_SLOPE_BANKED_TRANSITIONS }, + { "gentleSlopeBankedTransitions", VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TRANSITIONS }, + { "gentleSlopeBankedTurns", VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TURNS }, + { "flatToGentleSlopeWhileBankedTransitions", + VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_WHILE_BANKED_TRANSITIONS }, + { "corkscrews", VEHICLE_SPRITE_FLAG_CORKSCREWS }, + { "restraintAnimation", VEHICLE_SPRITE_FLAG_RESTRAINT_ANIMATION }, + { "curvedLiftHill", VEHICLE_SPRITE_FLAG_CURVED_LIFT_HILL }, + { "VEHICLE_SPRITE_FLAG_15", VEHICLE_SPRITE_FLAG_USE_4_ROTATION_FRAMES }, + }); + ReadLegacySpriteGroups(&car, spriteFlags); + return car; + } + + // OpenRCT2 sprite groups + auto jRotationCount = jCar["spriteGroups"]; + if (jRotationCount.is_object()) + { + for (uint8_t i = 0; i < EnumValue(SpriteGroupType::Count); i++) + { + auto numRotationFrames = Json::GetNumber(jRotationCount[SpriteGroupNames[i]], 0); + if (numRotationFrames != 0) + { + if (!is_power_of_2(numRotationFrames)) + { + context->LogError(ObjectError::InvalidProperty, "spriteGroups values must be powers of 2"); + continue; + } + car.SpriteGroups[i].spritePrecision = PrecisionFromNumFrames(numRotationFrames); + } + } + } return car; } @@ -1147,3 +1071,86 @@ ShopItem RideObject::ParseShopItem(const std::string& s) auto result = ShopItemLookupTable.find(s); return (result != ShopItemLookupTable.end()) ? result->second : ShopItem::None; } + +// Converts legacy sprite groups into OpenRCT2 sprite groups +void RideObject::ReadLegacySpriteGroups(rct_ride_entry_vehicle* vehicle, uint16_t spriteGroups) +{ + auto baseSpritePrecision = SpritePrecision::Sprites32; + if (vehicle->flags & VEHICLE_ENTRY_FLAG_USE_16_ROTATION_FRAMES) + baseSpritePrecision = SpritePrecision::Sprites16; + if (vehicle->flags & VEHICLE_SPRITE_FLAG_USE_4_ROTATION_FRAMES) + baseSpritePrecision = SpritePrecision::Sprites4; + + if (spriteGroups & VEHICLE_SPRITE_FLAG_FLAT) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::SlopeFlat)].spritePrecision = baseSpritePrecision; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_GENTLE_SLOPES) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes12)].spritePrecision = SpritePrecision::Sprites4; + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes25)].spritePrecision = baseSpritePrecision; + if (vehicle->flags & VEHICLE_ENTRY_FLAG_SPINNING_ADDITIONAL_FRAMES) + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes25)].spritePrecision = SpritePrecision::Sprites4; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_STEEP_SLOPES) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes42)].spritePrecision = SpritePrecision::Sprites8; + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes60)].spritePrecision = baseSpritePrecision; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes75)].spritePrecision = SpritePrecision::Sprites4; + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes90)].spritePrecision = baseSpritePrecision; + vehicle->SpriteGroups[EnumValue(SpriteGroupType::SlopesLoop)].spritePrecision = SpritePrecision::Sprites4; + vehicle->SpriteGroups[EnumValue(SpriteGroupType::SlopeInverted)].spritePrecision = SpritePrecision::Sprites4; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes8)].spritePrecision = SpritePrecision::Sprites4; + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes16)].spritePrecision = SpritePrecision::Sprites4; + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes50)].spritePrecision = SpritePrecision::Sprites4; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_FLAT_BANKED) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::FlatBanked22)].spritePrecision = SpritePrecision::Sprites8; + vehicle->SpriteGroups[EnumValue(SpriteGroupType::FlatBanked45)].spritePrecision = baseSpritePrecision; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::FlatBanked67)].spritePrecision = SpritePrecision::Sprites4; + vehicle->SpriteGroups[EnumValue(SpriteGroupType::FlatBanked90)].spritePrecision = SpritePrecision::Sprites4; + vehicle->SpriteGroups[EnumValue(SpriteGroupType::InlineTwists)].spritePrecision = SpritePrecision::Sprites4; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes12Banked22)].spritePrecision = baseSpritePrecision; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_DIAGONAL_GENTLE_SLOPE_BANKED_TRANSITIONS) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes8Banked22)].spritePrecision = SpritePrecision::Sprites4; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TRANSITIONS) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes25Banked22)].spritePrecision = SpritePrecision::Sprites4; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TURNS) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes25Banked45)].spritePrecision = baseSpritePrecision; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_WHILE_BANKED_TRANSITIONS) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Slopes12Banked45)].spritePrecision = SpritePrecision::Sprites4; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_CORKSCREWS) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::Corkscrews)].spritePrecision = SpritePrecision::Sprites4; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_RESTRAINT_ANIMATION) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::RestraintAnimation)].spritePrecision = SpritePrecision::Sprites4; + } + if (spriteGroups & VEHICLE_SPRITE_FLAG_CURVED_LIFT_HILL) + { + vehicle->SpriteGroups[EnumValue(SpriteGroupType::CurvedLiftHill)].spritePrecision = baseSpritePrecision; + } +} diff --git a/src/openrct2/object/RideObject.h b/src/openrct2/object/RideObject.h index cbb8d4db12..df4a8f9710 100644 --- a/src/openrct2/object/RideObject.h +++ b/src/openrct2/object/RideObject.h @@ -62,4 +62,6 @@ private: static uint8_t ParseRideCategory(const std::string& s); static ShopItem ParseShopItem(const std::string& s); static colour_t ParseColour(const std::string& s); + + void ReadLegacySpriteGroups(rct_ride_entry_vehicle* vehicle, uint16_t spriteGroups); }; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index f638dc8375..c14f2fbf7c 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -4833,78 +4833,128 @@ uint8_t ride_entry_get_vehicle_at_position(int32_t rideEntryIndex, int32_t numCa return rideEntry->default_vehicle; } +using namespace OpenRCT2::Entity::Yaw; + +struct NecessarySpriteGroup +{ + SpriteGroupType VehicleSpriteGroup; + SpritePrecision MinPrecision; +}; + // Finds track pieces that a given ride entry has sprites for uint64_t ride_entry_get_supported_track_pieces(const rct_ride_entry* rideEntry) { - // clang-format off - static constexpr uint32_t trackPieceRequiredSprites[TRACK_GROUP_COUNT] = - { - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_FLAT - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_STRAIGHT - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_STATION_END - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES, // TRACK_LIFT_HILL - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES | VEHICLE_SPRITE_FLAG_STEEP_SLOPES, // TRACK_LIFT_HILL_STEEP - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES, // TRACK_LIFT_HILL_CURVE - VEHICLE_SPRITE_FLAG_FLAT_BANKED, // TRACK_FLAT_ROLL_BANKING - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES | VEHICLE_SPRITE_FLAG_STEEP_SLOPES | VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES, // TRACK_VERTICAL_LOOP - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_GENTLE_SLOPES, // TRACK_SLOPE - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES | VEHICLE_SPRITE_FLAG_STEEP_SLOPES, // TRACK_SLOPE_STEEP_DOWN - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_GENTLE_SLOPES | VEHICLE_SPRITE_FLAG_STEEP_SLOPES, // TRACK_SLOPE_LONG - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES, // TRACK_SLOPE_CURVE - VEHICLE_SPRITE_FLAG_STEEP_SLOPES, // TRACK_SLOPE_CURVE_STEEP - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_S_BEND - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_CURVE_VERY_SMALL - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_CURVE_SMALL - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_CURVE - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_FLAT_BANKED | VEHICLE_SPRITE_FLAG_INLINE_TWISTS, // TRACK_TWIST - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES | VEHICLE_SPRITE_FLAG_STEEP_SLOPES | VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES, // TRACK_HALF_LOOP - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS | VEHICLE_SPRITE_FLAG_CORKSCREWS, // TRACK_CORKSCREW - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_TOWER_BASE - VEHICLE_SPRITE_FLAG_FLAT_BANKED, // TRACK_HELIX_SMALL - VEHICLE_SPRITE_FLAG_FLAT_BANKED, // TRACK_HELIX_LARGE - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_HELIX_LARGE_UNBANKED - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_BRAKES - 0, // TRACK_25 - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_ON_RIDE_PHOTO - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_WATER_SPLASH - VEHICLE_SPRITE_FLAG_STEEP_SLOPES | VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES, // TRACK_SLOPE_VERTICAL - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_FLAT_BANKED | VEHICLE_SPRITE_FLAG_INLINE_TWISTS, // TRACK_BARREL_ROLL - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES, // TRACK_POWERED_LIFT - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES | VEHICLE_SPRITE_FLAG_STEEP_SLOPES | VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES, // TRACK_HALF_LOOP_LARGE - VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS | VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TURNS, // TRACK_SLOPE_CURVE_BANKED - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_LOG_FLUME_REVERSER - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_FLAT_BANKED | VEHICLE_SPRITE_FLAG_INLINE_TWISTS, // TRACK_HEARTLINE_ROLL - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_REVERSER - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_REVERSE_FREEFALL - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_GENTLE_SLOPES | VEHICLE_SPRITE_FLAG_STEEP_SLOPES | VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES, // TRACK_SLOPE_TO_FLAT - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_BLOCK_BRAKES - VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TRANSITIONS, // TRACK_SLOPE_ROLL_BANKING - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_GENTLE_SLOPES | VEHICLE_SPRITE_FLAG_STEEP_SLOPES, // TRACK_SLOPE_STEEP_LONG - VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES, // TRACK_CURVE_VERTICAL - 0, // TRACK_42 - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES, // TRACK_LIFT_HILL_CABLE - VEHICLE_SPRITE_FLAG_CURVED_LIFT_HILL, // TRACK_LIFT_HILL_CURVED - VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES, // TRACK_QUARTER_LOOP - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_SPINNING_TUNNEL - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_ROTATION_CONTROL_TOGGLE - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_FLAT_BANKED | VEHICLE_SPRITE_FLAG_INLINE_TWISTS, // TRACK_INLINE_TWIST_UNINVERTED - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_FLAT_BANKED | VEHICLE_SPRITE_FLAG_INLINE_TWISTS, // TRACK_INLINE_TWIST_INVERTED - VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES, // TRACK_QUARTER_LOOP_UNINVERTED - VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES, // TRACK_QUARTER_LOOP_INVERTED - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES, // TRACK_RAPIDS - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES | VEHICLE_SPRITE_FLAG_STEEP_SLOPES | VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES, // TRACK_HALF_LOOP_UNINVERTED - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES | VEHICLE_SPRITE_FLAG_STEEP_SLOPES | VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES, // TRACK_HALF_LOOP_INVERTED - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_WATERFALL - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_WHIRLPOOL - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_GENTLE_SLOPES | VEHICLE_SPRITE_FLAG_STEEP_SLOPES, // TRACK_BRAKE_FOR_DROP - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS | VEHICLE_SPRITE_FLAG_CORKSCREWS, // TRACK_CORKSCREW_UNINVERTED - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS | VEHICLE_SPRITE_FLAG_CORKSCREWS, // TRACK_CORKSCREW_INVERTED - VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_GENTLE_SLOPES, // TRACK_HEARTLINE_TRANSFER - 0, // TRACK_MINI_GOLF_HOLE - VEHICLE_SPRITE_FLAG_FLAT, // TRACK_ROTATION_CONTROL_TOGGLE - VEHICLE_SPRITE_FLAG_GENTLE_SLOPES | VEHICLE_SPRITE_FLAG_STEEP_SLOPES, // TRACK_SLOPE_STEEP_UP + // TODO: Use a std::span when C++20 available as 6 is due to jagged array + static const std::array trackPieceRequiredSprites[TRACK_GROUP_COUNT] = { + { SpriteGroupType::SlopeFlat, SpritePrecision::None }, // TRACK_FLAT + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites4 }, // TRACK_STRAIGHT + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites4 }, // TRACK_STATION_END + { SpriteGroupType::Slopes25, SpritePrecision::Sprites4 }, // TRACK_LIFT_HILL + { SpriteGroupType::Slopes25, SpritePrecision::Sprites4, SpriteGroupType::Slopes60, + SpritePrecision::Sprites4 }, // TRACK_LIFT_HILL_STEEP + { SpriteGroupType::Slopes25, SpritePrecision::Sprites16 }, // TRACK_LIFT_HILL_CURVE + { SpriteGroupType::FlatBanked22, SpritePrecision::Sprites4, SpriteGroupType::FlatBanked45, + SpritePrecision::Sprites16 }, // TRACK_FLAT_ROLL_BANKING + { SpriteGroupType::Slopes60, SpritePrecision::Sprites4, SpriteGroupType::Slopes75, SpritePrecision::Sprites4, + SpriteGroupType::Slopes90, SpritePrecision::Sprites4, SpriteGroupType::SlopesLoop, SpritePrecision::Sprites4, + SpriteGroupType::SlopeInverted, SpritePrecision::Sprites4 }, // TRACK_VERTICAL_LOOP + { SpriteGroupType::Slopes25, SpritePrecision::Sprites4 }, // TRACK_SLOPE + { SpriteGroupType::Slopes60, SpritePrecision::Sprites4 }, // TRACK_SLOPE_STEEP_DOWN + { SpriteGroupType::Slopes25, SpritePrecision::Sprites4, SpriteGroupType::Slopes60, + SpritePrecision::Sprites4 }, // TRACK_SLOPE_LONG + { SpriteGroupType::Slopes25, SpritePrecision::Sprites16 }, // TRACK_SLOPE_CURVE + { SpriteGroupType::Slopes60, SpritePrecision::Sprites16 }, // TRACK_SLOPE_CURVE_STEEP + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites16 }, // TRACK_S_BEND + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites16 }, // TRACK_CURVE_VERY_SMALL + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites16 }, // TRACK_CURVE_SMALL + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites16 }, // TRACK_CURVE + { SpriteGroupType::FlatBanked22, SpritePrecision::Sprites4, SpriteGroupType::FlatBanked45, SpritePrecision::Sprites4, + SpriteGroupType::FlatBanked67, SpritePrecision::Sprites4, SpriteGroupType::FlatBanked90, SpritePrecision::Sprites4, + SpriteGroupType::InlineTwists, SpritePrecision::Sprites4, SpriteGroupType::SlopeInverted, + SpritePrecision::Sprites4 }, // TRACK_TWIST + { SpriteGroupType::Slopes60, SpritePrecision::Sprites4, SpriteGroupType::Slopes75, SpritePrecision::Sprites4, + SpriteGroupType::Slopes90, SpritePrecision::Sprites4, SpriteGroupType::SlopesLoop, SpritePrecision::Sprites4, + SpriteGroupType::SlopeInverted, SpritePrecision::Sprites4 }, // TRACK_HALF_LOOP + { SpriteGroupType::Corkscrews, SpritePrecision::Sprites4, SpriteGroupType::SlopeInverted, + SpritePrecision::Sprites4 }, // TRACK_CORKSCREW + { SpriteGroupType::SlopeFlat, SpritePrecision::None }, // TRACK_TOWER_BASE + { SpriteGroupType::FlatBanked45, SpritePrecision::Sprites16 }, // TRACK_HELIX_SMALL + { SpriteGroupType::FlatBanked45, SpritePrecision::Sprites16 }, // TRACK_HELIX_LARGE + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites16 }, // TRACK_HELIX_LARGE_UNBANKED + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites4 }, // TRACK_BRAKES + {}, // TRACK_25 + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites4 }, // TRACK_ON_RIDE_PHOTO + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites4, SpriteGroupType::Slopes12, + SpritePrecision::Sprites4 }, // TRACK_WATER_SPLASH + { SpriteGroupType::Slopes75, SpritePrecision::Sprites4, SpriteGroupType::Slopes90, + SpritePrecision::Sprites4 }, // TRACK_SLOPE_VERTICAL + { SpriteGroupType::FlatBanked22, SpritePrecision::Sprites4, SpriteGroupType::FlatBanked45, SpritePrecision::Sprites4, + SpriteGroupType::InlineTwists, SpritePrecision::Sprites4, SpriteGroupType::SlopeInverted, + SpritePrecision::Sprites4 }, // TRACK_BARREL_ROLL + { SpriteGroupType::Slopes25, SpritePrecision::Sprites4 }, // TRACK_POWERED_LIFT + { SpriteGroupType::Slopes60, SpritePrecision::Sprites4, SpriteGroupType::Slopes75, SpritePrecision::Sprites4, + SpriteGroupType::Slopes90, SpritePrecision::Sprites4, SpriteGroupType::SlopesLoop, SpritePrecision::Sprites4, + SpriteGroupType::SlopeInverted, SpritePrecision::Sprites4 }, // TRACK_HALF_LOOP_LARGE + { SpriteGroupType::Slopes25Banked45, SpritePrecision::Sprites16 }, // TRACK_SLOPE_CURVE_BANKED + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites16 }, // TRACK_LOG_FLUME_REVERSER + { SpriteGroupType::FlatBanked22, SpritePrecision::Sprites4, SpriteGroupType::FlatBanked45, SpritePrecision::Sprites4, + SpriteGroupType::InlineTwists, SpritePrecision::Sprites4, SpriteGroupType::SlopeInverted, + SpritePrecision::Sprites4 }, // TRACK_HEARTLINE_ROLL + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites16 }, // TRACK_REVERSER + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites4, SpriteGroupType::Slopes25, SpritePrecision::Sprites4, + SpriteGroupType::Slopes60, SpritePrecision::Sprites4, SpriteGroupType::Slopes75, SpritePrecision::Sprites4, + SpriteGroupType::Slopes90, SpritePrecision::Sprites4 }, // TRACK_REVERSE_FREEFALL + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites4, SpriteGroupType::Slopes25, SpritePrecision::Sprites4, + SpriteGroupType::Slopes60, SpritePrecision::Sprites4, SpriteGroupType::Slopes75, SpritePrecision::Sprites4, + SpriteGroupType::Slopes90, SpritePrecision::Sprites4 }, // TRACK_SLOPE_TO_FLAT + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites4 }, // TRACK_BLOCK_BRAKES + { SpriteGroupType::Slopes25Banked22, SpritePrecision::Sprites4 }, // TRACK_SLOPE_ROLL_BANKING + { SpriteGroupType::Slopes25, SpritePrecision::Sprites4, SpriteGroupType::Slopes60, + SpritePrecision::Sprites4 }, // TRACK_SLOPE_STEEP_LONG + { SpriteGroupType::Slopes90, SpritePrecision::Sprites16 }, // TRACK_CURVE_VERTICAL + {}, // TRACK_42 + { SpriteGroupType::Slopes25, SpritePrecision::Sprites4, SpriteGroupType::Slopes60, + SpritePrecision::Sprites4 }, // TRACK_LIFT_HILL_CABLE + { SpriteGroupType::CurvedLiftHill, 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 + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites4 }, // TRACK_ROTATION_CONTROL_TOGGLE + { SpriteGroupType::FlatBanked22, SpritePrecision::Sprites4, SpriteGroupType::FlatBanked45, SpritePrecision::Sprites4, + SpriteGroupType::FlatBanked67, SpritePrecision::Sprites4, SpriteGroupType::FlatBanked90, SpritePrecision::Sprites4, + SpriteGroupType::InlineTwists, SpritePrecision::Sprites4, SpriteGroupType::SlopeInverted, + SpritePrecision::Sprites4 }, // TRACK_INLINE_TWIST_UNINVERTED + { SpriteGroupType::FlatBanked22, SpritePrecision::Sprites4, SpriteGroupType::FlatBanked45, SpritePrecision::Sprites4, + SpriteGroupType::FlatBanked67, SpritePrecision::Sprites4, SpriteGroupType::FlatBanked90, SpritePrecision::Sprites4, + SpriteGroupType::InlineTwists, SpritePrecision::Sprites4, SpriteGroupType::SlopeInverted, + SpritePrecision::Sprites4 }, // TRACK_INLINE_TWIST_INVERTED + { SpriteGroupType::Slopes25, SpritePrecision::Sprites4, SpriteGroupType::Slopes60, SpritePrecision::Sprites4, + SpriteGroupType::Slopes75, SpritePrecision::Sprites4, SpriteGroupType::Slopes90, + SpritePrecision::Sprites4 }, // TRACK_QUARTER_LOOP_UNINVERTED + { SpriteGroupType::Slopes90, SpritePrecision::Sprites4, SpriteGroupType::SlopesLoop, SpritePrecision::Sprites4, + SpriteGroupType::SlopeInverted, SpritePrecision::Sprites4 }, // TRACK_QUARTER_LOOP_INVERTED + { SpriteGroupType::Slopes12, SpritePrecision::Sprites4 }, // TRACK_RAPIDS + { SpriteGroupType::Slopes25, SpritePrecision::Sprites4, SpriteGroupType::Slopes60, SpritePrecision::Sprites4, + SpriteGroupType::Slopes75, SpritePrecision::Sprites4, SpriteGroupType::Slopes90, + SpritePrecision::Sprites4 }, // TRACK_HALF_LOOP_UNINVERTED + { SpriteGroupType::Slopes25, SpritePrecision::Sprites4, SpriteGroupType::Slopes60, SpritePrecision::Sprites4, + SpriteGroupType::Slopes75, SpritePrecision::Sprites4, SpriteGroupType::Slopes90, SpritePrecision::Sprites4, + SpriteGroupType::SlopesLoop, SpritePrecision::Sprites4, SpriteGroupType::SlopeInverted, + SpritePrecision::Sprites4 }, // TRACK_HALF_LOOP_INVERTED + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites4 }, // TRACK_WATERFALL + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites4 }, // TRACK_WHIRLPOOL + { SpriteGroupType::Slopes25, SpritePrecision::Sprites4, SpriteGroupType::Slopes60, + SpritePrecision::Sprites4 }, // TRACK_BRAKE_FOR_DROP + { SpriteGroupType::Corkscrews, SpritePrecision::Sprites4, SpriteGroupType::SlopeInverted, + SpritePrecision::Sprites4 }, // TRACK_CORKSCREW_UNINVERTED + { SpriteGroupType::Corkscrews, SpritePrecision::Sprites4, SpriteGroupType::SlopeInverted, + SpritePrecision::Sprites4 }, // TRACK_CORKSCREW_INVERTED + { SpriteGroupType::Slopes12, SpritePrecision::Sprites4, SpriteGroupType::Slopes25, + SpritePrecision::Sprites4 }, // TRACK_HEARTLINE_TRANSFER + {}, // TRACK_MINI_GOLF_HOLE + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites4 }, // TRACK_ROTATION_CONTROL_TOGGLE + { SpriteGroupType::Slopes60, SpritePrecision::Sprites4 }, // TRACK_SLOPE_STEEP_UP }; - // clang-format on // Only check default vehicle; it's assumed the others will have correct sprites if this one does (I've yet to find an // exception, at least) @@ -4912,12 +4962,13 @@ uint64_t ride_entry_get_supported_track_pieces(const rct_ride_entry* rideEntry) auto defaultVehicle = rideEntry->GetDefaultVehicle(); if (defaultVehicle != nullptr) { - const auto defaultSpriteFlags = defaultVehicle->sprite_flags; for (size_t i = 0; i < std::size(trackPieceRequiredSprites); i++) { - if ((defaultSpriteFlags & trackPieceRequiredSprites[i]) != trackPieceRequiredSprites[i]) + for (auto& group : trackPieceRequiredSprites[i]) { - supportedPieces &= ~(1ULL << i); + auto precision = defaultVehicle->SpriteGroups[static_cast(group.VehicleSpriteGroup)].spritePrecision; + if (precision < group.MinPrecision) + supportedPieces &= ~(1ULL << i); } } } diff --git a/src/openrct2/ride/RideData.cpp b/src/openrct2/ride/RideData.cpp index 5c80115141..e2383cd0ec 100644 --- a/src/openrct2/ride/RideData.cpp +++ b/src/openrct2/ride/RideData.cpp @@ -119,17 +119,16 @@ #include +using namespace OpenRCT2::Entity::Yaw; + // clang-format off const rct_ride_entry_vehicle CableLiftVehicle = { /* .TabRotationMask = */ 31, - /* .SpriteYawPrecision = */ 3, - /* .pad_03 = */ 0, /* .spacing = */ 0, /* .car_mass = */ 0, /* .tab_height = */ 0, /* .num_seats = */ 0, - /* .sprite_flags = */ VEHICLE_SPRITE_FLAG_FLAT | VEHICLE_SPRITE_FLAG_GENTLE_SLOPES | VEHICLE_SPRITE_FLAG_STEEP_SLOPES, /* .sprite_width = */ 0, /* .sprite_height_negative = */ 0, /* .sprite_height_positive = */ 0, @@ -137,19 +136,32 @@ const rct_ride_entry_vehicle CableLiftVehicle = { /* .flags = */ 0, /* .base_num_frames = */ 1, /* .base_image_id = */ 29110, - /* .restraint_image_id = */ 0, - /* .gentle_slope_image_id = */ 29142, - /* .steep_slope_image_id = */ 29214, - /* .vertical_slope_image_id = */ 0, - /* .diagonal_slope_image_id = */ 0, - /* .banked_image_id = */ 0, - /* .inline_twist_image_id = */ 0, - /* .flat_to_gentle_bank_image_id = */ 0, - /* .diagonal_to_gentle_slope_bank_image_id = */ 0, - /* .gentle_slope_to_bank_image_id = */ 0, - /* .gentle_slope_bank_turn_image_id = */ 0, - /* .flat_bank_to_gentle_slope_image_id = */ 0, - /* .corkscrew_image_id = */ 0, + /* .SpriteGroups[SlopeFlat] = */ 29110, SpritePrecision::Sprites32, + /* .SpriteGroups[Slopes12] = */ 29142, SpritePrecision::Sprites4, + /* .SpriteGroups[Slopes25] = */ 29150, SpritePrecision::Sprites32, + /* .SpriteGroups[Slopes42] = */ 29214, SpritePrecision::Sprites8, + /* .SpriteGroups[Slopes60] = */ 29230, SpritePrecision::Sprites32, + /* .SpriteGroups[Slopes75] = */ 0, SpritePrecision::None, + /* .SpriteGroups[Slopes90] = */ 0, SpritePrecision::None, + /* .SpriteGroups[SlopesLoop] = */ 0, SpritePrecision::None, + /* .SpriteGroups[SlopeInverted] = */ 0, SpritePrecision::None, + /* .SpriteGroups[Slopes8] = */ 0, SpritePrecision::None, + /* .SpriteGroups[Slopes16] = */ 0, SpritePrecision::None, + /* .SpriteGroups[Slopes50] = */ 0, SpritePrecision::None, + /* .SpriteGroups[FlatBanked22] = */ 0, SpritePrecision::None, + /* .SpriteGroups[FlatBanked45] = */ 0, SpritePrecision::None, + /* .SpriteGroups[FlatBanked67] = */ 0, SpritePrecision::None, + /* .SpriteGroups[FlatBanked90] = */ 0, SpritePrecision::None, + /* .SpriteGroups[InlineTwists] = */ 0, SpritePrecision::None, + /* .SpriteGroups[Slopes12Banked22] = */ 0, SpritePrecision::None, + /* .SpriteGroups[Slopes8Banked22] = */ 0, SpritePrecision::None, + /* .SpriteGroups[Slopes25Banked22] = */ 0, SpritePrecision::None, + /* .SpriteGroups[Slopes25Banked45] = */ 0, SpritePrecision::None, + /* .SpriteGroups[Slopes12Banked45] = */ 0, SpritePrecision::None, + /* .SpriteGroups[Corkscrews] = */ 0, SpritePrecision::None, + /* .SpriteGroups[RestraintAnimation] = */ 0, SpritePrecision::None, + /* .SpriteGroups[CurvedLiftHill] = */ 0, SpritePrecision::None, + /* .no_vehicle_images = */ 0, /* .no_seating_rows = */ 0, /* .spinning_inertia = */ 0, diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 7981a22d8a..20f00e4dcb 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -9385,13 +9385,3 @@ void Vehicle::Serialise(DataSerialiser& stream) stream << BoatLocation; stream << IsCrashedVehicle; } - -uint32_t rct_ride_entry_vehicle::NumRotationFrames() const -{ - return OpenRCT2::Entity::Yaw::NumSpritesPrecision(SpriteYawPrecision); -} - -int32_t rct_ride_entry_vehicle::SpriteByYaw(int32_t yaw) const -{ - return OpenRCT2::Entity::Yaw::YawToPrecision(yaw, SpriteYawPrecision); -} diff --git a/src/openrct2/ride/VehicleData.cpp b/src/openrct2/ride/VehicleData.cpp index ee0bf614fa..d1bcc33cd1 100644 --- a/src/openrct2/ride/VehicleData.cpp +++ b/src/openrct2/ride/VehicleData.cpp @@ -799,7 +799,8 @@ const int32_t MotionSimulatorTimeToSpriteMapCount = static_cast(std::si The distance between subposition points in a movement direction (but not distance). */ const int32_t SubpositionTranslationDistances[] = { - // For a base length of 8716 (0x220C) on the horizontal and 6554 (0x199A) on the vertical, use the Pythagoras theorem and round up. + // For a base length of 8716 (0x220C) on the horizontal and 6554 (0x199A) on the vertical, + // use the Pythagoras theorem and round up. 0, // no movement 8716, // X translation 8716, // Y translation @@ -822,6 +823,7 @@ const int32_t SubpositionTranslationDistances[] = { /** rct2: 0x009A2970 */ const int32_t AccelerationFromPitch[] = { 0, // Flat + // The geometric angle of slopes 12.5 and 25 are actually 11.1 and 22.2 respectively. -124548, // 1 Slope Up 12.5 -243318, // 2 Slope Up 25 -416016, // 3 Slope Up 42.5 @@ -871,14 +873,14 @@ const int32_t AccelerationFromPitch[] = { 55854, // 47 Half Helix Down Small -66768, // 48 Quarter Helix Up 66768, // 49 Quarter Helix Down - -90522, // 50 Diag Slope Up 12.5 - -179760, // 51 Diag Slope Up 25 - // DiagUp25ToUp60 has transition slopes of 2 and 3 - -484068, // 52 Diag Slope Up 60 - 90522, // 53 Diag Slope Down 12.5 - 179760, // 54 Diag Slope Down 25 - // DiagDown25ToDown60 has transition slopes of 6 and 7 - 484068, // 55 Diag Slope Down 60 + // currently only diagonal elements use slopes angles 8, 16, 50. Diagonal gentle-to-steep transition uses + // diagonal sprites of slopes 25 and 42. + -90522, // 50 Slope Up 8 + -179760, // 51 Slope Down 16 + -484068, // 52 Slope Up 50 + 90522, // 53 Slope Down 8 + 179760, // 54 Slope Down 16 + 484068, // 55 Slope Down 50 243318, // 56 Inverting Loop Down 25 416016, // 57 Inverting Loop Down 42.5 546342, // 58 Inverting Loop Down 60 diff --git a/src/openrct2/ride/VehicleEntry.h b/src/openrct2/ride/VehicleEntry.h index 5d4cb24deb..7d08a655b7 100644 --- a/src/openrct2/ride/VehicleEntry.h +++ b/src/openrct2/ride/VehicleEntry.h @@ -87,44 +87,73 @@ enum : uint32_t VEHICLE_SPRITE_FLAG_USE_4_ROTATION_FRAMES = (1 << 15), }; +enum class SpriteGroupType : uint8_t +{ + SlopeFlat = 0, + Slopes12, + Slopes25, + Slopes42, + Slopes60, + Slopes75, + Slopes90, + SlopesLoop, + SlopeInverted, + Slopes8, + Slopes16, + Slopes50, + FlatBanked22, + FlatBanked45, + FlatBanked67, + FlatBanked90, + InlineTwists, + Slopes12Banked22, + Slopes8Banked22, + Slopes25Banked22, + Slopes25Banked45, + Slopes12Banked45, + Corkscrews, + RestraintAnimation, + CurvedLiftHill, + 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", + "slopes25Banked45", "slopes12Banked45", "corkscrews", "restraintAnimation", "curvedLiftHill", +}; +static_assert(std::size(SpriteGroupNames) == EnumValue(SpriteGroupType::Count)); + +struct VehicleSpriteGroup +{ + uint32_t imageId{}; + OpenRCT2::Entity::Yaw::SpritePrecision spritePrecision{}; + bool Enabled() const + { + return spritePrecision != OpenRCT2::Entity::Yaw::SpritePrecision::None; + } +}; + /** * Ride type vehicle structure. - * size: 0x65 */ struct rct_ride_entry_vehicle { uint16_t TabRotationMask; - uint8_t SpriteYawPrecision; - uint8_t pad_03; uint32_t spacing; uint16_t car_mass; int8_t tab_height; uint8_t num_seats; - uint32_t sprite_flags; uint8_t sprite_width; uint8_t sprite_height_negative; uint8_t sprite_height_positive; uint8_t animation; uint32_t flags; - uint16_t base_num_frames; // The number of sprites for a flat non-banked track piece. - uint32_t base_image_id; // Following image_id's populated during loading - uint32_t restraint_image_id; - uint32_t gentle_slope_image_id; - uint32_t steep_slope_image_id; - uint32_t vertical_slope_image_id; - uint32_t diagonal_slope_image_id; - uint32_t banked_image_id; - uint32_t inline_twist_image_id; - uint32_t flat_to_gentle_bank_image_id; - uint32_t diagonal_to_gentle_slope_bank_image_id; - uint32_t gentle_slope_to_bank_image_id; - uint32_t gentle_slope_bank_turn_image_id; - uint32_t flat_bank_to_gentle_slope_image_id; - union - { - uint32_t curved_lift_hill_image_id; - uint32_t corkscrew_image_id; - }; + uint16_t base_num_frames; // The number of sprites of animation or swinging per rotation frame + uint32_t base_image_id; + VehicleSpriteGroup SpriteGroups[EnumValue(SpriteGroupType::Count)]; uint32_t no_vehicle_images; uint8_t no_seating_rows; uint8_t spinning_inertia; @@ -141,10 +170,12 @@ struct rct_ride_entry_vehicle uint8_t num_vertical_frames_override; // A custom number that can be used rather than letting RCT2 determine it. // Needs the VEHICLE_ENTRY_FLAG_OVERRIDE_NUM_VERTICAL_FRAMES flag to be set. uint8_t peep_loading_waypoint_segments; - uint8_t pad_62[6] = {}; std::vector> peep_loading_waypoints = {}; std::vector peep_loading_positions = {}; - uint32_t NumRotationFrames() const; - int32_t SpriteByYaw(int32_t yaw) const; + uint32_t NumRotationSprites(SpriteGroupType rotationType) const; + int32_t SpriteByYaw(int32_t yaw, SpriteGroupType rotationType) const; + bool GroupEnabled(SpriteGroupType rotationType) const; + uint32_t GroupImageId(SpriteGroupType spriteGroup) const; + uint32_t SpriteOffset(SpriteGroupType spriteGroup, int32_t imageDirection, uint8_t rankIndex) const; }; diff --git a/src/openrct2/ride/VehiclePaint.cpp b/src/openrct2/ride/VehiclePaint.cpp index 659881c589..91777c259b 100644 --- a/src/openrct2/ride/VehiclePaint.cpp +++ b/src/openrct2/ride/VehiclePaint.cpp @@ -1021,13 +1021,12 @@ static void VehicleSpritePaintRestraints( const rct_ride_entry_vehicle* vehicleEntry) { int32_t boundingBoxNum = YawTo16(imageDirection); - imageDirection = YawTo4(imageDirection); - imageDirection += ((vehicle->restraints_position - 64) / 64) * 4; - imageDirection *= vehicleEntry->base_num_frames; - imageDirection += vehicleEntry->restraint_image_id; - + auto restraintFrame = ((vehicle->restraints_position - 64) / 64) * 4; + auto spriteNum = (vehicleEntry->SpriteByYaw(imageDirection, SpriteGroupType::RestraintAnimation) + restraintFrame) + * vehicleEntry->base_num_frames + + vehicleEntry->GroupImageId(SpriteGroupType::RestraintAnimation); vehicle_sprite_paint( - session, vehicle, imageDirection, VehicleBoundboxes[vehicleEntry->draw_order][boundingBoxNum], z, vehicleEntry); + session, vehicle, spriteNum, VehicleBoundboxes[vehicleEntry->draw_order][boundingBoxNum], z, vehicleEntry); } #pragma endregion @@ -1040,14 +1039,14 @@ static void VehicleSpriteFlatUnbanked( const rct_ride_entry_vehicle* vehicleEntry) { // Restraint animations are only drawn for vehicles that are in a cardinal direction (north, east, south, west) - if (vehicle->restraints_position >= 64 && (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_RESTRAINT_ANIMATION) + if (vehicle->restraints_position >= 64 && vehicleEntry->GroupEnabled(SpriteGroupType::RestraintAnimation) && (imageDirection & 7) == 0) { VehicleSpritePaintRestraints(session, vehicle, imageDirection, z, vehicleEntry); return; } int32_t boundingBoxNum = YawTo16(imageDirection); - auto spriteNum = (vehicleEntry->SpriteByYaw(imageDirection) * vehicleEntry->base_num_frames) + vehicleEntry->base_image_id; + auto spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::SlopeFlat, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } @@ -1056,10 +1055,10 @@ static void vehicle_sprite_0_1( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_BANKED) + if (vehicleEntry->GroupEnabled(SpriteGroupType::FlatBanked22)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = ((YawTo8(imageDirection)) * vehicleEntry->base_num_frames) + vehicleEntry->banked_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::FlatBanked22, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1073,11 +1072,10 @@ static void vehicle_sprite_0_2( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_BANKED) + if (vehicleEntry->GroupEnabled(SpriteGroupType::FlatBanked45)) { int32_t boundingBoxNum = YawTo16(imageDirection) + 108; - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + 16) * vehicleEntry->base_num_frames) - + vehicleEntry->banked_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::FlatBanked45, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1091,10 +1089,10 @@ static void vehicle_sprite_0_3( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_BANKED) + if (vehicleEntry->GroupEnabled(SpriteGroupType::FlatBanked22)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = (((YawTo8(imageDirection)) + 8) * vehicleEntry->base_num_frames) + vehicleEntry->banked_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::FlatBanked22, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1108,12 +1106,10 @@ static void vehicle_sprite_0_4( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_BANKED) + if (vehicleEntry->GroupEnabled(SpriteGroupType::FlatBanked45)) { int32_t boundingBoxNum = (YawTo16(imageDirection) ^ 8) + 108; - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + 16 + vehicleEntry->NumRotationFrames()) - * vehicleEntry->base_num_frames) - + vehicleEntry->banked_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::FlatBanked45, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1131,10 +1127,10 @@ static void vehicle_sprite_0_5( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::FlatBanked67)) { int32_t boundingBoxNum = YawTo4(imageDirection) + 124; - int32_t spriteNum = ((YawTo4(imageDirection)) * vehicleEntry->base_num_frames) + vehicleEntry->inline_twist_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::FlatBanked67, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1152,11 +1148,10 @@ static void vehicle_sprite_0_6( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::FlatBanked90)) { int32_t boundingBoxNum = YawTo4(imageDirection) + 128; - int32_t spriteNum = (((YawTo4(imageDirection)) + 8) * vehicleEntry->base_num_frames) - + vehicleEntry->inline_twist_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::FlatBanked90, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1174,11 +1169,10 @@ static void vehicle_sprite_0_7( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::InlineTwists)) { int32_t boundingBoxNum = YawTo4(imageDirection) + 132; - int32_t spriteNum = (((YawTo4(imageDirection)) + 16) * vehicleEntry->base_num_frames) - + vehicleEntry->inline_twist_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::InlineTwists, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1196,11 +1190,10 @@ static void vehicle_sprite_0_8( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::InlineTwists)) { int32_t boundingBoxNum = YawTo4(imageDirection) + 136; - int32_t spriteNum = (((YawTo4(imageDirection)) + 24) * vehicleEntry->base_num_frames) - + vehicleEntry->inline_twist_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::InlineTwists, imageDirection, 2); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1218,11 +1211,10 @@ static void vehicle_sprite_0_9( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::InlineTwists)) { int32_t boundingBoxNum = YawTo4(imageDirection) + 140; - int32_t spriteNum = (((YawTo4(imageDirection)) + 32) * vehicleEntry->base_num_frames) - + vehicleEntry->inline_twist_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::InlineTwists, imageDirection, 4); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1240,11 +1232,10 @@ static void vehicle_sprite_0_10( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::FlatBanked67)) { int32_t boundingBoxNum = (YawTo4(imageDirection) ^ 2) + 124; - int32_t spriteNum = (((YawTo4(imageDirection)) + 4) * vehicleEntry->base_num_frames) - + vehicleEntry->inline_twist_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::FlatBanked67, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1262,11 +1253,10 @@ static void vehicle_sprite_0_11( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::FlatBanked90)) { int32_t boundingBoxNum = (YawTo4(imageDirection) ^ 2) + 128; - int32_t spriteNum = (((YawTo4(imageDirection)) + 12) * vehicleEntry->base_num_frames) - + vehicleEntry->inline_twist_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::FlatBanked90, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1284,11 +1274,10 @@ static void vehicle_sprite_0_12( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::InlineTwists)) { int32_t boundingBoxNum = (YawTo4(imageDirection) ^ 2) + 132; - int32_t spriteNum = (((YawTo4(imageDirection)) + 20) * vehicleEntry->base_num_frames) - + vehicleEntry->inline_twist_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::InlineTwists, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1306,11 +1295,10 @@ static void vehicle_sprite_0_13( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::InlineTwists)) { int32_t boundingBoxNum = (YawTo4(imageDirection) ^ 2) + 136; - int32_t spriteNum = (((YawTo4(imageDirection)) + 28) * vehicleEntry->base_num_frames) - + vehicleEntry->inline_twist_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::InlineTwists, imageDirection, 3); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1328,11 +1316,10 @@ static void vehicle_sprite_0_14( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::InlineTwists)) { int32_t boundingBoxNum = (YawTo4(imageDirection) ^ 2) + 140; - int32_t spriteNum = (((YawTo4(imageDirection)) + 36) * vehicleEntry->base_num_frames) - + vehicleEntry->inline_twist_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::InlineTwists, imageDirection, 5); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1460,10 +1447,10 @@ static void vehicle_sprite_1_0( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes12)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = ((YawTo4(imageDirection)) * vehicleEntry->base_num_frames) + vehicleEntry->gentle_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes12, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1477,11 +1464,10 @@ static void vehicle_sprite_1_1( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes12Banked22)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = (vehicleEntry->SpriteByYaw(imageDirection) * vehicleEntry->base_num_frames) - + vehicleEntry->flat_to_gentle_bank_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes12Banked22, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1495,11 +1481,10 @@ static void vehicle_sprite_1_2( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_WHILE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes12Banked45)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = ((YawTo4(imageDirection)) * vehicleEntry->base_num_frames) - + vehicleEntry->flat_bank_to_gentle_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes12Banked45, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1513,12 +1498,10 @@ static void vehicle_sprite_1_3( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes12Banked22)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + vehicleEntry->NumRotationFrames()) - * vehicleEntry->base_num_frames) - + vehicleEntry->flat_to_gentle_bank_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes12Banked22, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1532,11 +1515,10 @@ static void vehicle_sprite_1_4( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_WHILE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes12Banked45)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = (((YawTo4(imageDirection)) + 4) * vehicleEntry->base_num_frames) - + vehicleEntry->flat_bank_to_gentle_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes12Banked45, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1597,22 +1579,11 @@ static void vehicle_sprite_2_0( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes25)) { - if (vehicleEntry->flags & VEHICLE_ENTRY_FLAG_SPINNING_ADDITIONAL_FRAMES) - { - int32_t boundingBoxNum = YawTo16(imageDirection) + 16; - int32_t spriteNum = (((YawTo4(imageDirection)) + 8) * vehicleEntry->base_num_frames) - + vehicleEntry->gentle_slope_image_id; - VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); - } - else - { - int32_t boundingBoxNum = (YawTo16(imageDirection)) + 16; - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + 8) * vehicleEntry->base_num_frames) - + vehicleEntry->gentle_slope_image_id; - VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); - } + int32_t boundingBoxNum = (YawTo16(imageDirection)) + 16; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes25, imageDirection, 0); + VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else { @@ -1625,11 +1596,10 @@ static void vehicle_sprite_2_1( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes25Banked22)) { int32_t boundingBoxNum = YawTo16(imageDirection) + 16; - int32_t spriteNum = ((YawTo4(imageDirection)) * vehicleEntry->base_num_frames) - + vehicleEntry->gentle_slope_to_bank_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes25Banked22, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1643,7 +1613,7 @@ static void vehicle_sprite_2_2( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TURNS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes25Banked45)) { int32_t boundingBoxNum = YawTo16(imageDirection); if (vehicleEntry->draw_order < 5) @@ -1651,8 +1621,7 @@ static void vehicle_sprite_2_2( else boundingBoxNum += 16; - int32_t spriteNum = (vehicleEntry->SpriteByYaw(imageDirection) * vehicleEntry->base_num_frames) - + vehicleEntry->gentle_slope_bank_turn_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes25Banked45, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1666,11 +1635,10 @@ static void vehicle_sprite_2_3( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes25Banked22)) { int32_t boundingBoxNum = YawTo16(imageDirection) + 16; - int32_t spriteNum = (((YawTo4(imageDirection)) + 4) * vehicleEntry->base_num_frames) - + vehicleEntry->gentle_slope_to_bank_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes25Banked22, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1684,16 +1652,14 @@ static void vehicle_sprite_2_4( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TURNS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes25Banked45)) { int32_t boundingBoxNum = YawTo16(imageDirection); if (vehicleEntry->draw_order < 5) boundingBoxNum = (boundingBoxNum ^ 8) + 108; else boundingBoxNum += 16; - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + vehicleEntry->NumRotationFrames()) - * vehicleEntry->base_num_frames) - + vehicleEntry->gentle_slope_bank_turn_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes25Banked45, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1784,15 +1750,15 @@ static void VehiclePitchUp42( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (!(vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_STEEP_SLOPES)) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes42)) { - VehiclePitchUp25(session, vehicle, imageDirection, z, vehicleEntry); + int32_t boundingBoxNum = (YawTo8(imageDirection)) + 32; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes42, imageDirection, 0); + VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else { - int32_t boundingBoxNum = (YawTo8(imageDirection)) + 32; - int32_t spriteNum = ((YawTo8(imageDirection)) * vehicleEntry->base_num_frames) + vehicleEntry->steep_slope_image_id; - VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); + VehiclePitchUp25(session, vehicle, imageDirection, z, vehicleEntry); } } @@ -1801,16 +1767,15 @@ static void VehiclePitchUp60( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (!(vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_STEEP_SLOPES)) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes60)) { - VehiclePitchUp25(session, vehicle, imageDirection, z, vehicleEntry); + int32_t boundingBoxNum = (YawTo16(imageDirection)) + 40; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes60, imageDirection, 0); + VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else { - int32_t boundingBoxNum = (YawTo16(imageDirection)) + 40; - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + 16) * vehicleEntry->base_num_frames) - + vehicleEntry->steep_slope_image_id; - VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); + VehiclePitchUp25(session, vehicle, imageDirection, z, vehicleEntry); } } @@ -1825,11 +1790,10 @@ static void vehicle_sprite_5_0( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes12)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = (((YawTo4(imageDirection)) + 4) * vehicleEntry->base_num_frames) - + vehicleEntry->gentle_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes12, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1843,12 +1807,10 @@ static void vehicle_sprite_5_1( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes12Banked22)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + vehicleEntry->NumRotationFrames() * 2) - * vehicleEntry->base_num_frames) - + vehicleEntry->flat_to_gentle_bank_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes12Banked22, imageDirection, 2); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1862,11 +1824,10 @@ static void vehicle_sprite_5_2( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_WHILE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes12Banked45)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = (((YawTo4(imageDirection)) + 8) * vehicleEntry->base_num_frames) - + vehicleEntry->flat_bank_to_gentle_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes12Banked45, imageDirection, 2); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1880,12 +1841,10 @@ static void vehicle_sprite_5_3( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes12Banked22)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + vehicleEntry->NumRotationFrames() * 3) - * vehicleEntry->base_num_frames) - + vehicleEntry->flat_to_gentle_bank_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes12Banked22, imageDirection, 3); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1899,11 +1858,10 @@ static void vehicle_sprite_5_4( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_WHILE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes12Banked45)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = (((YawTo4(imageDirection)) + 12) * vehicleEntry->base_num_frames) - + vehicleEntry->flat_bank_to_gentle_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes12Banked45, imageDirection, 3); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -1995,23 +1953,11 @@ static void vehicle_sprite_6_0( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes25)) { - if (vehicleEntry->flags & VEHICLE_ENTRY_FLAG_SPINNING_ADDITIONAL_FRAMES) - { - int32_t boundingBoxNum = ((YawTo16(imageDirection)) ^ 8) + 16; - int32_t spriteNum = (((YawTo4(imageDirection)) + 12) * vehicleEntry->base_num_frames) - + vehicleEntry->gentle_slope_image_id; - VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); - } - else - { - int32_t boundingBoxNum = ((YawTo16(imageDirection)) ^ 8) + 16; - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + 8 + vehicleEntry->NumRotationFrames()) - * vehicleEntry->base_num_frames) - + vehicleEntry->gentle_slope_image_id; - VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); - } + int32_t boundingBoxNum = ((YawTo16(imageDirection)) ^ 8) + 16; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes25, imageDirection, 1); + VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else { @@ -2024,11 +1970,10 @@ static void vehicle_sprite_6_1( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes25Banked22)) { int32_t boundingBoxNum = ((YawTo16(imageDirection)) ^ 8) + 16; - int32_t spriteNum = (((YawTo4(imageDirection)) + 8) * vehicleEntry->base_num_frames) - + vehicleEntry->gentle_slope_to_bank_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes25Banked22, imageDirection, 2); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2042,7 +1987,7 @@ static void vehicle_sprite_6_2( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TURNS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes25Banked45)) { int32_t boundingBoxNum = YawTo16(imageDirection); if (vehicleEntry->draw_order < 5) @@ -2050,9 +1995,7 @@ static void vehicle_sprite_6_2( else boundingBoxNum = (boundingBoxNum ^ 8) + 16; - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + vehicleEntry->NumRotationFrames() * 2) - * vehicleEntry->base_num_frames) - + vehicleEntry->gentle_slope_bank_turn_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes25Banked45, imageDirection, 2); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2066,11 +2009,10 @@ static void vehicle_sprite_6_3( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes25Banked22)) { int32_t boundingBoxNum = ((YawTo16(imageDirection)) ^ 8) + 16; - int32_t spriteNum = (((YawTo4(imageDirection)) + 12) * vehicleEntry->base_num_frames) - + vehicleEntry->gentle_slope_to_bank_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes25Banked22, imageDirection, 3); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2084,16 +2026,15 @@ static void vehicle_sprite_6_4( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TURNS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes25Banked45)) { int32_t boundingBoxNum = YawTo16(imageDirection); if (vehicleEntry->draw_order < 5) boundingBoxNum = (boundingBoxNum ^ 8) + 108; else boundingBoxNum = (boundingBoxNum ^ 8) + 16; - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + vehicleEntry->NumRotationFrames() * 3) - * vehicleEntry->base_num_frames) - + vehicleEntry->gentle_slope_bank_turn_image_id; + + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes25Banked45, imageDirection, 3); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2184,11 +2125,10 @@ static void VehiclePitchDown42( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_STEEP_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes42)) { int32_t boundingBoxNum = ((YawTo8(imageDirection)) ^ 4) + 32; - int32_t spriteNum = (((YawTo8(imageDirection)) + 8) * vehicleEntry->base_num_frames) - + vehicleEntry->steep_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes42, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2202,12 +2142,10 @@ static void VehiclePitchDown60( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_STEEP_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes60)) { int32_t boundingBoxNum = ((YawTo16(imageDirection)) ^ 8) + 40; - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + 16 + vehicleEntry->NumRotationFrames()) - * vehicleEntry->base_num_frames) - + vehicleEntry->steep_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes60, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2225,10 +2163,10 @@ static void VehiclePitchUp75( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes75)) { int32_t boundingBoxNum = (YawTo4(imageDirection)) + 56; - int32_t spriteNum = ((YawTo4(imageDirection)) * vehicleEntry->base_num_frames) + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes75, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2242,11 +2180,10 @@ static void VehiclePitchUp90( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes90)) { int32_t boundingBoxNum = (YawTo16(imageDirection)) + 60; - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + 8) * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes90, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2264,12 +2201,10 @@ static void VehiclePitchUp105( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::SlopesLoop)) { int32_t boundingBoxNum = (YawTo4(imageDirection)) + 76; - int32_t spriteNum = ((YawTo4(imageDirection) + 8 + vehicleEntry->NumRotationFrames() * 2) - * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::SlopesLoop, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2283,12 +2218,10 @@ static void VehiclePitchUp120( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::SlopesLoop)) { int32_t boundingBoxNum = (YawTo4(imageDirection)) + 80; - int32_t spriteNum = (((YawTo4(imageDirection)) + 16 + vehicleEntry->NumRotationFrames() * 2) - * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::SlopesLoop, imageDirection, 2); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2302,12 +2235,10 @@ static void VehiclePitchUp135( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::SlopesLoop)) { int32_t boundingBoxNum = (YawTo4(imageDirection)) + 84; - int32_t spriteNum = (((YawTo4(imageDirection)) + 24 + vehicleEntry->NumRotationFrames() * 2) - * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::SlopesLoop, imageDirection, 4); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2321,12 +2252,10 @@ static void VehiclePitchUp150( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::SlopesLoop)) { int32_t boundingBoxNum = (YawTo4(imageDirection)) + 88; - int32_t spriteNum = (((YawTo4(imageDirection)) + 32 + vehicleEntry->NumRotationFrames() * 2) - * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::SlopesLoop, imageDirection, 6); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2340,12 +2269,10 @@ static void VehiclePitchUp165( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::SlopesLoop)) { int32_t boundingBoxNum = (YawTo4(imageDirection)) + 92; - int32_t spriteNum = (((YawTo4(imageDirection)) + 40 + vehicleEntry->NumRotationFrames() * 2) - * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::SlopesLoop, imageDirection, 8); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2363,12 +2290,10 @@ static void VehiclePitchInverted( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::SlopeInverted)) { int32_t boundingBoxNum = (YawTo4(imageDirection)) + 96; - int32_t spriteNum = (((YawTo4(imageDirection)) + 48 + vehicleEntry->NumRotationFrames() * 2) - * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::SlopeInverted, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2394,11 +2319,10 @@ static void VehiclePitchDown75( vehicleEntry--; } } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes75)) { int32_t boundingBoxNum = ((YawTo4(imageDirection)) ^ 2) + 56; - int32_t spriteNum = (((YawTo4(imageDirection)) + 4) * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes75, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2420,12 +2344,10 @@ static void VehiclePitchDown90( vehicleEntry--; } } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes90)) { int32_t boundingBoxNum = ((YawTo16(imageDirection)) ^ 8) + 60; - int32_t spriteNum = ((vehicleEntry->SpriteByYaw(imageDirection) + 8 + vehicleEntry->NumRotationFrames()) - * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes90, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2447,12 +2369,10 @@ static void VehiclePitchDown105( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes90)) { int32_t boundingBoxNum = ((YawTo4(imageDirection)) ^ 2) + 76; - int32_t spriteNum = (((YawTo4(imageDirection)) + 12 + vehicleEntry->NumRotationFrames() * 2) - * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::SlopesLoop, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2470,12 +2390,10 @@ static void VehiclePitchDown120( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes90)) { int32_t boundingBoxNum = ((YawTo4(imageDirection)) ^ 2) + 80; - int32_t spriteNum = (((YawTo4(imageDirection)) + 20 + vehicleEntry->NumRotationFrames() * 2) - * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::SlopesLoop, imageDirection, 3); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2493,12 +2411,10 @@ static void VehiclePitchDown135( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::SlopesLoop)) { int32_t boundingBoxNum = ((YawTo4(imageDirection)) ^ 2) + 84; - int32_t spriteNum = (((YawTo4(imageDirection)) + 28 + vehicleEntry->NumRotationFrames() * 2) - * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::SlopesLoop, imageDirection, 5); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2516,12 +2432,10 @@ static void VehiclePitchDown150( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::SlopesLoop)) { int32_t boundingBoxNum = ((YawTo4(imageDirection)) ^ 2) + 88; - int32_t spriteNum = (((YawTo4(imageDirection)) + 36 + vehicleEntry->NumRotationFrames() * 2) - * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::SlopesLoop, imageDirection, 7); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2539,12 +2453,10 @@ static void VehiclePitchDown165( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::SlopesLoop)) { int32_t boundingBoxNum = ((YawTo4(imageDirection)) ^ 2) + 92; - int32_t spriteNum = (((YawTo4(imageDirection)) + 44 + vehicleEntry->NumRotationFrames() * 2) - * vehicleEntry->base_num_frames) - + vehicleEntry->vertical_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::SlopesLoop, imageDirection, 9); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2566,12 +2478,12 @@ static void VehiclePitchCorkscrew( { vehicleEntry--; } - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_CORKSCREWS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Corkscrews)) { - int32_t eax = ((vehicle->Pitch - 24) * 4); - int32_t boundingBoxNum = (YawTo4(imageDirection)) + eax + 144; - int32_t spriteNum = (((YawTo4(imageDirection)) + eax) * vehicleEntry->base_num_frames) - + vehicleEntry->corkscrew_image_id; + // corkscrew slopes begin at pitch 24 and end at pitch 43 + int32_t corkscrewFrame = vehicle->Pitch - 24; + int32_t boundingBoxNum = (YawTo4(imageDirection)) + corkscrewFrame * 4 + 144; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Corkscrews, imageDirection, corkscrewFrame); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2584,17 +2496,17 @@ static void VehiclePitchCorkscrew( #pragma region DiagonalSlopesUp -#pragma region DiagonalSlopeUp12 +#pragma region SlopeUp8 // 6D4D67 static void vehicle_sprite_50_0( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes8)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = ((YawTo4(imageDirection)) * vehicleEntry->base_num_frames) + vehicleEntry->diagonal_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes8, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2608,11 +2520,10 @@ static void vehicle_sprite_50_1( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_GENTLE_SLOPE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes8Banked22)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = ((YawTo4(imageDirection)) * vehicleEntry->base_num_frames) - + vehicleEntry->diagonal_to_gentle_slope_bank_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes8Banked22, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2626,11 +2537,10 @@ static void vehicle_sprite_50_3( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_GENTLE_SLOPE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes8Banked22)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = (((YawTo4(imageDirection)) + 4) * vehicleEntry->base_num_frames) - + vehicleEntry->diagonal_to_gentle_slope_bank_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes8Banked22, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2640,7 +2550,7 @@ static void vehicle_sprite_50_3( } // 6D4D60 -static void VehiclePitchDiagUp12( +static void VehiclePitchUp8( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { @@ -2712,18 +2622,17 @@ static void VehiclePitchDiagUp12( #pragma endregion -#pragma region DiagonalSlopeUp25 +#pragma region SlopeUp16 // 6D4E3A -static void VehiclePitchDiagUp25( +static void VehiclePitchUp16( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes16)) { - int32_t boundingBoxNum = YawTo4(imageDirection) + 100; - int32_t spriteNum = ((YawTo4(imageDirection) + 8) * vehicleEntry->base_num_frames) - + vehicleEntry->diagonal_slope_image_id; + int32_t boundingBoxNum = YawTo16(imageDirection); + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes16, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2734,18 +2643,17 @@ static void VehiclePitchDiagUp25( #pragma endregion -#pragma region DiagonalSlopeUp60 +#pragma region SlopeUp50 // 6D4E8F -static void VehiclePitchDiagUp60( +static void VehiclePitchUp50( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes50)) { - int32_t boundingBoxNum = (YawTo4(imageDirection)) + 104; - int32_t spriteNum = (((YawTo4(imageDirection)) + 16) * vehicleEntry->base_num_frames) - + vehicleEntry->diagonal_slope_image_id; + int32_t boundingBoxNum = YawTo16(imageDirection); + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes50, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2760,18 +2668,17 @@ static void VehiclePitchDiagUp60( #pragma region DiagonalSlopesDown -#pragma region DiagonalSlopeDown12 +#pragma region SlopeDown8 // 6D4D90 static void vehicle_sprite_53_0( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes8)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = (((YawTo4(imageDirection)) + 4) * vehicleEntry->base_num_frames) - + vehicleEntry->diagonal_slope_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes8, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2785,16 +2692,15 @@ static void vehicle_sprite_53_1( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_GENTLE_SLOPE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes8Banked22)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = (((YawTo4(imageDirection)) + 8) * vehicleEntry->base_num_frames) - + vehicleEntry->diagonal_to_gentle_slope_bank_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes8Banked22, imageDirection, 2); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else { - vehicle_sprite_53_0(session, vehicle, imageDirection, z, vehicleEntry); + VehiclePitchFlat(session, vehicle, imageDirection, z, vehicleEntry); } } @@ -2803,21 +2709,20 @@ static void vehicle_sprite_53_3( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_GENTLE_SLOPE_BANKED_TRANSITIONS) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes8Banked22)) { int32_t boundingBoxNum = YawTo16(imageDirection); - int32_t spriteNum = (((YawTo4(imageDirection)) + 12) * vehicleEntry->base_num_frames) - + vehicleEntry->diagonal_to_gentle_slope_bank_image_id; + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes8Banked22, imageDirection, 3); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else { - vehicle_sprite_53_0(session, vehicle, imageDirection, z, vehicleEntry); + VehiclePitchFlat(session, vehicle, imageDirection, z, vehicleEntry); } } // 6D4D89 -static void VehiclePitchDiagDown12( +static void VehiclePitchDown8( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { @@ -2889,18 +2794,17 @@ static void VehiclePitchDiagDown12( #pragma endregion -#pragma region DiagonalSlopeDown25 +#pragma region SlopeDown16 // 6D4E63 -static void VehiclePitchDiagDown25( +static void VehiclePitchDown16( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes16)) { - int32_t boundingBoxNum = ((YawTo4(imageDirection)) ^ 2) + 100; - int32_t spriteNum = (((YawTo4(imageDirection)) + 12) * vehicleEntry->base_num_frames) - + vehicleEntry->diagonal_slope_image_id; + int32_t boundingBoxNum = YawTo16(imageDirection); + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes16, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2911,18 +2815,17 @@ static void VehiclePitchDiagDown25( #pragma endregion -#pragma region DiagonalSlopeDown60 +#pragma region SlopeDown50 // 6D4EB8 -static void VehiclePitchDiagDown60( +static void VehiclePitchDown50( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES) + if (vehicleEntry->GroupEnabled(SpriteGroupType::Slopes50)) { - int32_t boundingBoxNum = ((YawTo4(imageDirection)) ^ 2) + 104; - int32_t spriteNum = (((YawTo4(imageDirection)) + 20) * vehicleEntry->base_num_frames) - + vehicleEntry->diagonal_slope_image_id; + int32_t boundingBoxNum = YawTo16(imageDirection); + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::Slopes50, imageDirection, 1); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else @@ -2973,16 +2876,15 @@ static void VehiclePitchSpiralLift( paint_session& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const rct_ride_entry_vehicle* vehicleEntry) { - if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_CURVED_LIFT_HILL) + if (vehicleEntry->GroupEnabled(SpriteGroupType::CurvedLiftHill)) { - int32_t boundingBoxNum = (YawTo16(imageDirection)) + 16; - int32_t spriteNum = (vehicleEntry->SpriteByYaw(imageDirection) * vehicleEntry->base_num_frames) - + vehicleEntry->curved_lift_hill_image_id; + int32_t boundingBoxNum = YawTo16(imageDirection); + int32_t spriteNum = vehicleEntry->SpriteOffset(SpriteGroupType::CurvedLiftHill, imageDirection, 0); VehicleSpritePaintWithSwinging(session, vehicle, spriteNum, boundingBoxNum, z, vehicleEntry); } else { - VehiclePitchUp25(session, vehicle, imageDirection, z, vehicleEntry); + VehiclePitchFlat(session, vehicle, imageDirection, z, vehicleEntry); } } @@ -3045,12 +2947,12 @@ static constexpr const vehicle_sprite_func PaintFunctionsByPitch[] = { VehiclePitchFlat, // Half Helix Down Small VehiclePitchFlat, // Quarter Helix Up VehiclePitchFlat, // Quarter Helix Down - VehiclePitchDiagUp12, - VehiclePitchDiagUp25, - VehiclePitchDiagUp60, - VehiclePitchDiagDown12, - VehiclePitchDiagDown25, - VehiclePitchDiagDown60, + VehiclePitchUp8, + VehiclePitchUp16, + VehiclePitchUp50, + VehiclePitchDown8, + VehiclePitchDown16, + VehiclePitchDown50, VehiclePitchInvertingDown25, VehiclePitchInvertingDown42, VehiclePitchInvertingDown60, @@ -3306,3 +3208,29 @@ void Vehicle::Paint(paint_session& session, int32_t imageDirection) const break; } } + +uint32_t rct_ride_entry_vehicle::NumRotationSprites(SpriteGroupType spriteGroup) const +{ + return NumSpritesPrecision(SpriteGroups[static_cast(spriteGroup)].spritePrecision); +} + +int32_t rct_ride_entry_vehicle::SpriteByYaw(int32_t yaw, SpriteGroupType spriteGroup) const +{ + return YawToPrecision(yaw, SpriteGroups[static_cast(spriteGroup)].spritePrecision); +} + +bool rct_ride_entry_vehicle::GroupEnabled(SpriteGroupType spriteGroup) const +{ + return SpriteGroups[static_cast(spriteGroup)].Enabled(); +} + +uint32_t rct_ride_entry_vehicle::GroupImageId(SpriteGroupType spriteGroup) const +{ + return SpriteGroups[static_cast(spriteGroup)].imageId; +} + +uint32_t rct_ride_entry_vehicle::SpriteOffset(SpriteGroupType spriteGroup, int32_t imageDirection, uint8_t rankIndex) const +{ + return ((SpriteByYaw(imageDirection, spriteGroup) + NumRotationSprites(spriteGroup) * rankIndex) * base_num_frames) + + GroupImageId(spriteGroup); +} diff --git a/src/openrct2/ride/water/SubmarineRide.cpp b/src/openrct2/ride/water/SubmarineRide.cpp index 675160de8b..d0d9644d53 100644 --- a/src/openrct2/ride/water/SubmarineRide.cpp +++ b/src/openrct2/ride/water/SubmarineRide.cpp @@ -22,18 +22,18 @@ static uint32_t SubmarineVehicleGetBaseImageId( uint32_t result = imageDirection; if (vehicle->restraints_position >= 64) { - if ((vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_RESTRAINT_ANIMATION) && !(imageDirection & 3)) + if ((vehicleEntry->GroupEnabled(SpriteGroupType::RestraintAnimation)) && !(imageDirection & 3)) { - result = OpenRCT2::Entity::Yaw::YawTo4(result); - result += ((vehicle->restraints_position - 64) / 64) * 4; - result *= vehicleEntry->base_num_frames; - result += vehicleEntry->restraint_image_id; + auto restraintFrame = ((vehicle->restraints_position - 64) / 64) * 4; + result = (vehicleEntry->SpriteByYaw(imageDirection, SpriteGroupType::RestraintAnimation) + restraintFrame) + * vehicleEntry->base_num_frames + + vehicleEntry->GroupImageId(SpriteGroupType::RestraintAnimation); } } else { - result = (vehicleEntry->SpriteByYaw(result) * vehicleEntry->base_num_frames) + vehicleEntry->base_image_id - + vehicle->SwingSprite; + result = (vehicleEntry->SpriteByYaw(imageDirection, SpriteGroupType::SlopeFlat) * vehicleEntry->base_num_frames) + + vehicleEntry->GroupImageId(SpriteGroupType::SlopeFlat) + vehicle->SwingSprite; } return result; } diff --git a/src/openrct2/scripting/Duktape.hpp b/src/openrct2/scripting/Duktape.hpp index f60e12b971..bb08e5510f 100644 --- a/src/openrct2/scripting/Duktape.hpp +++ b/src/openrct2/scripting/Duktape.hpp @@ -419,6 +419,14 @@ namespace OpenRCT2::Scripting return dukGForces.Take(); } + template<> inline DukValue ToDuk(duk_context* ctx, const VehicleSpriteGroup& value) + { + DukObject dukSpriteGroup(ctx); + dukSpriteGroup.Set("imageId", value.imageId); + dukSpriteGroup.Set("spriteNumImages", OpenRCT2::Entity::Yaw::NumSpritesPrecision(value.spritePrecision)); + return dukSpriteGroup.Take(); + } + template<> inline CoordsXYZD FromDuk(const DukValue& value) { CoordsXYZD result; diff --git a/src/openrct2/scripting/ScriptEngine.h b/src/openrct2/scripting/ScriptEngine.h index 2dbc27971d..d45c685404 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 = 54; + static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 55; // Versions marking breaking changes. static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33; diff --git a/src/openrct2/scripting/bindings/object/ScObject.hpp b/src/openrct2/scripting/bindings/object/ScObject.hpp index 85fab02c1d..eb332a019f 100644 --- a/src/openrct2/scripting/bindings/object/ScObject.hpp +++ b/src/openrct2/scripting/bindings/object/ScObject.hpp @@ -151,8 +151,6 @@ namespace OpenRCT2::Scripting static void Register(duk_context* ctx) { dukglue_register_property(ctx, &ScRideObjectVehicle::rotationFrameMask_get, nullptr, "rotationFrameMask"); - dukglue_register_property(ctx, &ScRideObjectVehicle::numVerticalFrames_get, nullptr, "numVerticalFrames"); - dukglue_register_property(ctx, &ScRideObjectVehicle::numHorizontalFrames_get, nullptr, "numHorizontalFrames"); dukglue_register_property(ctx, &ScRideObjectVehicle::spacing_get, nullptr, "spacing"); dukglue_register_property(ctx, &ScRideObjectVehicle::carMass_get, nullptr, "carMass"); dukglue_register_property(ctx, &ScRideObjectVehicle::tabHeight_get, nullptr, "tabHeight"); @@ -165,25 +163,7 @@ namespace OpenRCT2::Scripting dukglue_register_property(ctx, &ScRideObjectVehicle::flags_get, nullptr, "flags"); dukglue_register_property(ctx, &ScRideObjectVehicle::baseNumFrames_get, nullptr, "baseNumFrames"); dukglue_register_property(ctx, &ScRideObjectVehicle::baseImageId_get, nullptr, "baseImageId"); - dukglue_register_property(ctx, &ScRideObjectVehicle::restraintImageId_get, nullptr, "restraintImageId"); - dukglue_register_property(ctx, &ScRideObjectVehicle::gentleSlopeImageId_get, nullptr, "gentleSlopeImageId"); - dukglue_register_property(ctx, &ScRideObjectVehicle::steepSlopeImageId_get, nullptr, "steepSlopeImageId"); - dukglue_register_property(ctx, &ScRideObjectVehicle::verticalSlopeImageId_get, nullptr, "verticalSlopeImageId"); - dukglue_register_property(ctx, &ScRideObjectVehicle::diagonalSlopeImageId_get, nullptr, "diagonalSlopeImageId"); - dukglue_register_property(ctx, &ScRideObjectVehicle::bankedImageId_get, nullptr, "bankedImageId"); - dukglue_register_property(ctx, &ScRideObjectVehicle::inlineTwistImageId_get, nullptr, "inlineTwistImageId"); - dukglue_register_property( - ctx, &ScRideObjectVehicle::flatToGentleBankImageId_get, nullptr, "flatToGentleBankImageId"); - dukglue_register_property( - ctx, &ScRideObjectVehicle::diagonalToGentleSlopeBankImageId_get, nullptr, "diagonalToGentleSlopeBankImageId"); - dukglue_register_property( - ctx, &ScRideObjectVehicle::gentleSlopeToBankImageId_get, nullptr, "gentleSlopeToBankImageId"); - dukglue_register_property( - ctx, &ScRideObjectVehicle::gentleSlopeBankTurnImageId_get, nullptr, "gentleSlopeBankTurnImageId"); - dukglue_register_property( - ctx, &ScRideObjectVehicle::flatBankToGentleSlopeImageId_get, nullptr, "flatBankToGentleSlopeImageId"); - dukglue_register_property(ctx, &ScRideObjectVehicle::curvedLiftHillImageId_get, nullptr, "curvedLiftHillImageId"); - dukglue_register_property(ctx, &ScRideObjectVehicle::corkscrewImageId_get, nullptr, "corkscrewImageId"); + dukglue_register_property(ctx, &ScRideObjectVehicle::spriteGroups_get, nullptr, "spriteGroups"); dukglue_register_property(ctx, &ScRideObjectVehicle::noVehicleImages_get, nullptr, "noVehicleImages"); dukglue_register_property(ctx, &ScRideObjectVehicle::noSeatingRows_get, nullptr, "noSeatingRows"); dukglue_register_property(ctx, &ScRideObjectVehicle::spinningInertia_get, nullptr, "spinningInertia"); @@ -213,16 +193,6 @@ namespace OpenRCT2::Scripting return 0; } - uint8_t numVerticalFrames_get() const - { - return 0; - } - - uint8_t numHorizontalFrames_get() const - { - return 0; - } - uint32_t spacing_get() const { auto entry = GetEntry(); @@ -265,11 +235,6 @@ namespace OpenRCT2::Scripting uint16_t spriteFlags_get() const { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->sprite_flags; - } return 0; } @@ -343,144 +308,22 @@ namespace OpenRCT2::Scripting return 0; } - uint32_t restraintImageId_get() const + DukValue spriteGroups_get() const { + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto* ctx = scriptEngine.GetContext(); + DukObject groups(ctx); auto entry = GetEntry(); if (entry != nullptr) { - return entry->restraint_image_id; + for (uint8_t g = 0; g < EnumValue(SpriteGroupType::Count); g++) + { + auto group = entry->SpriteGroups[g]; + if (group.Enabled()) + groups.Set(SpriteGroupNames[g].c_str(), ToDuk(ctx, group)); + } } - return 0; - } - - uint32_t gentleSlopeImageId_get() const - { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->gentle_slope_image_id; - } - return 0; - } - - uint32_t steepSlopeImageId_get() const - { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->steep_slope_image_id; - } - return 0; - } - - uint32_t verticalSlopeImageId_get() const - { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->vertical_slope_image_id; - } - return 0; - } - - uint32_t diagonalSlopeImageId_get() const - { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->diagonal_slope_image_id; - } - return 0; - } - - uint32_t bankedImageId_get() const - { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->banked_image_id; - } - return 0; - } - - uint32_t inlineTwistImageId_get() const - { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->inline_twist_image_id; - } - return 0; - } - - uint32_t flatToGentleBankImageId_get() const - { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->flat_to_gentle_bank_image_id; - } - return 0; - } - - uint32_t diagonalToGentleSlopeBankImageId_get() const - { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->diagonal_to_gentle_slope_bank_image_id; - } - return 0; - } - - uint32_t gentleSlopeToBankImageId_get() const - { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->gentle_slope_to_bank_image_id; - } - return 0; - } - - uint32_t gentleSlopeBankTurnImageId_get() const - { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->gentle_slope_bank_turn_image_id; - } - return 0; - } - - uint32_t flatBankToGentleSlopeImageId_get() const - { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->flat_bank_to_gentle_slope_image_id; - } - return 0; - } - - uint32_t curvedLiftHillImageId_get() const - { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->curved_lift_hill_image_id; - } - return 0; - } - - uint32_t corkscrewImageId_get() const - { - auto entry = GetEntry(); - if (entry != nullptr) - { - return entry->corkscrew_image_id; - } - return 0; + return groups.Take(); } uint32_t noVehicleImages_get() const