Reduce the use of GET_VEHICLE (#12494)

* Start removing GET_VEHICLE macro use

* Further work

* Remove further GET_VEHICLE's

* Further removal of GET_VEHICLE

* Remove the last of GET_VEHICLE

* Fix testpaint

* Fix nullptr deref

* Make review changes

Also swapped in helper functions and used a standard patern for iterating the train cars

* Further simplify loops for train cars
This commit is contained in:
Duncan 2020-07-31 07:48:27 +01:00 committed by GitHub
parent d32809eaef
commit c6e26267a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 421 additions and 401 deletions

View File

@ -1093,11 +1093,8 @@ static void window_map_paint_train_overlay(rct_drawpixelinfo* dpi)
{
for (auto train : EntityList<Vehicle>(EntityListId::TrainHead))
{
Vehicle* vehicle = nullptr;
for (auto vehicle_index = train->sprite_index; vehicle_index != SPRITE_INDEX_NULL;
vehicle_index = vehicle->next_vehicle_on_train)
for (Vehicle* vehicle = train; vehicle != nullptr; vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
vehicle = GET_VEHICLE(vehicle_index);
if (vehicle->x == LOCATION_NULL)
continue;

View File

@ -1781,7 +1781,7 @@ static void window_ride_init_viewport(rct_window* w)
rct_ride_entry* ride_entry = ride->GetRideEntry();
if (ride_entry && ride_entry->tab_vehicle != 0)
{
Vehicle* vehicle = GET_VEHICLE(focus.sprite.sprite_id);
Vehicle* vehicle = GetEntity<Vehicle>(focus.sprite.sprite_id);
if (vehicle == nullptr)
{
focus.sprite.sprite_id = SPRITE_INDEX_NULL;
@ -4053,18 +4053,12 @@ static void window_ride_maintenance_dropdown(rct_window* w, rct_widgetindex widg
break;
for (int32_t i = 0; i < ride->num_vehicles; ++i)
{
uint16_t spriteId = ride->vehicles[i];
while (spriteId != SPRITE_INDEX_NULL)
for (vehicle = GetEntity<Vehicle>(ride->vehicles[i]); vehicle != nullptr;
vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
vehicle = GetEntity<Vehicle>(spriteId);
if (vehicle == nullptr)
{
break;
}
vehicle->ClearUpdateFlag(
VEHICLE_UPDATE_FLAG_BROKEN_CAR | VEHICLE_UPDATE_FLAG_ZERO_VELOCITY
| VEHICLE_UPDATE_FLAG_BROKEN_TRAIN);
spriteId = vehicle->next_vehicle_on_train;
}
}
break;

View File

@ -631,7 +631,7 @@ static void window_title_command_editor_tool_down(
else if (spriteIdentifier == SPRITE_IDENTIFIER_VEHICLE)
{
validSprite = true;
auto vehicle = GET_VEHICLE(spriteIndex);
auto vehicle = GetEntity<Vehicle>(spriteIndex);
if (vehicle != nullptr)
{
auto ride = vehicle->GetRide();

View File

@ -641,7 +641,6 @@ private:
void RemoveAllGuests() const
{
uint16_t spriteIndex;
for (auto& ride : GetRideManager())
{
ride.num_riders = 0;
@ -654,32 +653,21 @@ private:
for (auto trainIndex : ride.vehicles)
{
spriteIndex = trainIndex;
while (spriteIndex != SPRITE_INDEX_NULL)
for (Vehicle* vehicle = TryGetEntity<Vehicle>(trainIndex); vehicle != nullptr;
vehicle = TryGetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
auto vehicle = GET_VEHICLE(spriteIndex);
for (size_t i = 0, offset = 0; i < vehicle->num_peeps; i++)
for (auto& peepInTrainIndex : vehicle->peep)
{
while (vehicle->peep[i + offset] == SPRITE_INDEX_NULL)
{
offset++;
}
auto peep = TryGetEntity<Guest>(vehicle->peep[i + offset]);
auto peep = TryGetEntity<Guest>(peepInTrainIndex);
if (peep != nullptr)
{
vehicle->mass -= peep->Mass;
}
}
for (auto& peepInTrainIndex : vehicle->peep)
{
peepInTrainIndex = SPRITE_INDEX_NULL;
}
vehicle->num_peeps = 0;
vehicle->next_free_seat = 0;
spriteIndex = vehicle->next_vehicle_on_train;
}
}
}

View File

@ -739,7 +739,11 @@ void lightfx_add_lights_magic_vehicle(const Vehicle* vehicle)
Vehicle* vehicle_draw = vehicle->TrainHead();
if (vehicle_draw->next_vehicle_on_train != SPRITE_INDEX_NULL)
{
vehicle_draw = GET_VEHICLE(vehicle_draw->next_vehicle_on_train);
auto nextVeh = GetEntity<Vehicle>(vehicle_draw->next_vehicle_on_train);
if (nextVeh != nullptr)
{
vehicle_draw = nextVeh;
}
}
place_x = vehicle_draw->x;
place_y = vehicle_draw->y;

View File

@ -256,14 +256,12 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv)
}
else
{
for (int32_t i = 0; i < ride->num_vehicles; i++)
for (int32_t i = 0; i < ride->num_vehicles; ++i)
{
uint16_t vehicle_index = ride->vehicles[i];
while (vehicle_index != SPRITE_INDEX_NULL)
for (Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[i]); vehicle != nullptr;
vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
Vehicle* vehicle = GET_VEHICLE(vehicle_index);
vehicle->mass = mass;
vehicle_index = vehicle->next_vehicle_on_train;
}
}
}

View File

@ -707,10 +707,10 @@ viewport_focus viewport_update_smart_guest_follow(rct_window* window, Peep* peep
auto ride = get_ride(peep->CurrentRide);
if (ride != nullptr && (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK))
{
auto train = GET_VEHICLE(ride->vehicles[peep->CurrentTrain]);
auto train = GetEntity<Vehicle>(ride->vehicles[peep->CurrentTrain]);
if (train != nullptr)
{
auto car = train->GetCar(peep->CurrentCar);
const auto car = train->GetCar(peep->CurrentCar);
if (car != nullptr)
{
focus.sprite.sprite_id = car->sprite_index;

View File

@ -2487,14 +2487,12 @@ static Vehicle* peep_choose_car_from_ride(Peep* peep, Ride* ride, std::vector<ui
peep->CurrentCar = car_array[chosen_car];
Vehicle* vehicle = GET_VEHICLE(ride->vehicles[peep->CurrentTrain]);
for (int32_t i = peep->CurrentCar; i > 0; --i)
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[peep->CurrentTrain]);
if (vehicle == nullptr)
{
vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train);
return nullptr;
}
return vehicle;
return vehicle->GetCar(peep->CurrentCar);
}
/**
@ -2503,6 +2501,10 @@ static Vehicle* peep_choose_car_from_ride(Peep* peep, Ride* ride, std::vector<ui
*/
static void peep_choose_seat_from_car(Peep* peep, Ride* ride, Vehicle* vehicle)
{
if (vehicle == nullptr)
{
return;
}
uint8_t chosen_seat = vehicle->next_free_seat;
if (ride->mode == RIDE_MODE_FORWARD_ROTATION || ride->mode == RIDE_MODE_BACKWARD_ROTATION)
@ -2579,7 +2581,7 @@ bool Guest::FindVehicleToEnter(Ride* ride, std::vector<uint8_t>& car_array)
for (int32_t i = 0; i < ride->num_vehicles; ++i)
{
Vehicle* vehicle = GET_VEHICLE(ride->vehicles[i]);
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[i]);
if (vehicle == nullptr)
continue;
@ -2606,12 +2608,9 @@ bool Guest::FindVehicleToEnter(Ride* ride, std::vector<uint8_t>& car_array)
int32_t i = 0;
uint16_t vehicle_id = ride->vehicles[chosen_train];
Vehicle* vehicle = nullptr;
for (; vehicle_id != SPRITE_INDEX_NULL; vehicle_id = vehicle->next_vehicle_on_train, i++)
for (Vehicle* vehicle = GetEntity<Vehicle>(vehicle_id); vehicle != nullptr;
vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train), ++i)
{
vehicle = GET_VEHICLE(vehicle_id);
uint8_t num_seats = vehicle->num_seats;
if (vehicle->IsUsedInPairs())
{
@ -3640,7 +3639,12 @@ static void peep_update_ride_leave_entrance_waypoints(Peep* peep, Ride* ride)
uint8_t direction_track = (tile_element == nullptr ? 0 : tile_element->GetDirection());
auto vehicle = GET_VEHICLE(ride->vehicles[peep->CurrentTrain]);
auto vehicle = GetEntity<Vehicle>(ride->vehicles[peep->CurrentTrain]);
if (vehicle == nullptr)
{
// TODO: Goto ride exit on failure.
return;
}
auto ride_entry = vehicle->GetRideEntry();
auto vehicle_type = &ride_entry->vehicles[vehicle->vehicle_type];
@ -3742,20 +3746,13 @@ void Guest::UpdateRideAdvanceThroughEntrance()
}
}
Vehicle* vehicle = GET_VEHICLE(ride->vehicles[CurrentTrain]);
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[CurrentTrain]);
if (vehicle == nullptr)
{
return;
}
for (int32_t i = CurrentCar; i != 0; --i)
{
vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train);
if (vehicle == nullptr)
{
return;
}
}
vehicle = vehicle->GetCar(CurrentCar);
ride_entry = vehicle->GetRideEntry();
if (ride_entry == nullptr)
@ -3973,11 +3970,13 @@ void Guest::UpdateRideFreeVehicleCheck()
return;
}
Vehicle* vehicle = GET_VEHICLE(ride->vehicles[CurrentTrain]);
for (int32_t i = CurrentCar; i != 0; --i)
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[CurrentTrain]);
if (vehicle == nullptr)
{
vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train);
// TODO: Leave ride on failure goes for all returns on nullptr in this function
return;
}
vehicle = vehicle->GetCar(CurrentCar);
rct_ride_entry* ride_entry = vehicle->GetRideEntry();
if (ride_entry == nullptr)
@ -3994,8 +3993,13 @@ void Guest::UpdateRideFreeVehicleCheck()
if (ride->vehicles[i] == SPRITE_INDEX_NULL)
continue;
Vehicle* train = GET_VEHICLE(ride->vehicles[i]);
Vehicle* second_vehicle = GET_VEHICLE(train->next_vehicle_on_train);
Vehicle* train = GetEntity<Vehicle>(ride->vehicles[i]);
if (train == nullptr)
continue;
Vehicle* second_vehicle = GetEntity<Vehicle>(train->next_vehicle_on_train);
if (second_vehicle == nullptr)
continue;
if (second_vehicle->num_peeps == 0)
continue;
@ -4031,7 +4035,11 @@ void Guest::UpdateRideFreeVehicleCheck()
}
}
Vehicle* currentTrain = GET_VEHICLE(ride->vehicles[CurrentTrain]);
Vehicle* currentTrain = GetEntity<Vehicle>(ride->vehicles[CurrentTrain]);
if (currentTrain == nullptr)
{
return;
}
if (ride->status == RIDE_STATUS_OPEN && ++RejoinQueueTimeout != 0
&& !currentTrain->HasUpdateFlag(VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART))
{
@ -4065,13 +4073,10 @@ void Guest::UpdateRideEnterVehicle()
auto* ride = get_ride(CurrentRide);
if (ride != nullptr)
{
auto* vehicle = GET_VEHICLE(ride->vehicles[CurrentTrain]);
auto* vehicle = GetEntity<Vehicle>(ride->vehicles[CurrentTrain]);
if (vehicle != nullptr)
{
for (int32_t i = CurrentCar; i != 0; --i)
{
vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train);
}
vehicle = vehicle->GetCar(CurrentCar);
if (ride->mode != RIDE_MODE_FORWARD_ROTATION && ride->mode != RIDE_MODE_BACKWARD_ROTATION)
{
@ -4126,12 +4131,15 @@ void Guest::UpdateRideLeaveVehicle()
if (ride == nullptr)
return;
Vehicle* vehicle = GET_VEHICLE(ride->vehicles[CurrentTrain]);
uint8_t ride_station = vehicle->current_station;
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[CurrentTrain]);
if (vehicle == nullptr)
return;
for (int32_t i = CurrentCar; i != 0; --i)
uint8_t ride_station = vehicle->current_station;
vehicle = vehicle->GetCar(CurrentCar);
if (vehicle == nullptr)
{
vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train);
return;
}
// Check if ride is NOT Ferris Wheel.
@ -4181,7 +4189,7 @@ void Guest::UpdateRideLeaveVehicle()
if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_VEHICLE_IS_INTEGRAL))
{
for (; !vehicle->IsHead(); vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride))
for (; vehicle != nullptr && !vehicle->IsHead(); vehicle = GetEntity<Vehicle>(vehicle->prev_vehicle_on_ride))
{
uint16_t trackType = vehicle->GetTrackType();
if (trackType == TRACK_ELEM_FLAT || trackType > TRACK_ELEM_MIDDLE_STATION)
@ -4203,6 +4211,10 @@ void Guest::UpdateRideLeaveVehicle()
break;
}
if (vehicle == nullptr)
{
return;
}
uint8_t shiftMultiplier = 12;
uint8_t specialDirection = platformLocation.direction;
@ -4286,7 +4298,11 @@ void Guest::UpdateRideLeaveVehicle()
Direction station_direction = (trackElement == nullptr ? 0 : trackElement->GetDirection());
vehicle = GET_VEHICLE(ride->vehicles[CurrentTrain]);
vehicle = GetEntity<Vehicle>(ride->vehicles[CurrentTrain]);
if (vehicle == nullptr)
{
return;
}
rideEntry = vehicle->GetRideEntry();
rct_ride_entry_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
@ -4471,7 +4487,11 @@ void Guest::UpdateRideApproachVehicleWaypoints()
// This is incrementing the actual peep waypoint
Var37++;
Vehicle* vehicle = GET_VEHICLE(ride->vehicles[CurrentTrain]);
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[CurrentTrain]);
if (vehicle == nullptr)
{
return;
}
CoordsXY targetLoc = ride->stations[CurrentRideStation].Start.ToTileCentre();
@ -4540,7 +4560,11 @@ void Guest::UpdateRideApproachExitWaypoints()
}
Var37--;
Vehicle* vehicle = GET_VEHICLE(ride->vehicles[CurrentTrain]);
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[CurrentTrain]);
if (vehicle == nullptr)
{
return;
}
CoordsXY targetLoc = ride->stations[CurrentRideStation].Start.ToTileCentre();
if (ride->type == RIDE_TYPE_ENTERPRISE)

