diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index 977cf7841d..1087359f24 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -1093,11 +1093,8 @@ static void window_map_paint_train_overlay(rct_drawpixelinfo* dpi) { for (auto train : EntityList(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->next_vehicle_on_train)) { - vehicle = GET_VEHICLE(vehicle_index); if (vehicle->x == LOCATION_NULL) continue; diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 4fc0eba8f5..069b68b930 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -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(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(ride->vehicles[i]); vehicle != nullptr; + vehicle = GetEntity(vehicle->next_vehicle_on_train)) { - vehicle = GetEntity(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; diff --git a/src/openrct2-ui/windows/TitleCommandEditor.cpp b/src/openrct2-ui/windows/TitleCommandEditor.cpp index e94fadfd15..cc318866ff 100644 --- a/src/openrct2-ui/windows/TitleCommandEditor.cpp +++ b/src/openrct2-ui/windows/TitleCommandEditor.cpp @@ -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(spriteIndex); if (vehicle != nullptr) { auto ride = vehicle->GetRide(); diff --git a/src/openrct2/actions/SetCheatAction.hpp b/src/openrct2/actions/SetCheatAction.hpp index 4ac2457010..297597c690 100644 --- a/src/openrct2/actions/SetCheatAction.hpp +++ b/src/openrct2/actions/SetCheatAction.hpp @@ -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(trainIndex); vehicle != nullptr; + vehicle = TryGetEntity(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(vehicle->peep[i + offset]); + auto peep = TryGetEntity(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; } } } diff --git a/src/openrct2/drawing/LightFX.cpp b/src/openrct2/drawing/LightFX.cpp index a3897a3197..6761ebaf14 100644 --- a/src/openrct2/drawing/LightFX.cpp +++ b/src/openrct2/drawing/LightFX.cpp @@ -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_draw->next_vehicle_on_train); + if (nextVeh != nullptr) + { + vehicle_draw = nextVeh; + } } place_x = vehicle_draw->x; place_y = vehicle_draw->y; diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 9c4489c2c8..b2c7e425a1 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -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(ride->vehicles[i]); vehicle != nullptr; + vehicle = GetEntity(vehicle->next_vehicle_on_train)) { - Vehicle* vehicle = GET_VEHICLE(vehicle_index); vehicle->mass = mass; - vehicle_index = vehicle->next_vehicle_on_train; } } } diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 8c112829bc..917f356321 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -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(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; diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 9a8370974e..7a5d510a69 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -2487,14 +2487,12 @@ static Vehicle* peep_choose_car_from_ride(Peep* peep, Ride* ride, std::vectorCurrentCar = car_array[chosen_car]; - Vehicle* vehicle = GET_VEHICLE(ride->vehicles[peep->CurrentTrain]); - - for (int32_t i = peep->CurrentCar; i > 0; --i) + Vehicle* vehicle = GetEntity(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::vectornext_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& car_array) for (int32_t i = 0; i < ride->num_vehicles; ++i) { - Vehicle* vehicle = GET_VEHICLE(ride->vehicles[i]); + Vehicle* vehicle = GetEntity(ride->vehicles[i]); if (vehicle == nullptr) continue; @@ -2606,12 +2608,9 @@ bool Guest::FindVehicleToEnter(Ride* ride, std::vector& 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_id); vehicle != nullptr; + vehicle = GetEntity(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(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(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(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(ride->vehicles[i]); + if (train == nullptr) + continue; + + Vehicle* second_vehicle = GetEntity(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(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(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(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->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(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(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(ride->vehicles[CurrentTrain]); + if (vehicle == nullptr) + { + return; + } CoordsXY targetLoc = ride->stations[CurrentRideStation].Start.ToTileCentre(); if (ride->type == RIDE_TYPE_ENTERPRISE) diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 9e8e2b420a..766b30d8d4 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -2193,7 +2193,11 @@ bool Staff::UpdateFixingMoveToBrokenDownVehicle(bool firstRun, Ride* ride) break; } - vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride); + vehicle = GetEntity(vehicle->prev_vehicle_on_ride); + if (vehicle == nullptr) + { + return true; + } } CoordsXY offset = DirectionOffsets[PeepDirection]; diff --git a/src/openrct2/ride/CableLift.cpp b/src/openrct2/ride/CableLift.cpp index a60c4266d9..b3a30c0fea 100644 --- a/src/openrct2/ride/CableLift.cpp +++ b/src/openrct2/ride/CableLift.cpp @@ -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(cable_lift_target); + Vehicle* cableLiftSecondPart = GetEntity(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(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(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->next_vehicle_on_train); } else { if (vehicle == this) break; - vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride); + vehicle = GetEntity(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(sprite_index); vehicle != nullptr; + vehicle = GetEntity(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; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 35c9893d4d..78b3671501 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -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(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(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(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(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(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(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(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->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(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(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(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(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(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(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(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(ride->vehicles[i]); vehicle != nullptr; + vehicle = GetEntity(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(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(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(entityIndex); vehicle != nullptr; + vehicle = TryGetEntity(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; } } } diff --git a/src/openrct2/ride/Station.cpp b/src/openrct2/ride/Station.cpp index fb45609475..52ac8fb150 100644 --- a/src/openrct2/ride/Station.cpp +++ b/src/openrct2/ride/Station.cpp @@ -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(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(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(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(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(ride->vehicles[i]); + if (vehicle == nullptr) continue; - Vehicle* vehicle = GET_VEHICLE(vehicleSpriteIdx); vehicle->ClearUpdateFlag(VEHICLE_UPDATE_FLAG_6); rct_ride_entry* rideEntry = vehicle->GetRideEntry(); diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index b75bdb1e83..ef5d44403f 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -864,15 +864,11 @@ namespace } iterator& operator++() { - if (NextVehicleId != SPRITE_INDEX_NULL) + Current = GetEntity(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( - vehicle->sound1_id, vehicle->sound1_volume, &vehicleSoundParams, vehicleSound->TrackSound, panVol); - UpdateSound( - vehicle->sound2_id, vehicle->sound2_volume, &vehicleSoundParams, vehicleSound->OtherSound, panVol); + Vehicle* vehicle = GetEntity(vehicleSoundParams.id); + if (vehicle != nullptr) + { + UpdateSound( + vehicle->sound1_id, vehicle->sound1_volume, &vehicleSoundParams, vehicleSound->TrackSound, panVol); + UpdateSound( + 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(sprite_index); vehicle != nullptr; + vehicle = GetEntity(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(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(sprite_index); vehicle != nullptr; + vehicle = GetEntity(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(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(sprite_index); trainCar != nullptr; + trainCar = GetEntity(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(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(sprite_index); trainCar != nullptr; + trainCar = GetEntity(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(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(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(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(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(sprite_index); vehicle != nullptr; + vehicle = GetEntity(vehicle->next_vehicle_on_train)) { - vehicle = GET_VEHICLE(spriteId); for (int32_t i = 0; i < vehicle->num_peeps; ++i) { auto* curPeep = GetEntity(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(sprite_index); train != nullptr; + train = GetEntity(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(prev_vehicle_on_ride); + auto nextTrain = GetEntity(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(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(prev_vehicle_on_ride); + auto nextTrain = GetEntity(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(sprite_index); train != nullptr; + train = GetEntity(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(sprite_index); train != nullptr; + train = GetEntity(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(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(sprite_index); trainCar != nullptr; + trainCar = GetEntity(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(sprite_index); curVehicle != nullptr; + curVehicle = GetEntity(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(sprite_index); vehicle2 != nullptr; + vehicle2 = GetEntity(vehicle2->next_vehicle_on_train)) { - auto vehicle2 = GetEntity(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(sprite_index); vehicle2 != nullptr; + vehicle2 = GetEntity(vehicle2->next_vehicle_on_train)) { - auto vehicle2 = GetEntity(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->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(spriteIndex); + if (vehicle == nullptr) + { + return const_cast(this); + } } return const_cast(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(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(next_vehicle_on_ride); + if (nextVehicle == nullptr) + return; + + Vehicle* nextNextVehicle = GetEntity(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(*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(prev_vehicle_on_ride); + Vehicle* nextVehicle = GetEntity(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(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(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(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(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(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(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(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->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->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->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(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->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(sprite_index); vehicle != nullptr; + vehicle = GetEntity(vehicle->next_vehicle_on_train)) { - const Vehicle* vehicle = GetEntity(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(v->prev_vehicle_on_ride); } return v; } @@ -9795,12 +9821,17 @@ const Vehicle* Vehicle::GetHead() const return (const_cast(this)->GetHead()); } -const Vehicle* Vehicle::GetCar(size_t carIndex) const +Vehicle* Vehicle::GetCar(size_t carIndex) const { - auto car = this; + auto car = const_cast(this); for (; carIndex != 0; carIndex--) { - car = GET_VEHICLE(car->next_vehicle_on_train); + car = GetEntity(car->next_vehicle_on_train); + if (car == nullptr) + { + log_error("Tried to get non-existant car from index!"); + return nullptr; + } } return car; } diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index b6ef61599e..9cd40148fe 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -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 diff --git a/src/openrct2/ride/VehiclePaint.cpp b/src/openrct2/ride/VehiclePaint.cpp index 13e498ef7f..d8be09bc5b 100644 --- a/src/openrct2/ride/VehiclePaint.cpp +++ b/src/openrct2/ride/VehiclePaint.cpp @@ -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->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->prev_vehicle_on_ride); + if (vehicle2 == nullptr) + { + return; + } if (vehicle2->velocity <= 0x50000) { return; diff --git a/src/openrct2/ride/coaster/ReverserRollerCoaster.cpp b/src/openrct2/ride/coaster/ReverserRollerCoaster.cpp index bee1143d26..57a9cbca90 100644 --- a/src/openrct2/ride/coaster/ReverserRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/ReverserRollerCoaster.cpp @@ -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->prev_vehicle_on_ride); + Vehicle* v2 = GetEntity(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; diff --git a/src/openrct2/ride/gentle/Circus.cpp b/src/openrct2/ride/gentle/Circus.cpp index 40d03b831f..6085105d09 100644 --- a/src/openrct2/ride/gentle/Circus.cpp +++ b/src/openrct2/ride/gentle/Circus.cpp @@ -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(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]; diff --git a/src/openrct2/ride/gentle/FerrisWheel.cpp b/src/openrct2/ride/gentle/FerrisWheel.cpp index 52974c0e3b..067af7a66b 100644 --- a/src/openrct2/ride/gentle/FerrisWheel.cpp +++ b/src/openrct2/ride/gentle/FerrisWheel.cpp @@ -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(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) diff --git a/src/openrct2/ride/gentle/HauntedHouse.cpp b/src/openrct2/ride/gentle/HauntedHouse.cpp index 74fc6673a8..6b6b804206 100644 --- a/src/openrct2/ride/gentle/HauntedHouse.cpp +++ b/src/openrct2/ride/gentle/HauntedHouse.cpp @@ -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(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; } diff --git a/src/openrct2/ride/gentle/MerryGoRound.cpp b/src/openrct2/ride/gentle/MerryGoRound.cpp index 9c731b6002..9b9629dd2c 100644 --- a/src/openrct2/ride/gentle/MerryGoRound.cpp +++ b/src/openrct2/ride/gentle/MerryGoRound.cpp @@ -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(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) diff --git a/src/openrct2/ride/gentle/SpaceRings.cpp b/src/openrct2/ride/gentle/SpaceRings.cpp index 7dda8064f8..75d4c56a3c 100644 --- a/src/openrct2/ride/gentle/SpaceRings.cpp +++ b/src/openrct2/ride/gentle/SpaceRings.cpp @@ -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(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(vehicle->vehicle_sprite_type) * 4; } diff --git a/src/openrct2/ride/thrill/3dCinema.cpp b/src/openrct2/ride/thrill/3dCinema.cpp index 7dc7f4125a..c46d6cd23a 100644 --- a/src/openrct2/ride/thrill/3dCinema.cpp +++ b/src/openrct2/ride/thrill/3dCinema.cpp @@ -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(ride->vehicles[0]); } uint32_t imageColourFlags = session->TrackColours[SCHEME_MISC]; diff --git a/src/openrct2/ride/thrill/Enterprise.cpp b/src/openrct2/ride/thrill/Enterprise.cpp index d58a18f7b1..80ff9efa4b 100644 --- a/src/openrct2/ride/thrill/Enterprise.cpp +++ b/src/openrct2/ride/thrill/Enterprise.cpp @@ -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(ride->vehicles[0]); session->CurrentlyDrawnItem = vehicle; } diff --git a/src/openrct2/ride/thrill/MagicCarpet.cpp b/src/openrct2/ride/thrill/MagicCarpet.cpp index 016ce5f496..d19bad0629 100644 --- a/src/openrct2/ride/thrill/MagicCarpet.cpp +++ b/src/openrct2/ride/thrill/MagicCarpet.cpp @@ -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(vehicleSpriteIndex); } } return nullptr; diff --git a/src/openrct2/ride/thrill/MotionSimulator.cpp b/src/openrct2/ride/thrill/MotionSimulator.cpp index b6b6044ba7..d16eaaca78 100644 --- a/src/openrct2/ride/thrill/MotionSimulator.cpp +++ b/src/openrct2/ride/thrill/MotionSimulator.cpp @@ -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(spriteIndex); session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE; session->CurrentlyDrawnItem = vehicle; } diff --git a/src/openrct2/ride/thrill/SwingingInverterShip.cpp b/src/openrct2/ride/thrill/SwingingInverterShip.cpp index a552e27f33..1c25fb4d3f 100644 --- a/src/openrct2/ride/thrill/SwingingInverterShip.cpp +++ b/src/openrct2/ride/thrill/SwingingInverterShip.cpp @@ -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(ride->vehicles[0]); session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE; session->CurrentlyDrawnItem = vehicle; diff --git a/src/openrct2/ride/thrill/SwingingShip.cpp b/src/openrct2/ride/thrill/SwingingShip.cpp index fa1aeb8e50..dad6a69ec0 100644 --- a/src/openrct2/ride/thrill/SwingingShip.cpp +++ b/src/openrct2/ride/thrill/SwingingShip.cpp @@ -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(ride->vehicles[0]); session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE; session->CurrentlyDrawnItem = vehicle; diff --git a/src/openrct2/ride/thrill/TopSpin.cpp b/src/openrct2/ride/thrill/TopSpin.cpp index a1ee77828e..aeb56bb1bc 100644 --- a/src/openrct2/ride/thrill/TopSpin.cpp +++ b/src/openrct2/ride/thrill/TopSpin.cpp @@ -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(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; diff --git a/src/openrct2/ride/thrill/Twist.cpp b/src/openrct2/ride/thrill/Twist.cpp index 512a0e6744..08edadc8b7 100644 --- a/src/openrct2/ride/thrill/Twist.cpp +++ b/src/openrct2/ride/thrill/Twist.cpp @@ -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(ride->vehicles[0]); session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE; session->CurrentlyDrawnItem = vehicle; diff --git a/src/openrct2/ride/water/SplashBoats.cpp b/src/openrct2/ride/water/SplashBoats.cpp index d3c693fe7d..4c3bbdc901 100644 --- a/src/openrct2/ride/water/SplashBoats.cpp +++ b/src/openrct2/ride/water/SplashBoats.cpp @@ -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->next_vehicle_on_ride); } else { - vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride); + vehicle = GetEntity(vehicle->prev_vehicle_on_ride); + } + if (vehicle == nullptr) + { + return; } session->CurrentlyDrawnItem = vehicle; imageDirection = ((session->CurrentRotation * 8) + vehicle->sprite_direction) & 0x1F; diff --git a/test/testpaint/Compat.cpp b/test/testpaint/Compat.cpp index c290b2665e..1efcc344b0 100644 --- a/test/testpaint/Compat.cpp +++ b/test/testpaint/Compat.cpp @@ -162,6 +162,11 @@ template<> bool SpriteBase::Is() const return peep && peep->AssignedPeepType == PeepType::Guest; } +template<> bool SpriteBase::Is() const +{ + return sprite_identifier == SPRITE_IDENTIFIER_VEHICLE; +} + rct_sprite* get_sprite(size_t sprite_idx) { assert(sprite_idx < MAX_SPRITES);