mirror of https://github.com/OpenRCT2/OpenRCT2.git
Fix hacked rides with no vehicles crashing the game.
This commit is contained in:
parent
f8d91279ea
commit
f0bd72732c
|
@ -2595,6 +2595,10 @@ bool Ride::CanBreakDown() const
|
|||
|
||||
static void choose_random_train_to_breakdown_safe(Ride* ride)
|
||||
{
|
||||
// Prevent integer division by zero in case of hacked ride.
|
||||
if (ride->num_vehicles == 0)
|
||||
return;
|
||||
|
||||
ride->broken_vehicle = scenario_rand() % ride->num_vehicles;
|
||||
|
||||
// Prevent crash caused by accessing SPRITE_INDEX_NULL on hacked rides.
|
||||
|
@ -2612,6 +2616,7 @@ static void choose_random_train_to_breakdown_safe(Ride* ride)
|
|||
void ride_prepare_breakdown(int32_t rideIndex, int32_t breakdownReason)
|
||||
{
|
||||
int32_t i;
|
||||
uint16_t vehicleSpriteIdx;
|
||||
Ride* ride;
|
||||
rct_vehicle* vehicle;
|
||||
|
||||
|
@ -2646,21 +2651,25 @@ void ride_prepare_breakdown(int32_t rideIndex, int32_t breakdownReason)
|
|||
ride->broken_car = scenario_rand() % ride->num_cars_per_train;
|
||||
|
||||
// Set flag on broken car
|
||||
vehicle = GET_VEHICLE(ride->vehicles[ride->broken_vehicle]);
|
||||
for (i = ride->broken_car; i > 0; i--)
|
||||
vehicleSpriteIdx = ride->vehicles[ride->broken_vehicle];
|
||||
if (vehicleSpriteIdx != SPRITE_INDEX_NULL)
|
||||
{
|
||||
if (vehicle->next_vehicle_on_train == SPRITE_INDEX_NULL)
|
||||
vehicle = GET_VEHICLE(vehicleSpriteIdx);
|
||||
for (i = ride->broken_car; i > 0; i--)
|
||||
{
|
||||
vehicle = nullptr;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train);
|
||||
if (vehicle->next_vehicle_on_train == SPRITE_INDEX_NULL)
|
||||
{
|
||||
vehicle = nullptr;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train);
|
||||
}
|
||||
}
|
||||
if (vehicle != nullptr)
|
||||
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_BROKEN_CAR;
|
||||
}
|
||||
if (vehicle != nullptr)
|
||||
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_BROKEN_CAR;
|
||||
break;
|
||||
case BREAKDOWN_VEHICLE_MALFUNCTION:
|
||||
// Choose a random train
|
||||
|
@ -2668,8 +2677,12 @@ void ride_prepare_breakdown(int32_t rideIndex, int32_t breakdownReason)
|
|||
ride->broken_car = 0;
|
||||
|
||||
// Set flag on broken train, first car
|
||||
vehicle = GET_VEHICLE(ride->vehicles[ride->broken_vehicle]);
|
||||
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_BROKEN_TRAIN;
|
||||
vehicleSpriteIdx = ride->vehicles[ride->broken_vehicle];
|
||||
if (vehicleSpriteIdx != SPRITE_INDEX_NULL)
|
||||
{
|
||||
vehicle = GET_VEHICLE(vehicleSpriteIdx);
|
||||
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_BROKEN_TRAIN;
|
||||
}
|
||||
break;
|
||||
case BREAKDOWN_BRAKES_FAILURE:
|
||||
// Original code generates a random number but does not use it
|
||||
|
@ -2978,11 +2991,15 @@ static void ride_music_update(int32_t rideIndex)
|
|||
|
||||
if (ride->type == RIDE_TYPE_CIRCUS)
|
||||
{
|
||||
rct_vehicle* vehicle = GET_VEHICLE(ride->vehicles[0]);
|
||||
if (vehicle->status != VEHICLE_STATUS_DOING_CIRCUS_SHOW)
|
||||
uint16_t vehicleSpriteIdx = ride->vehicles[0];
|
||||
if (vehicleSpriteIdx != SPRITE_INDEX_NULL)
|
||||
{
|
||||
ride->music_tune_id = 255;
|
||||
return;
|
||||
rct_vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx);
|
||||
if (vehicle->status != VEHICLE_STATUS_DOING_CIRCUS_SHOW)
|
||||
{
|
||||
ride->music_tune_id = 255;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3169,11 +3186,11 @@ void ride_measurements_update()
|
|||
// For each vehicle
|
||||
for (int32_t j = 0; j < ride->num_vehicles; j++)
|
||||
{
|
||||
uint16_t spriteIndex = ride->vehicles[j];
|
||||
if (spriteIndex == SPRITE_INDEX_NULL)
|
||||
uint16_t vehicleSpriteIdx = ride->vehicles[j];
|
||||
if (vehicleSpriteIdx == SPRITE_INDEX_NULL)
|
||||
continue;
|
||||
|
||||
rct_vehicle* vehicle = GET_VEHICLE(spriteIndex);
|
||||
rct_vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx);
|
||||
if (vehicle->status == VEHICLE_STATUS_DEPARTING || vehicle->status == VEHICLE_STATUS_TRAVELLING_CABLE_LIFT)
|
||||
{
|
||||
measurement->vehicle_index = j;
|
||||
|
@ -5324,7 +5341,11 @@ void loc_6DDF9C(Ride* ride, TileElement* tileElement)
|
|||
|
||||
for (int32_t i = 0; i < ride->num_vehicles; i++)
|
||||
{
|
||||
train = GET_VEHICLE(ride->vehicles[i]);
|
||||
uint16_t vehicleSpriteIdx = ride->vehicles[i];
|
||||
if (vehicleSpriteIdx == SPRITE_INDEX_NULL)
|
||||
continue;
|
||||
|
||||
train = GET_VEHICLE(vehicleSpriteIdx);
|
||||
if (i == 0)
|
||||
{
|
||||
vehicle_update_track_motion(train, nullptr);
|
||||
|
|
|
@ -99,7 +99,11 @@ static void ride_update_station_bumpercar(Ride* ride, int32_t stationIndex)
|
|||
int32_t dh = (dx >> 8) & 0xFF;
|
||||
for (size_t i = 0; i < ride->num_vehicles; i++)
|
||||
{
|
||||
rct_vehicle* vehicle = &(get_sprite(ride->vehicles[i])->vehicle);
|
||||
uint16_t vehicleSpriteIdx = ride->vehicles[i];
|
||||
if (vehicleSpriteIdx == SPRITE_INDEX_NULL)
|
||||
continue;
|
||||
|
||||
rct_vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx);
|
||||
if (vehicle->var_CE < dh || (vehicle->var_CE < dh && vehicle->sub_state > dl))
|
||||
continue;
|
||||
|
||||
|
@ -117,7 +121,11 @@ static void ride_update_station_bumpercar(Ride* ride, int32_t stationIndex)
|
|||
// Check if all vehicles are ready to go
|
||||
for (size_t i = 0; i < ride->num_vehicles; i++)
|
||||
{
|
||||
rct_vehicle* vehicle = &(get_sprite(ride->vehicles[i])->vehicle);
|
||||
uint16_t vehicleSpriteIdx = ride->vehicles[i];
|
||||
if (vehicleSpriteIdx == SPRITE_INDEX_NULL)
|
||||
continue;
|
||||
|
||||
rct_vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx);
|
||||
if (vehicle->status != VEHICLE_STATUS_WAITING_TO_DEPART)
|
||||
{
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
|
@ -185,15 +193,20 @@ static void ride_update_station_race(Ride* ride, int32_t stationIndex)
|
|||
if (ride->lifecycle_flags & RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING)
|
||||
{
|
||||
int32_t numLaps = ride->num_laps;
|
||||
|
||||
for (size_t i = 0; i < ride->num_vehicles; i++)
|
||||
{
|
||||
rct_vehicle* vehicle = &(get_sprite(ride->vehicles[i])->vehicle);
|
||||
uint16_t vehicleSpriteIdx = ride->vehicles[i];
|
||||
if (vehicleSpriteIdx == SPRITE_INDEX_NULL)
|
||||
continue;
|
||||
|
||||
rct_vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx);
|
||||
if (vehicle->status != VEHICLE_STATUS_WAITING_TO_DEPART && vehicle->num_laps >= numLaps)
|
||||
{
|
||||
// Found a winner
|
||||
if (vehicle->num_peeps != 0)
|
||||
{
|
||||
rct_peep* peep = &(get_sprite(vehicle->peep[0])->peep);
|
||||
rct_peep* peep = GET_PEEP(vehicle->peep[0]);
|
||||
ride->race_winner = peep->sprite_index;
|
||||
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST;
|
||||
}
|
||||
|
@ -217,7 +230,11 @@ static void ride_update_station_race(Ride* ride, int32_t stationIndex)
|
|||
// Check if all vehicles are ready to go
|
||||
for (size_t i = 0; i < ride->num_vehicles; i++)
|
||||
{
|
||||
rct_vehicle* vehicle = &(get_sprite(ride->vehicles[i])->vehicle);
|
||||
uint16_t vehicleSpriteIdx = ride->vehicles[i];
|
||||
if (vehicleSpriteIdx == SPRITE_INDEX_NULL)
|
||||
continue;
|
||||
|
||||
rct_vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx);
|
||||
if (vehicle->status != VEHICLE_STATUS_WAITING_TO_DEPART && vehicle->status != VEHICLE_STATUS_DEPARTING)
|
||||
{
|
||||
if (ride->station_depart[stationIndex] & STATION_DEPART_FLAG)
|
||||
|
@ -251,7 +268,11 @@ static void ride_race_init_vehicle_speeds(Ride* ride)
|
|||
{
|
||||
for (size_t i = 0; i < ride->num_vehicles; i++)
|
||||
{
|
||||
rct_vehicle* vehicle = &get_sprite(ride->vehicles[i])->vehicle;
|
||||
uint16_t vehicleSpriteIdx = ride->vehicles[i];
|
||||
if (vehicleSpriteIdx == SPRITE_INDEX_NULL)
|
||||
continue;
|
||||
|
||||
rct_vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx);
|
||||
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_6;
|
||||
|
||||
rct_ride_entry* rideEntry = get_ride_entry(vehicle->ride_subtype);
|
||||
|
|
Loading…
Reference in New Issue