diff --git a/src/ride/ride.c b/src/ride/ride.c index e976e89d42..39c4da9132 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -515,13 +515,85 @@ void ride_update_station(rct_ride *ride, int stationIndex) } } -int sub_6B7294(rct_ride *ride) +int bitscanforward(int source) { - int eax, ebx, ecx, edx, esi, edi, ebp; + int i; - esi = (int)ride; - RCT2_CALLFUNC_X(0x006B7294, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - return ebx; + for (i = 0; i < 32; i++) + if (source & (1 << i)) + return i; + + return -1; +} + +static uint8 _breakdownProblemProbabilities[] = { + 25, // BREAKDOWN_SAFETY_CUT_OUT + 12, // BREAKDOWN_RESTRAINTS_STUCK_CLOSED + 10, // BREAKDOWN_RESTRAINTS_STUCK_OPEN + 13, // BREAKDOWN_DOORS_STUCK_CLOSED + 10, // BREAKDOWN_DOORS_STUCK_OPEN + 6, // BREAKDOWN_VEHICLE_MALFUNCTION + 0, // BREAKDOWN_BRAKES_FAILURE + 3 // BREAKDOWN_CONTROL_FAILURE +}; + +/** + * + * rct2: 0x006B7294 + */ +int ride_get_new_breakdown_problem(rct_ride *ride) +{ + int availableBreakdownProblems, monthsOld, totalProbability, randomProbability, problemBits, breakdownProblem; + rct_ride_type *entry; + + // Brake failure is more likely when its raining + _breakdownProblemProbabilities[BREAKDOWN_BRAKES_FAILURE] = + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RAIN_LEVEL, uint8) == 0 ? 3 : 20; + + entry = ride_get_entry(ride); + if (entry->var_008 & 0x4000) + return -1; + + availableBreakdownProblems = RideAvailableBreakdowns[ride->type]; + + // Calculate the total probability range for all possible breakdown problems + totalProbability = 0; + problemBits = availableBreakdownProblems; + while (problemBits != 0) { + breakdownProblem = bitscanforward(problemBits); + problemBits &= ~(1 << breakdownProblem); + totalProbability += _breakdownProblemProbabilities[breakdownProblem]; + } + if (totalProbability == 0) + return -1; + + // Choose a random number within this range + randomProbability = scenario_rand() % totalProbability; + + // Find which problem range the random number lies + problemBits = availableBreakdownProblems; + do { + breakdownProblem = bitscanforward(problemBits); + problemBits &= ~(1 << breakdownProblem); + randomProbability -= _breakdownProblemProbabilities[breakdownProblem]; + } while (randomProbability >= 0); + + if (breakdownProblem != BREAKDOWN_BRAKES_FAILURE) + return breakdownProblem; + + // Breaks failure can not happen if block breaks are used (so long as there is more than one vehicle) + // However if this is the case, break failure should be taken out the equation, otherwise block brake + // rides have a lower probability to break down due to a random implementation reason. + if (ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED || ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED) + if (ride->num_vehicles != 1) + return -1; + + // Again the probability is lower, this time if young or two other unknown reasons... + monthsOld = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint8) - ride->build_date; + if (monthsOld < 16 || ride->var_196 > 12800 || ride->lifecycle_flags & RIDE_LIFECYCLE_19) + return -1; + + return BREAKDOWN_BRAKES_FAILURE; } /** @@ -533,13 +605,81 @@ void sub_6B75C8(int rideIndex) RCT2_CALLPROC_X(0x006B75C8, 0, 0, 0, rideIndex, 0, 0, 0); } +/** + * + * rct2: 0x006B7348 + */ +void ride_prepare_breakdown(int rideIndex, int breakdownReason) +{ + int i; + rct_ride *ride; + rct_vehicle *vehicle; + + ride = GET_RIDE(rideIndex); + if (ride->lifecycle_flags & (RIDE_LIFECYCLE_6 | RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_CRASHED)) + return; + + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_DUE_INSPECTION; + ride->lifecycle_flags |= RIDE_LIFECYCLE_6; + + ride->breakdown_reason_pending = breakdownReason; + ride->mechanic_status = RIDE_MECHANIC_STATUS_UNDEFINED; + ride->var_1AC = 0; + ride->var_1AD = 0; + + switch (breakdownReason) { + case BREAKDOWN_SAFETY_CUT_OUT: + case BREAKDOWN_CONTROL_FAILURE: + // Inspect first station with an exit + for (i = 0; i < 4; i++) { + if (ride->exits[i] != 0xFFFF) { + ride->inspection_station = i; + break; + } + } + break; + case BREAKDOWN_RESTRAINTS_STUCK_CLOSED: + case BREAKDOWN_RESTRAINTS_STUCK_OPEN: + case BREAKDOWN_DOORS_STUCK_CLOSED: + case BREAKDOWN_DOORS_STUCK_OPEN: + // Choose a random train and car + ride->broken_vehicle = scenario_rand() % ride->num_vehicles; + ride->broken_car = scenario_rand() % ride->num_cars_per_train; + + // Set flag on broken car + vehicle = &(g_sprite_list[ride->vehicles[ride->broken_vehicle]].vehicle); + for (i = ride->broken_car; i >= 0; i--) + vehicle = &(g_sprite_list[ride->vehicles[vehicle->next_vehicle_on_train]].vehicle); + vehicle->var_48 |= 0x100; + break; + case BREAKDOWN_VEHICLE_MALFUNCTION: + // Choose a random train + ride->broken_vehicle = scenario_rand() % ride->num_vehicles; + ride->broken_car = 0; + + // Set flag on broken train, first car + vehicle = &(g_sprite_list[ride->vehicles[ride->broken_vehicle]].vehicle); + vehicle->var_48 |= 0x200; + break; + case BREAKDOWN_BRAKES_FAILURE: + // Original code generates a random number but does not use it + // Unsure if this was supposed to choose a random station (or random station with an exit) + for (i = 0; i < 4; i++) { + ride->inspection_station = i; + if (ride->exits[i] != 0xFFFF) + break; + } + break; + } +} + /** * * rct2: 0x006AC622 */ void ride_breakdown_update(int rideIndex) { - int agePenalty, years, ax; + int agePenalty, years, ax, breakdownReason; rct_ride *ride = GET_RIDE(rideIndex); if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 255) @@ -606,10 +746,12 @@ void ride_breakdown_update(int rideIndex) ride->var_196 = max(0, ride->var_196 - ax); ride->var_14D |= 32; - // Break down based on probability? - if (ride->var_196 == 0 || (scenario_rand() & 0x2FFFFF) <= 25856 - ride->var_196) - if (sub_6B7294(ride) != -1) - sub_6B75C8(rideIndex); + // Random probability of a breakdown + if (ride->var_196 == 0 || (scenario_rand() & 0x2FFFFF) <= 25856 - ride->var_196) { + breakdownReason = ride_get_new_breakdown_problem(ride); + if (breakdownReason != -1) + ride_prepare_breakdown(rideIndex, breakdownReason); + } } /** @@ -665,7 +807,7 @@ void ride_chairlift_update(rct_ride *ride) return; if (!(ride->lifecycle_flags & (RIDE_LIFECYCLE_6 | RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_CRASHED))) return; - if (ride->var_18C == 0) + if (ride->breakdown_reason_pending == 0) return; ax = ride->var_0D0 * 2048; @@ -694,6 +836,7 @@ void ride_spiral_slide_update(rct_ride *ride) { int i, x, y, z; rct_map_element *mapElement; + rct_peep *peep; if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 3) return; @@ -704,9 +847,8 @@ void ride_spiral_slide_update(rct_ride *ride) if (ride->var_176 >= 48) { ride->var_15D--; - // TODO find out what type of sprite is stored here - rct_sprite *sprite = &g_sprite_list[ride->maze_tiles]; - RCT2_GLOBAL((int)sprite + 0x32, uint16)++; + peep = &(g_sprite_list[ride->maze_tiles].peep); + peep->var_32++; } // Invalidate something related to station start @@ -755,14 +897,19 @@ void ride_music_update(int rideIndex) // Oscillate parameters for a power cut effect when breaking down if (ride->lifecycle_flags & (RIDE_LIFECYCLE_6 | RIDE_LIFECYCLE_BROKEN_DOWN)) { - if (ride->var_18C == 7) { + if (ride->breakdown_reason_pending == BREAKDOWN_CONTROL_FAILURE) { if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 7)) if (ride->var_1AC != 255) ride->var_1AC++; } else { - if ((ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) || ride->var_18C == 6 || ride->var_18C == 7) + if ( + (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) || + ride->breakdown_reason_pending == BREAKDOWN_BRAKES_FAILURE || + ride->breakdown_reason_pending == BREAKDOWN_CONTROL_FAILURE + ) { if (ride->var_1AC != 255) ride->var_1AC++; + } if (ride->var_1AC == 255) { ride->music_tune_id = 255; @@ -789,7 +936,7 @@ void ride_music_update(int rideIndex) // Alter sample rate for a power cut effect if (ride->lifecycle_flags & (RIDE_LIFECYCLE_6 | RIDE_LIFECYCLE_BROKEN_DOWN)) { sampleRate = ride->var_1AC * 70; - if (ride->var_18C != 7) + if (ride->breakdown_reason_pending != BREAKDOWN_CONTROL_FAILURE) sampleRate *= -1; sampleRate += 22050; } diff --git a/src/ride/ride.h b/src/ride/ride.h index 9d25f00d1d..e4c04e5723 100644 --- a/src/ride/ride.h +++ b/src/ride/ride.h @@ -180,7 +180,10 @@ typedef struct { uint8 num_riders; // 0x15B uint8 music_tune_id; // 0x15C uint8 var_15D; - uint16 maze_tiles; // 0x15E + union { + uint16 slide_peep; // 0x15E + uint16 maze_tiles; // 0x15E + }; uint8 pad_160[0x16]; uint8 var_176; uint8 pad_177[0x9]; @@ -189,11 +192,12 @@ typedef struct { uint16 race_winner; // 0x184 uint8 pad_186[0x02]; uint32 music_position; // 0x188 - uint8 var_18C; + uint8 breakdown_reason_pending; // 0x18C uint8 mechanic_status; // 0x18D uint16 mechanic; // 0x18E uint8 inspection_station; // 0x190 - uint8 pad_191[0x02]; + uint8 broken_vehicle; // 0x191 + uint8 broken_car; // 0x192 uint8 breakdown_reason; // 0x193 money16 price_secondary; // 0x194 uint16 var_196; @@ -213,7 +217,7 @@ typedef struct { uint32 var_1A4; uint8 pad_1A8[4]; uint8 var_1AC; - uint8 pad_1AD; + uint8 var_1AD; uint8 var_1AE; uint8 connected_message_throttle; // 0x1AF money32 income_per_hour; // 0x1B0 @@ -492,6 +496,7 @@ enum { }; enum { + RIDE_MECHANIC_STATUS_UNDEFINED = 0, RIDE_MECHANIC_STATUS_CALLING = 1, RIDE_MECHANIC_STATUS_HEADING = 2, RIDE_MECHANIC_STATUS_FIXING = 3, diff --git a/src/ride/ride_data.c b/src/ride/ride_data.c index b1ae1d8b85..d6645eef1a 100644 --- a/src/ride/ride_data.c +++ b/src/ride/ride_data.c @@ -771,4 +771,98 @@ const uint8 RideAvailableModes[] = { RIDE_MODE_CONTINUOUS_CIRCUIT, 0xFF, // 58 Mine Ride RIDE_MODE_CONTINUOUS_CIRCUIT, RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED, 0xFF, // 59 LIM Launched Roller Coaster RIDE_MODE_POWERED_LAUNCH_35, RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED, 0xFF // 60 (none) +}; + +const uint8 RideAvailableBreakdowns[] = { + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 00 Spiral Roller coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 01 Stand Up Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 02 Suspended Swinging + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 03 Inverted + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 04 Steel Mini Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 05 Mini Railroad + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_DOORS_STUCK_CLOSED) | (1 << BREAKDOWN_DOORS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 06 Monorail + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 07 Mini Suspended Coaster + (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 08 Bumper Boats + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 09 Wooden Wild Mine/Mouse + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 0A Steeplechase/Motorbike/Soap Box Derby + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 0B Car Ride + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 0C Launched Freefall + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 0D Bobsleigh Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 0E Observation Tower + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 0F Looping Roller Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 10 Dinghy Slide + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 11 Mine Train Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 12 Chairlift + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 13 Corkscrew Roller Coaster + 0, // 14 Maze + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 15 Spiral Slide + (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 16 Go Karts + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_CONTROL_FAILURE), // 17 Log Flume + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_CONTROL_FAILURE), // 18 River Rapids + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 19 Bumper Cars + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 1A Pirate Ship + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 1B Swinging Inverter Ship + 0, // 1C Food Stall + 0, // 1D (none) + 0, // 1E Drink Stall + 0, // 1F (none) + 0, // 20 Shop (all types) + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_CONTROL_FAILURE), // 21 Merry Go Round + 0, // 22 Balloon Stall (maybe) + 0, // 23 Information Kiosk + 0, // 24 Bathroom + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 25 Ferris Wheel + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 26 Motion Simulator + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 27 3D Cinema + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 28 Gravitron + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 29 Space Rings + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 2A Reverse Freefall Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_DOORS_STUCK_CLOSED) | (1 << BREAKDOWN_DOORS_STUCK_OPEN), // 2B Elevator + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 2C Vertical Drop Roller Coaster + 0, // 2D ATM + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 2E Twist + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 2F Haunted House + 0, // 30 First Aid + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 31 Circus Show + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 32 Ghost Train + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 33 Twister Roller Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 34 Wooden Roller Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 35 Side-Friction Roller Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 36 Wild Mouse + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 37 Multi Dimension Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 38 (none) + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 39 Flying Roller Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 3A (none) + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 3B Virginia Reel + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_CONTROL_FAILURE), // 3C Splash Boats + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 3D Mini Helicopters + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 3E Lay-down Roller Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_DOORS_STUCK_CLOSED) | (1 << BREAKDOWN_DOORS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 3F Suspended Monorail + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 40 (none) + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 41 Reverser Roller Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 42 Heartline Twister Roller Coaster + 0, // 43 Mini Golf + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 44 Giga Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 45 Roto-Drop + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 46 Flying Saucers + 0, // 47 Crooked House + (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 48 Monorail Cycles + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 49 Compact Inverted Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 4A Water Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 4B Air Powered Vertical Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 4C Inverted Hairpin Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 4D Magic Carpet + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 4E Submarine Ride + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 4F River Rafts + 0, // 50 (none) + (1 << BREAKDOWN_SAFETY_CUT_OUT), // 51 Enterprise + 0, // 52 (none) + 0, // 53 (none) + 0, // 54 (none) + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 55 (none) + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 56 Inverted Impulse Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 57 Mini Roller Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 58 Mine Ride + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 59 LIM Launched Roller Coaster + (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE) // 60 (none) }; \ No newline at end of file diff --git a/src/ride/ride_data.h b/src/ride/ride_data.h index d6b1617b04..d45438480d 100644 --- a/src/ride/ride_data.h +++ b/src/ride/ride_data.h @@ -41,5 +41,6 @@ extern const uint8 rideUnknownData3[0x60]; extern const rct_ride_name_convention RideNameConvention[96]; extern const uint8 RideAvailableModes[]; +extern const uint8 RideAvailableBreakdowns[]; #endif \ No newline at end of file