From a9afe3253ca602c7b005ffead2b2a88624e45efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sat, 10 Feb 2018 20:24:50 +0100 Subject: [PATCH] Fix #7160: Crash when trying to play the Dynamite Dunes scenario The fix shouldn't modify guests that don't have any ride set. This also fixes how peeps get removed and adds name of the offending guest in the warning message. --- src/openrct2/Game.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index d61526cab9..c744ce23a7 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1211,19 +1211,30 @@ void game_fix_save_vars() peep_sort(); + // Peeps to remove have to be cached here, as removing them from within the loop breaks iteration + std::vector peepsToRemove; + // Fix possibly invalid field values FOR_ALL_GUESTS(spriteIndex, peep) { if (peep->current_ride_station >= MAX_STATIONS) { const uint8 srcStation = peep->current_ride_station; - const uint8 ride = peep->current_ride; - log_warning("Peep %u has invalid ride station = %u for ride %u.", spriteIndex, srcStation, ride); - sint8 station = ride_get_first_valid_station_exit(get_ride(ride)); + const uint8 rideIdx = peep->current_ride; + if (rideIdx == RIDE_ID_NULL) + { + continue; + } + set_format_arg(0, uint32, peep->id); + utf8 * curName = gCommonStringFormatBuffer; + rct_string_id curId = peep->name_string_idx; + format_string(curName, 256, curId, gCommonFormatArgs); + log_warning("Peep %u (%s) has invalid ride station = %u for ride %u.", spriteIndex, curName, srcStation, rideIdx); + sint8 station = ride_get_first_valid_station_exit(get_ride(rideIdx)); if (station == -1) { log_warning("Couldn't find station, removing peep %u", spriteIndex); - peep_remove(peep); + peepsToRemove.push_back(peep); } else { log_warning("Amending ride station to %u.", station); peep->current_ride_station = station; @@ -1231,6 +1242,11 @@ void game_fix_save_vars() } } + for (auto ptr : peepsToRemove) + { + peep_remove(ptr); + } + // Fixes broken saves where a surface element could be null // and broken saves with incorrect invisible map border tiles for (sint32 y = 0; y < 256; y++)