View File

@ -2193,7 +2193,11 @@ bool Staff::UpdateFixingMoveToBrokenDownVehicle(bool firstRun, Ride* ride)
break;
}
vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
vehicle = GetEntity<Vehicle>(vehicle->prev_vehicle_on_ride);
if (vehicle == nullptr)
{
return true;
}
}
CoordsXY offset = DirectionOffsets[PeepDirection];

View File

@ -152,8 +152,12 @@ void Vehicle::CableLiftUpdateWaitingToDepart()
// Next check to see if the second part of the cable lift
// is at the front of the passenger vehicle to simulate the
// cable being attached underneath the train.
Vehicle* passengerVehicle = GET_VEHICLE(cable_lift_target);
Vehicle* cableLiftSecondPart = GET_VEHICLE(prev_vehicle_on_ride);
Vehicle* passengerVehicle = GetEntity<Vehicle>(cable_lift_target);
Vehicle* cableLiftSecondPart = GetEntity<Vehicle>(prev_vehicle_on_ride);
if (passengerVehicle == nullptr || cableLiftSecondPart == nullptr)
{
return;
}
int16_t distX = abs(passengerVehicle->x - cableLiftSecondPart->x);
int16_t distY = abs(passengerVehicle->y - cableLiftSecondPart->y);
@ -176,7 +180,11 @@ void Vehicle::CableLiftUpdateDeparting()
if (sub_state < 16)
return;
Vehicle* passengerVehicle = GET_VEHICLE(cable_lift_target);
Vehicle* passengerVehicle = GetEntity<Vehicle>(cable_lift_target);
if (passengerVehicle == nullptr)
{
return;
}
SetState(VEHICLE_STATUS_TRAVELLING, sub_state);
passengerVehicle->SetState(VEHICLE_STATUS_TRAVELLING_CABLE_LIFT, passengerVehicle->sub_state);
}
@ -187,7 +195,11 @@ void Vehicle::CableLiftUpdateDeparting()
*/
void Vehicle::CableLiftUpdateTravelling()
{
Vehicle* passengerVehicle = GET_VEHICLE(cable_lift_target);
Vehicle* passengerVehicle = GetEntity<Vehicle>(cable_lift_target);
if (passengerVehicle == nullptr)
{
return;
}
velocity = std::min(passengerVehicle->velocity, 439800);
acceleration = 0;
@ -371,7 +383,7 @@ int32_t Vehicle::CableLiftUpdateTrackMotion()
_vehicleFrontVehicle = frontVehicle;
for (Vehicle* vehicle = frontVehicle;;)
for (Vehicle* vehicle = frontVehicle; vehicle != nullptr;)
{
vehicle->acceleration = dword_9A2970[vehicle->vehicle_sprite_type];
_vehicleUnkF64E10 = 1;
@ -425,15 +437,13 @@ int32_t Vehicle::CableLiftUpdateTrackMotion()
vehicle->acceleration /= _vehicleUnkF64E10;
if (_vehicleVelocityF64E08 >= 0)
{
if (vehicle->next_vehicle_on_train == SPRITE_INDEX_NULL)
break;
vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train);
vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train);
}
else
{
if (vehicle == this)
break;
vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
vehicle = GetEntity<Vehicle>(vehicle->prev_vehicle_on_ride);
}
}
@ -441,15 +451,13 @@ int32_t Vehicle::CableLiftUpdateTrackMotion()
uint16_t massTotal = 0;
int32_t accelerationTotal = 0;
for (uint16_t spriteId = sprite_index; spriteId != SPRITE_INDEX_NULL;)
for (Vehicle* vehicle = GetEntity<Vehicle>(sprite_index); vehicle != nullptr;
vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
Vehicle* vehicle = GET_VEHICLE(spriteId);
vehicleCount++;
massTotal += vehicle->mass;
accelerationTotal = add_clamp_int32_t(accelerationTotal, vehicle->acceleration);
spriteId = vehicle->next_vehicle_on_train;
}
int32_t newAcceleration = (accelerationTotal / vehicleCount) >> 9;

View File

