diff --git a/src/openrct2/ParkFile.cpp b/src/openrct2/ParkFile.cpp index b6200b53b8..62d5b1c108 100644 --- a/src/openrct2/ParkFile.cpp +++ b/src/openrct2/ParkFile.cpp @@ -93,6 +93,7 @@ namespace OpenRCT2 public: ObjectList RequiredObjects; std::vector ExportObjectsList; + bool OmitTracklessRides{}; private: std::unique_ptr _os; @@ -839,7 +840,7 @@ namespace OpenRCT2 void ReadWriteRidesChunk(OrcaStream& os) { - os.ReadWriteChunk(ParkFileChunkType::RIDES, [](OrcaStream::ChunkStream& cs) { + os.ReadWriteChunk(ParkFileChunkType::RIDES, [this](OrcaStream::ChunkStream& cs) { std::vector rideIds; if (cs.GetMode() == OrcaStream::Mode::READING) { @@ -847,9 +848,24 @@ namespace OpenRCT2 } else { - for (const auto& ride : GetRideManager()) + if (OmitTracklessRides) { - rideIds.push_back(ride.id); + auto tracklessRides = GetTracklessRides(); + for (const auto& ride : GetRideManager()) + { + auto it = std::find(tracklessRides.begin(), tracklessRides.end(), ride.id); + if (it == tracklessRides.end()) + { + rideIds.push_back(ride.id); + } + } + } + else + { + for (const auto& ride : GetRideManager()) + { + rideIds.push_back(ride.id); + } } } cs.ReadWriteVector(rideIds, [&cs](ride_id_t& rideId) { @@ -1614,8 +1630,7 @@ int32_t scenario_save(const utf8* path, int32_t flags) auto& objManager = OpenRCT2::GetContext()->GetObjectManager(); parkFile->ExportObjectsList = objManager.GetPackableObjects(); } - // s6exporter->RemoveTracklessRides = true; - // s6exporter->Export(); + parkFile->OmitTracklessRides = true; if (flags & S6_SAVE_FLAG_SCENARIO) { // s6exporter->SaveScenario(path); diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 887dd2f9c1..2caa30f4e9 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -7362,3 +7362,37 @@ void Ride::IncreaseNumShelteredSections() num_sheltered_sections &= ~ShelteredSectionsBits::NumShelteredSectionsMask; num_sheltered_sections |= newNumShelteredSections; } + +std::vector GetTracklessRides() +{ + // Iterate map and build list of seen ride IDs + std::vector seen; + seen.resize(256); + tile_element_iterator it; + tile_element_iterator_begin(&it); + while (tile_element_iterator_next(&it)) + { + auto trackEl = it.element->AsTrack(); + if (trackEl != nullptr && !trackEl->IsGhost()) + { + auto rideId = trackEl->GetRideIndex(); + if (rideId >= seen.size()) + { + seen.resize(rideId + 1); + } + seen[rideId] = true; + } + } + + // Get all rides that did not get seen during map iteration + const auto& rideManager = GetRideManager(); + std::vector result; + for (const auto& ride : rideManager) + { + if (seen.size() <= ride.id || !seen[ride.id]) + { + result.push_back(ride.id); + } + } + return result; +} diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index ba5b2d82e3..99bc30bb89 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -1251,4 +1251,6 @@ void ride_action_modify(Ride* ride, int32_t modifyType, int32_t flags); void determine_ride_entrance_and_exit_locations(); void ride_clear_leftover_entrances(Ride* ride); +std::vector GetTracklessRides(); + #endif diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index 006b921456..3de5f286be 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -666,41 +666,6 @@ void scenario_fix_ghosts(rct_s6_data* s6) } } -static void ride_all_has_any_track_elements(std::array& rideIndexArray) -{ - tile_element_iterator it; - tile_element_iterator_begin(&it); - while (tile_element_iterator_next(&it)) - { - if (it.element->GetType() != TILE_ELEMENT_TYPE_TRACK) - continue; - if (it.element->IsGhost()) - continue; - - rideIndexArray[it.element->AsTrack()->GetRideIndex()] = true; - } -} - -void scenario_remove_trackless_rides(rct_s6_data* s6) -{ - std::array rideHasTrack{}; - ride_all_has_any_track_elements(rideHasTrack); - for (int32_t i = 0; i < RCT12_MAX_RIDES_IN_PARK; i++) - { - auto ride = &s6->rides[i]; - if (rideHasTrack[i] || ride->type == RIDE_TYPE_NULL) - { - continue; - } - - ride->type = RIDE_TYPE_NULL; - if (is_user_string_id(ride->name)) - { - s6->custom_strings[(ride->name % RCT12_MAX_USER_STRINGS)][0] = 0; - } - } -} - ObjectiveStatus Objective::CheckGuestsBy() const { int16_t parkRating = gParkRating;