diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 83c99e51a1..6a6af9eb05 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -6,6 +6,7 @@ - Feature: Implementation of the user-defined currency - Feature: Add ability to rotate map elements with the tile inspector. - Feature: Add ride console command for diagnostics and changing vehicle type. +- Feature: Allow selecting corners when using the mountain tool. - Feature: Allow setting ownership of map edges. - Feature: Allow up to 255 cars per train. - Feature: Importing SV4 and SC4 files with rides. @@ -28,6 +29,7 @@ - Removed: BMP screenshots. - Removed: Intamin and Phoenix easter eggs. - Fix: [#1038] Guest List is out of order. +- Fix: [#2081] Game hangs when track has infinite loop. - Fix: [#2754] Dragging scrollview fails when scaled. - Fix: [#3210] Scenery window scrolls too far. - Fix: [#3282] Launched Freefall ride ratings are fixed for Downward Launch (original bug). diff --git a/src/ride/ride.c b/src/ride/ride.c index c6a0bf74a3..d44800d882 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -743,7 +743,7 @@ int ride_find_track_gap(rct_xy_element *input, rct_xy_element *output) { rct_window *w; rct_ride *ride; - track_circuit_iterator it; + track_circuit_iterator it, slowIt; int rideIndex; rideIndex = input->element->properties.track.ride_index; @@ -756,12 +756,27 @@ int ride_find_track_gap(rct_xy_element *input, rct_xy_element *output) if (w != NULL && _rideConstructionState != RIDE_CONSTRUCTION_STATE_0 && _currentRideIndex == rideIndex) sub_6C9627(); + bool counter = true; track_circuit_iterator_begin(&it, *input); + slowIt = it; while (track_circuit_iterator_next(&it)) { if (!track_is_connected_by_shape(it.last.element, it.current.element)) { *output = it.current; return 1; } + //#2081: prevent an infinite loop + counter = !counter; + if (counter) { + track_circuit_iterator_next(&slowIt); + if (slowIt.currentZ == it.currentZ && + slowIt.currentDirection == it.currentDirection && + slowIt.current.x == it.current.x && + slowIt.current.y == it.current.y) { + *output = it.current; + return 1; + } + } + } if (!it.looped) { *output = it.last; diff --git a/src/ride/vehicle.c b/src/ride/vehicle.c index 8169dcd00d..0ba53770bb 100644 --- a/src/ride/vehicle.c +++ b/src/ride/vehicle.c @@ -5753,7 +5753,11 @@ static void vehicle_update_block_breaks_open_previous_section(rct_vehicle *vehic int x = vehicle->track_x; int y = vehicle->track_y; int z = vehicle->track_z; - track_begin_end trackBeginEnd; + track_begin_end trackBeginEnd, slowTrackBeginEnd; + rct_map_element slowMapElement = *mapElement; + bool counter = true; + int slowX = x; + int slowY = y; do { if (!track_block_get_previous(x, y, mapElement, &trackBeginEnd)) { return; @@ -5768,6 +5772,21 @@ static void vehicle_update_block_breaks_open_previous_section(rct_vehicle *vehic y = trackBeginEnd.end_y; z = trackBeginEnd.begin_z; mapElement = trackBeginEnd.begin_element; + + //#2081: prevent infinite loop + counter = !counter; + if (counter) { + track_block_get_previous(slowX, slowY, &slowMapElement, &slowTrackBeginEnd); + slowX = slowTrackBeginEnd.end_x; + slowY = slowTrackBeginEnd.end_y; + slowMapElement = *(slowTrackBeginEnd.begin_element); + if (slowX == x && + slowY == y && + slowMapElement.base_height == mapElement->base_height && + slowMapElement.type == mapElement->type ) { + return; + } + } } while (!track_element_is_block_start(trackBeginEnd.begin_element)); // Get the start of the track block instead of the end