@ -1013,7 +1013,11 @@ static void ride_remove_cable_lift(Ride* ride)
uint16_t spriteIndex = ride->cable_lift;
do
{
Vehicle* vehicle = GET_VEHICLE(spriteIndex);
Vehicle* vehicle = GetEntity<Vehicle>(spriteIndex);
if (vehicle == nullptr)
{
return;
}
vehicle->Invalidate();
sprite_remove(vehicle);
spriteIndex = vehicle->next_vehicle_on_train;
@ -1037,7 +1041,11 @@ static void ride_remove_vehicles(Ride* ride)
uint16_t spriteIndex = ride->vehicles[i];
while (spriteIndex != SPRITE_INDEX_NULL)
{
Vehicle* vehicle = GET_VEHICLE(spriteIndex);
Vehicle* vehicle = GetEntity<Vehicle>(spriteIndex);
if (vehicle == nullptr)
{
break;
}
vehicle->Invalidate();
sprite_remove(vehicle);
spriteIndex = vehicle->next_vehicle_on_train;
@ -2483,24 +2491,14 @@ void ride_prepare_breakdown(Ride* ride, int32_t breakdownReason)
ride->broken_car = scenario_rand() % ride->num_cars_per_train;
// Set flag on broken car
vehicleSpriteIdx = ride->vehicles[ride->broken_vehicle];
if (vehicleSpriteIdx != SPRITE_INDEX_NULL)
vehicle = GetEntity<Vehicle>(ride->vehicles[ride->broken_vehicle]);
if (vehicle != nullptr)
{
vehicle = GET_VEHICLE(vehicleSpriteIdx);
for (i = ride->broken_car; i > 0; i--)
{
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->SetUpdateFlag(VEHICLE_UPDATE_FLAG_BROKEN_CAR);
vehicle = vehicle->GetCar(ride->broken_car);
}
if (vehicle != nullptr)
{
vehicle->SetUpdateFlag(VEHICLE_UPDATE_FLAG_BROKEN_CAR);
}
}
break;
@ -2513,8 +2511,11 @@ void ride_prepare_breakdown(Ride* ride, int32_t breakdownReason)
vehicleSpriteIdx = ride->vehicles[ride->broken_vehicle];
if (vehicleSpriteIdx != SPRITE_INDEX_NULL)
{
vehicle = GET_VEHICLE(vehicleSpriteIdx);
vehicle->SetUpdateFlag(VEHICLE_UPDATE_FLAG_BROKEN_TRAIN);
vehicle = GetEntity<Vehicle>(vehicleSpriteIdx);
if (vehicle != nullptr)
{
vehicle->SetUpdateFlag(VEHICLE_UPDATE_FLAG_BROKEN_TRAIN);
}
}
break;
case BREAKDOWN_BRAKES_FAILURE:
@ -2804,8 +2805,8 @@ static void ride_music_update(Ride* ride)
uint16_t vehicleSpriteIdx = ride->vehicles[0];
if (vehicleSpriteIdx != SPRITE_INDEX_NULL)
{
Vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx);
if (vehicle->status != VEHICLE_STATUS_DOING_CIRCUS_SHOW)
Vehicle* vehicle = GetEntity<Vehicle>(vehicleSpriteIdx);
if (vehicle != nullptr && vehicle->status != VEHICLE_STATUS_DOING_CIRCUS_SHOW)
{
ride->music_tune_id = 255;
return;
@ -2883,7 +2884,7 @@ static void ride_measurement_update(Ride& ride, RideMeasurement& measurement)
if (spriteIndex == SPRITE_INDEX_NULL)
return;
auto vehicle = GET_VEHICLE(spriteIndex);
auto vehicle = GetEntity<Vehicle>(spriteIndex);
if (vehicle == nullptr)
return;
@ -2973,9 +2974,9 @@ void ride_measurements_update()
for (int32_t j = 0; j < ride.num_vehicles; j++)
{
uint16_t vehicleSpriteIdx = ride.vehicles[j];
if (vehicleSpriteIdx != SPRITE_INDEX_NULL)
auto vehicle = GetEntity<Vehicle>(vehicleSpriteIdx);
if (vehicle != nullptr)
{
auto vehicle = GET_VEHICLE(vehicleSpriteIdx);
if (vehicle->status == VEHICLE_STATUS_DEPARTING
|| vehicle->status == VEHICLE_STATUS_TRAVELLING_CABLE_LIFT)
{
@ -4615,16 +4616,9 @@ static void vehicle_create_trains(ride_id_t rideIndex, const CoordsXYZ& trainsPo
static void vehicle_unset_update_flag_b1(Vehicle* head)
{
Vehicle* vehicle = head;
while (true)
for (auto vehicle = head; vehicle != nullptr; vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
vehicle->ClearUpdateFlag(VEHICLE_UPDATE_FLAG_1);
uint16_t spriteIndex = vehicle->next_vehicle_on_train;
if (spriteIndex == SPRITE_INDEX_NULL)
{
break;
}
vehicle = GET_VEHICLE(spriteIndex);
}
}
@ -4634,7 +4628,9 @@ static void vehicle_unset_update_flag_b1(Vehicle* head)
*/
static void ride_create_vehicles_find_first_block(Ride* ride, CoordsXYE* outXYElement)
{
Vehicle* vehicle = GET_VEHICLE(ride->vehicles[0]);
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[0]);
assert(vehicle != nullptr);
auto curTrackPos = vehicle->TrackLocation;
auto curTrackElement = map_get_track_element_at(curTrackPos);
@ -4756,7 +4752,11 @@ static bool ride_create_vehicles(Ride* ride, const CoordsXYE& element, int32_t i
{
for (int32_t i = 0; i < ride->num_vehicles; i++)
{
Vehicle* vehicle = GET_VEHICLE(ride->vehicles[i]);
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[i]);
if (vehicle == nullptr)
{
continue;
}
auto vehicleEntry = vehicle->Entry();
@ -4779,15 +4779,12 @@ static bool ride_create_vehicles(Ride* ride, const CoordsXYE& element, int32_t i
*/
void loc_6DDF9C(Ride* ride, TileElement* tileElement)
{
Vehicle *train, *car;
for (int32_t i = 0; i < ride->num_vehicles; i++)
{
uint16_t vehicleSpriteIdx = ride->vehicles[i];
if (vehicleSpriteIdx == SPRITE_INDEX_NULL)
auto train = GetEntity<Vehicle>(ride->vehicles[i]);
if (train == nullptr)
continue;
train = GET_VEHICLE(vehicleSpriteIdx);
if (i == 0)
{
train->UpdateTrackMotion(nullptr);
@ -4800,26 +4797,17 @@ void loc_6DDF9C(Ride* ride, TileElement* tileElement)
do
{
tileElement->AsTrack()->SetBlockBrakeClosed(true);
car = train;
while (true)
for (Vehicle* car = train; car != nullptr; car = GetEntity<Vehicle>(car->next_vehicle_on_train))
{
car->velocity = 0;
car->acceleration = 0;
car->SwingSprite = 0;
car->remaining_distance += 13962;
uint16_t spriteIndex = car->next_vehicle_on_train;
if (spriteIndex == SPRITE_INDEX_NULL)
{
break;
}
car = GET_VEHICLE(spriteIndex);
}
} while (!(train->UpdateTrackMotion(nullptr) & VEHICLE_UPDATE_MOTION_TRACK_FLAG_10));
tileElement->AsTrack()->SetBlockBrakeClosed(true);
car = train;
while (true)
for (Vehicle* car = train; car != nullptr; car = GetEntity<Vehicle>(car->next_vehicle_on_train))
{
car->ClearUpdateFlag(VEHICLE_UPDATE_FLAG_1);
car->SetState(VEHICLE_STATUS_TRAVELLING, car->sub_state);
@ -4827,13 +4815,6 @@ void loc_6DDF9C(Ride* ride, TileElement* tileElement)
{
car->SetState(VEHICLE_STATUS_MOVING_TO_END_OF_STATION, car->sub_state);
}
uint16_t spriteIndex = car->next_vehicle_on_train;
if (spriteIndex == SPRITE_INDEX_NULL)
{
break;
}
car = GET_VEHICLE(spriteIndex);
}
}
}
@ -6356,10 +6337,9 @@ void invalidate_test_results(Ride* ride)
{
for (int32_t i = 0; i < ride->num_vehicles; i++)
{
uint16_t spriteIndex = ride->vehicles[i];
if (spriteIndex != SPRITE_INDEX_NULL)
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[i]);
if (vehicle != nullptr)
{
Vehicle* vehicle = GET_VEHICLE(spriteIndex);
vehicle->ClearUpdateFlag(VEHICLE_UPDATE_FLAG_TESTING);
}
}
@ -6388,7 +6368,11 @@ void ride_fix_breakdown(Ride* ride, int32_t reliabilityIncreaseFactor)
uint16_t spriteIndex = ride->vehicles[i];
while (spriteIndex != SPRITE_INDEX_NULL)
{
Vehicle* vehicle = GET_VEHICLE(spriteIndex);
Vehicle* vehicle = GetEntity<Vehicle>(spriteIndex);
if (vehicle == nullptr)
{
break;
}
vehicle->ClearUpdateFlag(VEHICLE_UPDATE_FLAG_ZERO_VELOCITY);
vehicle->ClearUpdateFlag(VEHICLE_UPDATE_FLAG_BROKEN_CAR);
vehicle->ClearUpdateFlag(VEHICLE_UPDATE_FLAG_BROKEN_TRAIN);
@ -6415,12 +6399,11 @@ void ride_update_vehicle_colours(Ride* ride)
for (int32_t i = 0; i <= MAX_VEHICLES_PER_RIDE; i++)
{
int32_t carIndex = 0;
uint16_t spriteIndex = ride->vehicles[i];
VehicleColour colours = {};
while (spriteIndex != SPRITE_INDEX_NULL)
for (Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[i]); vehicle != nullptr;
vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
Vehicle* vehicle = GET_VEHICLE(spriteIndex);
switch (ride->colour_scheme_type & 3)
{
case RIDE_COLOUR_SCHEME_ALL_SAME:
@ -6441,7 +6424,6 @@ void ride_update_vehicle_colours(Ride* ride)
vehicle->colours.trim_colour = colours.Trim;
vehicle->colours_extended = colours.Ternary;
vehicle->Invalidate();
spriteIndex = vehicle->next_vehicle_on_train;
carIndex++;
}
}
@ -7085,9 +7067,9 @@ void Ride::SetToDefaultInspectionInterval()
*/
void Ride::Crash(uint8_t vehicleIndex)
{
Vehicle* vehicle = GET_VEHICLE(vehicles[vehicleIndex]);
Vehicle* vehicle = GetEntity<Vehicle>(vehicles[vehicleIndex]);
if (!(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO))
if (!(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) && vehicle != nullptr)
{
// Open ride window for crashed vehicle
auto intent = Intent(WD_VEHICLE);
@ -7139,19 +7121,12 @@ uint32_t ride_customers_in_last_5_minutes(const Ride* ride)
Vehicle* ride_get_broken_vehicle(Ride* ride)
{
uint16_t vehicleIndex = ride->vehicles[ride->broken_vehicle];
if (vehicleIndex == SPRITE_INDEX_NULL)
Vehicle* vehicle = GetEntity<Vehicle>(vehicleIndex);
if (vehicle != nullptr)
{
return nullptr;
return vehicle->GetCar(ride->broken_car);
}
Vehicle* vehicle = GET_VEHICLE(vehicleIndex);
for (uint8_t i = 0; vehicle != nullptr && i < ride->broken_car; i++)
{
vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train);
}
return vehicle;
return nullptr;
}
/**
@ -7370,17 +7345,11 @@ void fix_invalid_vehicle_sprite_sizes()
{
for (const auto& ride : GetRideManager())
{
for (uint16_t j = 0; j <= MAX_VEHICLES_PER_RIDE; j++)
for (auto entityIndex : ride.vehicles)
{
uint16_t rideSpriteIndex = ride.vehicles[j];
while (rideSpriteIndex != SPRITE_INDEX_NULL)
for (Vehicle* vehicle = TryGetEntity<Vehicle>(entityIndex); vehicle != nullptr;
vehicle = TryGetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
Vehicle* vehicle = try_get_vehicle(rideSpriteIndex);
if (vehicle == nullptr)
{
break;
}
auto vehicleEntry = vehicle->Entry();
if (vehicleEntry == nullptr)
{
@ -7399,7 +7368,6 @@ void fix_invalid_vehicle_sprite_sizes()
{
vehicle->sprite_height_positive = vehicleEntry->sprite_height_positive;
}
rideSpriteIndex = vehicle->next_vehicle_on_train;
}
}
}

View File

@ -100,11 +100,10 @@ static void ride_update_station_dodgems(Ride* ride, StationIndex stationIndex)
int32_t dh = (dx >> 8) & 0xFF;
for (size_t i = 0; i < ride->num_vehicles; i++)
{
uint16_t vehicleSpriteIdx = ride->vehicles[i];
if (vehicleSpriteIdx == SPRITE_INDEX_NULL)
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[i]);
if (vehicle == nullptr)
continue;
Vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx);
if (vehicle->var_CE < dh)
continue;
@ -122,11 +121,10 @@ static void ride_update_station_dodgems(Ride* ride, StationIndex stationIndex)
// Check if all vehicles are ready to go
for (size_t i = 0; i < ride->num_vehicles; i++)
{
uint16_t vehicleSpriteIdx = ride->vehicles[i];
if (vehicleSpriteIdx == SPRITE_INDEX_NULL)
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[i]);
if (vehicle == nullptr)
continue;
Vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx);
if (vehicle->status != VEHICLE_STATUS_WAITING_TO_DEPART)
{
ride->stations[stationIndex].Depart &= ~STATION_DEPART_FLAG;
@ -197,11 +195,10 @@ static void ride_update_station_race(Ride* ride, StationIndex stationIndex)
for (size_t i = 0; i < ride->num_vehicles; i++)
{
uint16_t vehicleSpriteIdx = ride->vehicles[i];
if (vehicleSpriteIdx == SPRITE_INDEX_NULL)
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[i]);
if (vehicle == nullptr)
continue;
Vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx);
if (vehicle->status != VEHICLE_STATUS_WAITING_TO_DEPART && vehicle->num_laps >= numLaps)
{
// Found a winner
@ -234,11 +231,10 @@ static void ride_update_station_race(Ride* ride, StationIndex stationIndex)
// Check if all vehicles are ready to go
for (size_t i = 0; i < ride->num_vehicles; i++)
{
uint16_t vehicleSpriteIdx = ride->vehicles[i];
if (vehicleSpriteIdx == SPRITE_INDEX_NULL)
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[i]);
if (vehicle == nullptr)
continue;
Vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx);
if (vehicle->status != VEHICLE_STATUS_WAITING_TO_DEPART && vehicle->status != VEHICLE_STATUS_DEPARTING)
{
if (ride->stations[stationIndex].Depart & STATION_DEPART_FLAG)
@ -272,11 +268,10 @@ static void ride_race_init_vehicle_speeds(Ride* ride)
{
for (size_t i = 0; i < ride->num_vehicles; i++)
{
uint16_t vehicleSpriteIdx = ride->vehicles[i];
if (vehicleSpriteIdx == SPRITE_INDEX_NULL)
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[i]);
if (vehicle == nullptr)
continue;
Vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx);
vehicle->ClearUpdateFlag(VEHICLE_UPDATE_FLAG_6);
rct_ride_entry* rideEntry = vehicle->GetRideEntry();

View File

@ -864,15 +864,11 @@ namespace
}
iterator& operator++()
{
if (NextVehicleId != SPRITE_INDEX_NULL)
Current = GetEntity<Vehicle>(NextVehicleId);
if (Current != nullptr)
{
Current = GET_VEHICLE(NextVehicleId);
NextVehicleId = Current->next_vehicle_on_train;
}
else
{
Current = nullptr;
}
return *this;
}
iterator operator++(int)
@ -1337,11 +1333,14 @@ void vehicle_sounds_update()
vehicleSound->volume = tempvolume;
panVol = std::max(0, panVol - tempvolume);
Vehicle* vehicle = GET_VEHICLE(vehicleSoundParams.id);
UpdateSound<SoundType::TrackNoises>(
vehicle->sound1_id, vehicle->sound1_volume, &vehicleSoundParams, vehicleSound->TrackSound, panVol);
UpdateSound<SoundType::OtherNoises>(
vehicle->sound2_id, vehicle->sound2_volume, &vehicleSoundParams, vehicleSound->OtherSound, panVol);
Vehicle* vehicle = GetEntity<Vehicle>(vehicleSoundParams.id);
if (vehicle != nullptr)
{
UpdateSound<SoundType::TrackNoises>(
vehicle->sound1_id, vehicle->sound1_volume, &vehicleSoundParams, vehicleSound->TrackSound, panVol);
UpdateSound<SoundType::OtherNoises>(
vehicle->sound2_id, vehicle->sound2_volume, &vehicleSoundParams, vehicleSound->OtherSound, panVol);
}
}
}
@ -1375,11 +1374,9 @@ bool Vehicle::CloseRestraints()
return true;
bool restraintsClosed = true;
uint16_t vehicle_id = sprite_index;
Vehicle* vehicle = this;
do
for (Vehicle* vehicle = GetEntity<Vehicle>(sprite_index); vehicle != nullptr;
vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
vehicle = GET_VEHICLE(vehicle_id);
if (vehicle->HasUpdateFlag(VEHICLE_UPDATE_FLAG_BROKEN_CAR) && vehicle->restraints_position != 0
&& (curRide->breakdown_reason_pending == BREAKDOWN_RESTRAINTS_STUCK_OPEN
|| curRide->breakdown_reason_pending == BREAKDOWN_DOORS_STUCK_OPEN))
@ -1395,9 +1392,11 @@ bool Vehicle::CloseRestraints()
curRide->mechanic_status = RIDE_MECHANIC_STATUS_CALLING;
Vehicle* broken_vehicle = GET_VEHICLE(curRide->vehicles[curRide->broken_vehicle]);
curRide->inspection_station = broken_vehicle->current_station;
Vehicle* broken_vehicle = GetEntity<Vehicle>(curRide->vehicles[curRide->broken_vehicle]);
if (broken_vehicle != nullptr)
{
curRide->inspection_station = broken_vehicle->current_station;
}
curRide->breakdown_reason = curRide->breakdown_reason_pending;
}
}
@ -1411,7 +1410,7 @@ bool Vehicle::CloseRestraints()
}
vehicle->Invalidate();
restraintsClosed = false;
} while ((vehicle_id = vehicle->next_vehicle_on_train) != SPRITE_INDEX_NULL);
}
return restraintsClosed;
}
@ -1424,12 +1423,9 @@ bool Vehicle::CloseRestraints()
bool Vehicle::OpenRestraints()
{
int32_t restraintsOpen = true;
uint16_t vehicle_id = sprite_index;
Vehicle* vehicle = this;
do
for (Vehicle* vehicle = GetEntity<Vehicle>(sprite_index); vehicle != nullptr;
vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
vehicle = GET_VEHICLE(vehicle_id);
vehicle->SwingPosition = 0;
vehicle->SwingSpeed = 0;
vehicle->SwingSprite = 0;
@ -1505,9 +1501,11 @@ bool Vehicle::OpenRestraints()
curRide->mechanic_status = RIDE_MECHANIC_STATUS_CALLING;
Vehicle* broken_vehicle = GET_VEHICLE(curRide->vehicles[curRide->broken_vehicle]);
curRide->inspection_station = broken_vehicle->current_station;
Vehicle* broken_vehicle = GetEntity<Vehicle>(curRide->vehicles[curRide->broken_vehicle]);
if (broken_vehicle != nullptr)
{
curRide->inspection_station = broken_vehicle->current_station;
}
curRide->breakdown_reason = curRide->breakdown_reason_pending;
}
}
@ -1522,7 +1520,7 @@ bool Vehicle::OpenRestraints()
}
vehicle->Invalidate();
restraintsOpen = false;
} while ((vehicle_id = vehicle->next_vehicle_on_train) != SPRITE_INDEX_NULL);
}
return restraintsOpen;
}
@ -2289,15 +2287,12 @@ void Vehicle::UpdateWaitingForPassengers()
// 0xF64E31, 0xF64E32, 0xF64E33
uint8_t num_peeps_on_train = 0, num_used_seats_on_train = 0, num_seats_on_train = 0;
for (uint16_t sprite_id = sprite_index; sprite_id != SPRITE_INDEX_NULL;)
for (const Vehicle* trainCar = GetEntity<Vehicle>(sprite_index); trainCar != nullptr;
trainCar = GetEntity<Vehicle>(trainCar->next_vehicle_on_train))
{
Vehicle* train_vehicle = GET_VEHICLE(sprite_id);
num_peeps_on_train += train_vehicle->num_peeps;
num_used_seats_on_train += train_vehicle->next_free_seat;
num_seats_on_train += train_vehicle->num_seats;
sprite_id = train_vehicle->next_vehicle_on_train;
num_peeps_on_train += trainCar->num_peeps;
num_used_seats_on_train += trainCar->next_free_seat;
num_seats_on_train += trainCar->num_seats;
}
num_seats_on_train &= 0x7F;
@ -2344,13 +2339,12 @@ void Vehicle::UpdateWaitingForPassengers()
{
for (auto train_id : curRide->vehicles)
{
if (train_id == SPRITE_INDEX_NULL)
continue;
if (train_id == sprite_index)
continue;
Vehicle* train = GET_VEHICLE(train_id);
Vehicle* train = GetEntity<Vehicle>(train_id);
if (train == nullptr)
continue;
if (train->status == VEHICLE_STATUS_UNLOADING_PASSENGERS
|| train->status == VEHICLE_STATUS_MOVING_TO_END_OF_STATION)
@ -2505,12 +2499,10 @@ void Vehicle::UpdateWaitingToDepart()
}
else
{
uint16_t spriteId = sprite_index;
for (Vehicle* curVehicle; spriteId != SPRITE_INDEX_NULL; spriteId = curVehicle->next_vehicle_on_train)
for (const Vehicle* trainCar = GetEntity<Vehicle>(sprite_index); trainCar != nullptr;
trainCar = GetEntity<Vehicle>(trainCar->next_vehicle_on_train))
{
curVehicle = GET_VEHICLE(spriteId);
if (curVehicle->num_peeps != 0)
if (trainCar->num_peeps != 0)
{
if (!ride_get_exit_location(curRide, current_station).isNull())
{
@ -2744,13 +2736,12 @@ static bool try_add_synchronised_station(const CoordsXYZ& coords)
// Look for a vehicle on this station waiting to depart.
for (int32_t i = 0; i < ride->num_vehicles; i++)
{
uint16_t spriteIndex = ride->vehicles[i];
if (spriteIndex == SPRITE_INDEX_NULL)
auto* vehicle = GetEntity<Vehicle>(ride->vehicles[i]);
if (vehicle == nullptr)
{
continue;
}
Vehicle* vehicle = GET_VEHICLE(spriteIndex);
if (vehicle->status != VEHICLE_STATUS_WAITING_TO_DEPART)
{
continue;
@ -2768,7 +2759,7 @@ static bool try_add_synchronised_station(const CoordsXYZ& coords)
continue;
}
sv->vehicle_id = spriteIndex;
sv->vehicle_id = vehicle->sprite_index;
return true;
}
@ -2880,7 +2871,11 @@ static bool ride_station_can_depart_synchronised(const Ride& ride, StationIndex
{
for (int32_t i = 0; i < curRide->num_vehicles; i++)
{
Vehicle* v = GET_VEHICLE(curRide->vehicles[i]);
Vehicle* v = GetEntity<Vehicle>(curRide->vehicles[i]);
if (v == nullptr)
{
continue;
}
if (v->status != VEHICLE_STATUS_WAITING_TO_DEPART && v->velocity != 0)
{
// Here at least one vehicle on the ride is moving.
@ -2914,25 +2909,25 @@ static bool ride_station_can_depart_synchronised(const Ride& ride, StationIndex
auto currentStation = sv->stationIndex;
for (int32_t i = 0; i < sv_ride->num_vehicles; i++)
{
uint16_t spriteIndex = sv_ride->vehicles[i];
if (spriteIndex != SPRITE_INDEX_NULL)
auto* otherVehicle = GetEntity<Vehicle>(sv_ride->vehicles[i]);
if (otherVehicle == nullptr)
{
Vehicle* otherVehicle = GET_VEHICLE(spriteIndex);
if (otherVehicle->status != VEHICLE_STATUS_TRAVELLING)
continue;
}
if (otherVehicle->status != VEHICLE_STATUS_TRAVELLING)
{
if (currentStation == otherVehicle->current_station)
{
if (currentStation == otherVehicle->current_station)
if (otherVehicle->status == VEHICLE_STATUS_WAITING_TO_DEPART
|| otherVehicle->status == VEHICLE_STATUS_MOVING_TO_END_OF_STATION)
{
if (otherVehicle->status == VEHICLE_STATUS_WAITING_TO_DEPART
|| otherVehicle->status == VEHICLE_STATUS_MOVING_TO_END_OF_STATION)
{
numTrainsAtStation++;
}
numTrainsAtStation++;
}
}
else
{
numTravelingTrains++;
}
}
else
{
numTravelingTrains++;
}
}
@ -2961,9 +2956,9 @@ static bool ride_station_can_depart_synchronised(const Ride& ride, StationIndex
// At this point all vehicles in _snychronisedVehicles can depart.
for (rct_synchronised_vehicle* sv = _synchronisedVehicles; sv < _lastSynchronisedVehicle; sv++)
{
if (sv->vehicle_id != SPRITE_INDEX_NULL)
auto v = GetEntity<Vehicle>(sv->vehicle_id);
if (v != nullptr)
{
Vehicle* v = GET_VEHICLE(sv->vehicle_id);
v->ClearUpdateFlag(VEHICLE_UPDATE_FLAG_WAIT_ON_ADJACENT);
}
}
@ -2985,11 +2980,9 @@ bool Vehicle::CanDepartSynchronised() const
*/
void Vehicle::PeepEasterEggHereWeAre() const
{
const Vehicle* vehicle = this;
uint16_t spriteId = vehicle->sprite_index;
do
for (Vehicle* vehicle = GetEntity<Vehicle>(sprite_index); vehicle != nullptr;
vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
vehicle = GET_VEHICLE(spriteId);
for (int32_t i = 0; i < vehicle->num_peeps; ++i)
{
auto* curPeep = GetEntity<Guest>(vehicle->peep[i]);
@ -2998,7 +2991,7 @@ void Vehicle::PeepEasterEggHereWeAre() const
curPeep->InsertNewThought(PEEP_THOUGHT_TYPE_HERE_WE_ARE, curPeep->CurrentRide);
}
}
} while ((spriteId = vehicle->next_vehicle_on_train) != SPRITE_INDEX_NULL);
}
}
/**
@ -3540,10 +3533,9 @@ void Vehicle::UpdateCollisionSetup()
KillAllPassengersInTrain();
Vehicle* lastVehicle = this;
uint16_t spriteId = sprite_index;
for (Vehicle* train; spriteId != SPRITE_INDEX_NULL; spriteId = train->next_vehicle_on_train)
for (Vehicle* train = GetEntity<Vehicle>(sprite_index); train != nullptr;
train = GetEntity<Vehicle>(train->next_vehicle_on_train))
{
train = GET_VEHICLE(spriteId);
lastVehicle = train;
train->sub_state = 2;
@ -3572,8 +3564,19 @@ void Vehicle::UpdateCollisionSetup()
train->SwingSpeed = 0;
}
(GET_VEHICLE(prev_vehicle_on_ride))->next_vehicle_on_ride = lastVehicle->next_vehicle_on_ride;
(GET_VEHICLE(lastVehicle->next_vehicle_on_ride))->prev_vehicle_on_ride = prev_vehicle_on_ride;
// Remove the current train from the ride linked list of trains
auto prevTrain = GetEntity<Vehicle>(prev_vehicle_on_ride);
auto nextTrain = GetEntity<Vehicle>(lastVehicle->next_vehicle_on_ride);
if (prevTrain == nullptr || nextTrain == nullptr)
{
log_error("Corrupted vehicle list for ride!");
}
else
{
prevTrain->next_vehicle_on_ride = lastVehicle->next_vehicle_on_ride;
nextTrain->prev_vehicle_on_ride = prev_vehicle_on_ride;
}
velocity = 0;
}
@ -3608,7 +3611,11 @@ void Vehicle::UpdateCrashSetup()
uint16_t spriteId = sprite_index;
for (Vehicle* trainVehicle; spriteId != SPRITE_INDEX_NULL; spriteId = trainVehicle->next_vehicle_on_train)
{
trainVehicle = GET_VEHICLE(spriteId);
trainVehicle = GetEntity<Vehicle>(spriteId);
if (trainVehicle == nullptr)
{
break;
}
lastVehicle = trainVehicle;
trainVehicle->sub_state = 0;
@ -3638,8 +3645,18 @@ void Vehicle::UpdateCrashSetup()
trainVehicle->TrackLocation = { 0, 0, 0 };
}
(GET_VEHICLE(prev_vehicle_on_ride))->next_vehicle_on_ride = lastVehicle->next_vehicle_on_ride;
(GET_VEHICLE(lastVehicle->next_vehicle_on_ride))->prev_vehicle_on_ride = prev_vehicle_on_ride;
// Remove the current train from the ride linked list of trains
auto prevTrain = GetEntity<Vehicle>(prev_vehicle_on_ride);
auto nextTrain = GetEntity<Vehicle>(lastVehicle->next_vehicle_on_ride);
if (prevTrain == nullptr || nextTrain == nullptr)
{
log_error("Corrupted vehicle list for ride!");
}
else
{
prevTrain->next_vehicle_on_ride = lastVehicle->next_vehicle_on_ride;
nextTrain->prev_vehicle_on_ride = prev_vehicle_on_ride;
}
velocity = 0;
}
@ -4090,10 +4107,9 @@ void Vehicle::UpdateUnloadingPassengers()
return;
}
uint16_t spriteId = sprite_index;
for (Vehicle* train; spriteId != SPRITE_INDEX_NULL; spriteId = train->next_vehicle_on_train)
for (Vehicle* train = GetEntity<Vehicle>(sprite_index); train != nullptr;
train = GetEntity<Vehicle>(train->next_vehicle_on_train))
{
train = GET_VEHICLE(spriteId);
if (train->restraints_position != 255)
continue;
@ -4116,10 +4132,9 @@ void Vehicle::UpdateUnloadingPassengers()
if (sub_state != 1)
return;
uint16_t spriteId = sprite_index;
for (Vehicle* train; spriteId != SPRITE_INDEX_NULL; spriteId = train->next_vehicle_on_train)
for (Vehicle* train = GetEntity<Vehicle>(sprite_index); train != nullptr;
train = GetEntity<Vehicle>(train->next_vehicle_on_train))
{
train = GET_VEHICLE(spriteId);
if (train->num_peeps != train->next_free_seat)
return;
}
@ -4142,7 +4157,9 @@ void Vehicle::UpdateWaitingForCableLift()
if (curRide == nullptr)
return;
Vehicle* cableLift = GET_VEHICLE(curRide->cable_lift);
Vehicle* cableLift = GetEntity<Vehicle>(curRide->cable_lift);
if (cableLift == nullptr)
return;
if (cableLift->status != VEHICLE_STATUS_WAITING_FOR_PASSENGERS)
return;
@ -5203,11 +5220,10 @@ void Vehicle::KillAllPassengersInTrain()
ride_train_crash(curRide, NumPeepsUntilTrainTail());
uint16_t spriteId = sprite_index;
for (Vehicle* curVehicle; spriteId != SPRITE_INDEX_NULL; spriteId = curVehicle->next_vehicle_on_train)
for (Vehicle* trainCar = GetEntity<Vehicle>(sprite_index); trainCar != nullptr;
trainCar = GetEntity<Vehicle>(trainCar->next_vehicle_on_train))
{
curVehicle = GET_VEHICLE(spriteId);
curVehicle->KillPassengers(curRide);
trainCar->KillPassengers(curRide);
}
}
@ -5372,11 +5388,9 @@ void Vehicle::CrashOnWater()
*/
void Vehicle::UpdateCrash()
{
uint16_t spriteId = sprite_index;
Vehicle* curVehicle;
do
for (Vehicle* curVehicle = GetEntity<Vehicle>(sprite_index); curVehicle != nullptr;
curVehicle = GetEntity<Vehicle>(curVehicle->next_vehicle_on_train))
{
curVehicle = GET_VEHICLE(spriteId);
if (curVehicle->sub_state > 1)
{
if (curVehicle->crash_z <= 96)
@ -5453,7 +5467,7 @@ void Vehicle::UpdateCrash()
{
curVehicle->crash_z -= 20;
}
} while ((spriteId = curVehicle->next_vehicle_on_train) != SPRITE_INDEX_NULL);
}
}
/**
*
@ -5582,15 +5596,9 @@ SoundId Vehicle::UpdateScreamSound()
if (velocity > -0x2C000)
return SoundId::Null;
for (uint16_t spriteIndex = sprite_index; spriteIndex != SPRITE_INDEX_NULL;)
for (Vehicle* vehicle2 = GetEntity<Vehicle>(sprite_index); vehicle2 != nullptr;
vehicle2 = GetEntity<Vehicle>(vehicle2->next_vehicle_on_train))
{
auto vehicle2 = GetEntity<Vehicle>(spriteIndex);
if (vehicle2 == nullptr)
{
return SoundId::Null;
}
spriteIndex = vehicle2->next_vehicle_on_train;
if (vehicle2->vehicle_sprite_type < 1)
continue;
if (vehicle2->vehicle_sprite_type <= 4)
@ -5606,14 +5614,9 @@ SoundId Vehicle::UpdateScreamSound()
if (velocity < 0x2C000)
return SoundId::Null;
for (uint16_t spriteIndex = sprite_index; spriteIndex != SPRITE_INDEX_NULL;)
for (Vehicle* vehicle2 = GetEntity<Vehicle>(sprite_index); vehicle2 != nullptr;
vehicle2 = GetEntity<Vehicle>(vehicle2->next_vehicle_on_train))
{
auto vehicle2 = GetEntity<Vehicle>(spriteIndex);
if (vehicle2 == nullptr)
{
return SoundId::Null;
}
spriteIndex = vehicle2->next_vehicle_on_train;
if (vehicle2->vehicle_sprite_type < 5)
continue;
if (vehicle2->vehicle_sprite_type <= 8)
@ -6215,9 +6218,9 @@ Vehicle* Vehicle::TrainHead() const
for (;;)
{
if (vehicle->prev_vehicle_on_ride > MAX_SPRITES)
prevVehicle = GetEntity<Vehicle>(vehicle->prev_vehicle_on_ride);
if (prevVehicle == nullptr)
return nullptr;
prevVehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
if (prevVehicle->next_vehicle_on_train == SPRITE_INDEX_NULL)
break;
@ -6234,7 +6237,11 @@ Vehicle* Vehicle::TrainTail() const
while ((spriteIndex = vehicle->next_vehicle_on_train) != SPRITE_INDEX_NULL)
{
vehicle = GET_VEHICLE(spriteIndex);
vehicle = GetEntity<Vehicle>(spriteIndex);
if (vehicle == nullptr)
{
return const_cast<Vehicle*>(this);
}
}
return const_cast<Vehicle*>(vehicle);
@ -6362,13 +6369,13 @@ int32_t Vehicle::UpdateMotionDodgems()
velocity = 0;
uint8_t direction = sprite_direction | 1;
if (collideSprite != SPRITE_INDEX_NULL)
Vehicle* collideVehicle = GetEntity<Vehicle>(collideSprite);
if (collideVehicle != nullptr)
{
var_34 = (scenario_rand() & 1) ? 1 : -1;
if (oldVelocity >= 131072)
{
Vehicle* collideVehicle = GET_VEHICLE(collideSprite);
collideVehicle->dodgems_collision_direction = direction;
dodgems_collision_direction = direction ^ (1 << 4);
}
@ -7516,8 +7523,13 @@ void Vehicle::UpdateHandleWaterSplash() const
{
if (track_element_is_covered(trackType))
{
Vehicle* nextVehicle = GET_VEHICLE(next_vehicle_on_ride);
Vehicle* nextNextVehicle = GET_VEHICLE(nextVehicle->next_vehicle_on_ride);
Vehicle* nextVehicle = GetEntity<Vehicle>(next_vehicle_on_ride);
if (nextVehicle == nullptr)
return;
Vehicle* nextNextVehicle = GetEntity<Vehicle>(nextVehicle->next_vehicle_on_ride);
if (nextNextVehicle == nullptr)
return;
if (!track_element_is_covered(nextNextVehicle->GetTrackType()))
{
if (track_progress == 4)
@ -7589,7 +7601,9 @@ bool Vehicle::UpdateMotionCollisionDetection(const CoordsXYZ& loc, uint16_t* oth
if (otherVehicleIndex == nullptr)
return false;
Vehicle* collideVehicle = GET_VEHICLE(*otherVehicleIndex);
Vehicle* collideVehicle = GetEntity<Vehicle>(*otherVehicleIndex);
if (collideVehicle == nullptr)
return false;
if (this == collideVehicle)
return false;
@ -7763,8 +7777,12 @@ bool Vehicle::UpdateMotionCollisionDetection(const CoordsXYZ& loc, uint16_t* oth
*/
void Vehicle::ReverseReverserCar()
{
Vehicle* previousVehicle = GET_VEHICLE(prev_vehicle_on_ride);
Vehicle* nextVehicle = GET_VEHICLE(next_vehicle_on_ride);
Vehicle* previousVehicle = GetEntity<Vehicle>(prev_vehicle_on_ride);
Vehicle* nextVehicle = GetEntity<Vehicle>(next_vehicle_on_ride);
if (previousVehicle == nullptr || nextVehicle == nullptr)
{
return;
}
track_progress = 168;
vehicle_type ^= 1;
@ -8259,7 +8277,14 @@ loc_6DB967:
remaining_distance = -1;
// Might need to be bp rather than this, but hopefully not
auto head = (GET_VEHICLE(otherVehicleIndex))->TrainHead();
auto otherVeh = GetEntity<Vehicle>(otherVehicleIndex);
if (otherVeh == nullptr)
{
// This can never happen as prev_vehicle_on_ride will always be set to a vehicle
log_error("Failed to get next vehicle during update!");
return true;
}
auto head = otherVeh->TrainHead();
regs.eax = abs(velocity - head->velocity);
if (!(rideEntry->flags & RIDE_ENTRY_FLAG_DISABLE_COLLISION_CRASHES))
@ -8567,8 +8592,12 @@ loc_6DBE7F:
_vehicleVelocityF64E0C -= remaining_distance - 0x368A;
remaining_distance = 0x368A;
Vehicle* v3 = GET_VEHICLE(otherVehicleIndex);
Vehicle* v3 = GetEntity<Vehicle>(otherVehicleIndex);
Vehicle* v4 = gCurrentVehicle;
if (v3 == nullptr)
{
return false;
}
if (!(rideEntry->flags & RIDE_ENTRY_FLAG_DISABLE_COLLISION_CRASHES))
{
@ -8646,7 +8675,11 @@ loc_6DC476:
if (mini_golf_flags & (1 << 0))
{
auto vehicleIdx = IsHead() ? next_vehicle_on_ride : prev_vehicle_on_ride;
Vehicle* vEDI = GET_VEHICLE(vehicleIdx);
Vehicle* vEDI = GetEntity<Vehicle>(vehicleIdx);
if (vEDI == nullptr)
{
return;
}
if (!(vEDI->mini_golf_flags & (1 << 0)) || (vEDI->mini_golf_flags & (1 << 2)))
{
goto loc_6DC985;
@ -8662,7 +8695,11 @@ loc_6DC476:
if (mini_golf_flags & (1 << 1))
{
auto vehicleIdx = IsHead() ? next_vehicle_on_ride : prev_vehicle_on_ride;
Vehicle* vEDI = GET_VEHICLE(vehicleIdx);
Vehicle* vEDI = GetEntity<Vehicle>(vehicleIdx);
if (vEDI == nullptr)
{
return;
}
if (!(vEDI->mini_golf_flags & (1 << 1)) || (vEDI->mini_golf_flags & (1 << 2)))
{
goto loc_6DC985;
@ -8681,8 +8718,8 @@ loc_6DC476:
for (;;)
{
vEDI = GET_VEHICLE(vEDI->prev_vehicle_on_ride);
if (vEDI == this)
vEDI = GetEntity<Vehicle>(vEDI->prev_vehicle_on_ride);
if (vEDI == this || vEDI == nullptr)
{
break;
}
@ -8746,8 +8783,11 @@ loc_6DC476:
if (!IsHead())
{
Vehicle* prevVehicle = GET_VEHICLE(prev_vehicle_on_ride);
TrackSubposition = prevVehicle->TrackSubposition;
Vehicle* prevVehicle = GetEntity<Vehicle>(prev_vehicle_on_ride);
if (prevVehicle != nullptr)
{
TrackSubposition = prevVehicle->TrackSubposition;
}
if (TrackSubposition != VEHICLE_TRACK_SUBPOSITION_MINI_GOLF_START_9)
{
TrackSubposition--;
@ -9026,7 +9066,11 @@ loc_6DCD6B:
_vehicleVelocityF64E0C -= remaining_distance - 0x368A;
remaining_distance = 0x368A;
{
Vehicle* vEBP = GET_VEHICLE(otherVehicleIndex);
Vehicle* vEBP = GetEntity<Vehicle>(otherVehicleIndex);
if (vEBP == nullptr)
{
return;
}
Vehicle* vEDI = gCurrentVehicle;
if (abs(vEDI->velocity - vEBP->velocity) > 0xE0000)
{
@ -9131,7 +9175,7 @@ int32_t Vehicle::UpdateTrackMotionMiniGolf(int32_t* outStation)
_vehicleVelocityF64E0C = (velocity >> 10) * 42;
_vehicleFrontVehicle = _vehicleVelocityF64E08 < 0 ? TrainTail() : this;
for (Vehicle* vehicle = _vehicleFrontVehicle;;)
for (Vehicle* vehicle = _vehicleFrontVehicle; vehicle != nullptr;)
{
vehicle->UpdateTrackMotionMiniGolfVehicle(curRide, rideEntry, vehicleEntry);
if (vehicle->HasUpdateFlag(VEHICLE_UPDATE_FLAG_ON_LIFT_HILL))
@ -9140,11 +9184,7 @@ int32_t Vehicle::UpdateTrackMotionMiniGolf(int32_t* outStation)
}
if (_vehicleVelocityF64E08 >= 0)
{
if (vehicle->next_vehicle_on_train == SPRITE_INDEX_NULL)
{
break;
}
vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train);
vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train);
}
else
{
@ -9152,7 +9192,7 @@ int32_t Vehicle::UpdateTrackMotionMiniGolf(int32_t* outStation)
{
break;
}
vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
vehicle = GetEntity<Vehicle>(vehicle->prev_vehicle_on_ride);
}
}
@ -9160,17 +9200,11 @@ int32_t Vehicle::UpdateTrackMotionMiniGolf(int32_t* outStation)
int32_t numVehicles = 0;
uint16_t totalMass = 0;
for (Vehicle* vehicle = this;;)
for (Vehicle* vehicle = this; vehicle != nullptr; vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
numVehicles++;
totalMass += vehicle->mass;
sumAcceleration += vehicle->acceleration;
auto nextVehicleIndex = vehicle->next_vehicle_on_train;
if (nextVehicleIndex == SPRITE_INDEX_NULL)
{
break;
}
vehicle = GET_VEHICLE(nextVehicleIndex);
}
int32_t newAcceleration = ((sumAcceleration / numVehicles) * 21) >> 9;
@ -9393,7 +9427,11 @@ int32_t Vehicle::UpdateTrackMotion(int32_t* outStation)
uint16_t spriteId = vehicle->sprite_index;
while (spriteId != SPRITE_INDEX_NULL)
{
Vehicle* car = GET_VEHICLE(spriteId);
Vehicle* car = GetEntity<Vehicle>(spriteId);
if (car == nullptr)
{
break;
}
vehicleEntry = car->Entry();
if (vehicleEntry == nullptr)
{
@ -9507,20 +9545,13 @@ int32_t Vehicle::UpdateTrackMotion(int32_t* outStation)
// ebx
int32_t numVehicles = 0;
for (;;)
for (; vehicle != nullptr; vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
numVehicles++;
// Not used?
regs.dx |= vehicle->update_flags;
totalMass += vehicle->mass;
totalAcceleration += vehicle->acceleration;
uint16_t spriteIndex = vehicle->next_vehicle_on_train;
if (spriteIndex == SPRITE_INDEX_NULL)
{
break;
}
vehicle = GET_VEHICLE(spriteIndex);
}
vehicle = gCurrentVehicle;
@ -9614,14 +9645,9 @@ Ride* Vehicle::GetRide() const
int32_t Vehicle::NumPeepsUntilTrainTail() const
{
int32_t numPeeps = 0;
for (uint16_t spriteIndex = sprite_index; spriteIndex != SPRITE_INDEX_NULL;)
for (const Vehicle* vehicle = GetEntity<Vehicle>(sprite_index); vehicle != nullptr;
vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{
const Vehicle* vehicle = GetEntity<Vehicle>(spriteIndex);
if (vehicle == nullptr)
{
return numPeeps;
}
spriteIndex = vehicle->next_vehicle_on_train;
numPeeps += vehicle->num_peeps;
}
@ -9785,7 +9811,7 @@ Vehicle* Vehicle::GetHead()
auto v = this;
while (v != nullptr && !v->IsHead())
{
v = GET_VEHICLE(v->prev_vehicle_on_ride);
v = GetEntity<Vehicle>(v->prev_vehicle_on_ride);
}
return v;
}
@ -9795,12 +9821,17 @@ const Vehicle* Vehicle::GetHead() const
return (const_cast<Vehicle*>(this)->GetHead());
}
const Vehicle* Vehicle::GetCar(size_t carIndex) const
Vehicle* Vehicle::GetCar(size_t carIndex) const
{
auto car = this;
auto car = const_cast<Vehicle*>(this);
for (; carIndex != 0; carIndex--)
{
car = GET_VEHICLE(car->next_vehicle_on_train);
car = GetEntity<Vehicle>(car->next_vehicle_on_train);
if (car == nullptr)
{
log_error("Tried to get non-existant car from index!");
return nullptr;
}
}
return car;
}

View File

@ -319,7 +319,7 @@ struct Vehicle : SpriteBase
void Update();
Vehicle* GetHead();
const Vehicle* GetHead() const;
const Vehicle* GetCar(size_t carIndex) const;
Vehicle* GetCar(size_t carIndex) const;
void Invalidate();
void SetState(VEHICLE_STATUS vehicleStatus, uint8_t subState = 0);
bool IsGhost() const;
@ -635,7 +635,4 @@ extern uint8_t _vehicleF64E2C;
extern Vehicle* _vehicleFrontVehicle;
extern CoordsXYZ unk_F64E20;
/** Helper macro until rides are stored in this module. */
#define GET_VEHICLE(sprite_index) &(get_sprite(sprite_index)->vehicle)
#endif

View File

@ -3037,7 +3037,11 @@ static void vehicle_visual_splash3_effect(paint_session* session, int32_t z, con
*/
static void vehicle_visual_splash4_effect(paint_session* session, int32_t z, const Vehicle* vehicle)
{
Vehicle* vehicle2 = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
Vehicle* vehicle2 = GetEntity<Vehicle>(vehicle->prev_vehicle_on_ride);
if (vehicle2 == nullptr)
{
return;
}
if (vehicle2->velocity <= 0x50000)
{
return;
@ -3061,7 +3065,11 @@ static void vehicle_visual_splash4_effect(paint_session* session, int32_t z, con
*/
static void vehicle_visual_splash5_effect(paint_session* session, int32_t z, const Vehicle* vehicle)
{
Vehicle* vehicle2 = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
Vehicle* vehicle2 = GetEntity<Vehicle>(vehicle->prev_vehicle_on_ride);
if (vehicle2 == nullptr)
{
return;
}
if (vehicle2->velocity <= 0x50000)
{
return;

View File

@ -29,8 +29,12 @@ void vehicle_visual_reverser(
paint_session* session, int32_t x, int32_t imageDirection, int32_t y, int32_t z, const Vehicle* vehicle,
const rct_ride_entry_vehicle* vehicleEntry)
{
Vehicle* v1 = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
Vehicle* v2 = GET_VEHICLE(vehicle->next_vehicle_on_ride);
Vehicle* v1 = GetEntity<Vehicle>(vehicle->prev_vehicle_on_ride);
Vehicle* v2 = GetEntity<Vehicle>(vehicle->next_vehicle_on_ride);
if (v1 == nullptr || v2 == nullptr)
{
return;
}
x = (v1->x + v2->x) / 2;
y = (v1->y + v2->y) / 2;
z = (v1->z + v2->z) / 2;

View File

@ -30,10 +30,11 @@ static void paint_circus_tent(
if (rideEntry == nullptr)
return;
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL)
auto vehicle = GetEntity<Vehicle>(ride->vehicles[0]);
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && vehicle != nullptr)
{
session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE;
session->CurrentlyDrawnItem = GET_VEHICLE(ride->vehicles[0]);
session->CurrentlyDrawnItem = vehicle;
}
uint32_t imageColourFlags = session->TrackColours[SCHEME_MISC];

View File

@ -62,7 +62,6 @@ static void paint_ferris_wheel_structure(
if (rideEntry == nullptr)
return;
Vehicle* vehicle = nullptr;
int8_t xOffset = !(direction & 1) ? axisOffset : 0;
int8_t yOffset = (direction & 1) ? axisOffset : 0;
@ -70,10 +69,9 @@ static void paint_ferris_wheel_structure(
baseImageId = rideEntry->vehicles[0].base_image_id;
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL)
auto vehicle = GetEntity<Vehicle>(ride->vehicles[0]);
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && vehicle != nullptr)
{
vehicle = GET_VEHICLE(ride->vehicles[0]);
session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE;
session->CurrentlyDrawnItem = vehicle;
}
@ -102,9 +100,8 @@ static void paint_ferris_wheel_structure(
session, imageId, xOffset, yOffset, boundBox.length_x, boundBox.length_y, 127, height, boundBox.offset_x,
boundBox.offset_y, height);
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL)
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && vehicle != nullptr)
{
vehicle = GET_VEHICLE(ride->vehicles[0]);
for (int32_t i = 0; i < 32; i += 2)
{
if (vehicle->peep[i] == SPRITE_INDEX_NULL)

View File

@ -48,10 +48,10 @@ static void paint_haunted_house_structure(
uint32_t baseImageId = rideEntry->vehicles[0].base_image_id;
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL)
auto vehicle = GetEntity<Vehicle>(ride->vehicles[0]);
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && vehicle != nullptr)
{
session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE;
Vehicle* vehicle = GET_VEHICLE(ride->vehicles[0]);
session->CurrentlyDrawnItem = vehicle;
frameNum = vehicle->vehicle_sprite_type;
}

View File

@ -37,13 +37,11 @@ static void paint_merry_go_round_structure(
if (rideEntry == nullptr)
return;
Vehicle* vehicle = nullptr;
uint32_t baseImageId = rideEntry->vehicles[0].base_image_id;
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL)
auto vehicle = GetEntity<Vehicle>(ride->vehicles[0]);
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && vehicle != nullptr)
{
session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE;
vehicle = GET_VEHICLE(ride->vehicles[0]);
session->CurrentlyDrawnItem = vehicle;
if (ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN)

View File

@ -40,16 +40,14 @@ static void paint_space_rings_structure(paint_session* session, Ride* ride, uint
if (ride->num_stations == 0 || vehicleIndex < ride->num_vehicles)
{
rct_ride_entry* rideEntry = get_ride_entry(ride->subtype);
Vehicle* vehicle = nullptr;
int32_t frameNum = direction;
uint32_t baseImageId = rideEntry->vehicles[0].base_image_id;
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL)
auto vehicle = GetEntity<Vehicle>(ride->vehicles[0]);
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && vehicle != nullptr)
{
session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE;
vehicle = GET_VEHICLE(ride->vehicles[vehicleIndex]);
session->CurrentlyDrawnItem = vehicle;
frameNum += static_cast<int8_t>(vehicle->vehicle_sprite_type) * 4;
}

View File

@ -33,7 +33,7 @@ static void paint_3d_cinema_structure(
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL)
{
session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE;
session->CurrentlyDrawnItem = GET_VEHICLE(ride->vehicles[0]);
session->CurrentlyDrawnItem = GetEntity<Vehicle>(ride->vehicles[0]);
}
uint32_t imageColourFlags = session->TrackColours[SCHEME_MISC];

View File

@ -35,7 +35,7 @@ static void paint_enterprise_structure(
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL)
{
session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE;
vehicle = GET_VEHICLE(ride->vehicles[0]);
vehicle = GetEntity<Vehicle>(ride->vehicles[0]);
session->CurrentlyDrawnItem = vehicle;
}

View File

@ -61,7 +61,7 @@ static Vehicle* get_first_vehicle(Ride* ride)
uint16_t vehicleSpriteIndex = ride->vehicles[0];
if (vehicleSpriteIndex != SPRITE_INDEX_NULL)
{
return GET_VEHICLE(vehicleSpriteIndex);
return GetEntity<Vehicle>(vehicleSpriteIndex);
}
}
return nullptr;

View File

@ -49,7 +49,7 @@ static void paint_motionsimulator_vehicle(
uint16_t spriteIndex = ride->vehicles[0];
if (spriteIndex != SPRITE_INDEX_NULL)
{
vehicle = GET_VEHICLE(spriteIndex);
vehicle = GetEntity<Vehicle>(spriteIndex);
session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE;
session->CurrentlyDrawnItem = vehicle;
}

View File

@ -59,7 +59,7 @@ static void paint_swinging_inverter_ship_structure(
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL)
{
vehicle = GET_VEHICLE(ride->vehicles[0]);
vehicle = GetEntity<Vehicle>(ride->vehicles[0]);
session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE;
session->CurrentlyDrawnItem = vehicle;

View File

@ -72,7 +72,7 @@ static void paint_swinging_ship_structure(
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL)
{
vehicle = GET_VEHICLE(ride->vehicles[0]);
vehicle = GetEntity<Vehicle>(ride->vehicles[0]);
session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE;
session->CurrentlyDrawnItem = vehicle;

View File

@ -57,15 +57,12 @@ static void top_spin_paint_vehicle(
height += 3;
rct_ride_entry* rideEntry = get_ride_entry(ride->subtype);
Vehicle* vehicle = nullptr;
uint8_t seatRotation = 0;
int8_t armRotation = 0;
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL)
Vehicle* vehicle = GetEntity<Vehicle>(ride->vehicles[0]);
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && vehicle != nullptr)
{
vehicle = GET_VEHICLE(ride->vehicles[0]);
session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE;
session->CurrentlyDrawnItem = vehicle;

View File

@ -34,7 +34,7 @@ static void paint_twist_structure(
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK && ride->vehicles[0] != SPRITE_INDEX_NULL)
{
vehicle = GET_VEHICLE(ride->vehicles[0]);
vehicle = GetEntity<Vehicle>(ride->vehicles[0]);
session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE;
session->CurrentlyDrawnItem = vehicle;

View File

@ -1252,11 +1252,15 @@ void vehicle_visual_splash_boats_or_water_coaster(
{
if (vehicle->IsHead())
{
vehicle = GET_VEHICLE(vehicle->next_vehicle_on_ride);
vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_ride);
}
else
{
vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
vehicle = GetEntity<Vehicle>(vehicle->prev_vehicle_on_ride);
}
if (vehicle == nullptr)
{
return;
}
session->CurrentlyDrawnItem = vehicle;
imageDirection = ((session->CurrentRotation * 8) + vehicle->sprite_direction) & 0x1F;

View File

@ -162,6 +162,11 @@ template<> bool SpriteBase::Is<Guest>() const
return peep && peep->AssignedPeepType == PeepType::Guest;
}
template<> bool SpriteBase::Is<Vehicle>() const
{
return sprite_identifier == SPRITE_IDENTIFIER_VEHICLE;
}
rct_sprite* get_sprite(size_t sprite_idx)
{
assert(sprite_idx < MAX_SPRITES);