From e3b0409fbc29e2511616017043497f0736701adb Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Wed, 25 Oct 2017 15:05:10 +0200 Subject: [PATCH] Also fix disconnected exits --- src/openrct2/game.c | 4 +- src/openrct2/ride/ride.c | 88 ++++++++++++++++++++++++++++------------ src/openrct2/ride/ride.h | 2 +- src/openrct2/world/map.c | 24 +++++++++++ src/openrct2/world/map.h | 1 + 5 files changed, 89 insertions(+), 30 deletions(-) diff --git a/src/openrct2/game.c b/src/openrct2/game.c index 5945aa0ba0..10973e6b7c 100644 --- a/src/openrct2/game.c +++ b/src/openrct2/game.c @@ -1125,8 +1125,8 @@ void game_fix_save_vars() // Fix gParkEntrance locations for which the map_element no longer exists fix_park_entrance_locations(); - // Fix ride entrances that were moved without updating ride->entrances[] - fix_ride_entrance_locations(); + // Fix ride entrances and exits that were moved without updating ride->entrances[] / ride->exits[] + fix_ride_entrance_and_exit_locations(); } void handle_park_load_failure_with_title_opt(const ParkLoadResult * result, const utf8 * path, bool loadTitleFirst) diff --git a/src/openrct2/ride/ride.c b/src/openrct2/ride/ride.c index a94d72b284..06bfa2f6a0 100644 --- a/src/openrct2/ride/ride.c +++ b/src/openrct2/ride/ride.c @@ -8227,7 +8227,7 @@ LocationXY16 ride_get_rotated_coords(sint16 x, sint16 y, sint16 z) return rotatedCoords; } -void fix_ride_entrance_locations() +void fix_ride_entrance_and_exit_locations() { sint32 rideIndex; Ride * ride; @@ -8236,25 +8236,43 @@ void fix_ride_entrance_locations() { for (sint32 stationIndex = 0; stationIndex < MAX_STATIONS; stationIndex++) { - LocationXY8 entranceLoc = ride->entrances[stationIndex]; - uint8 entranceHeight = ride->station_heights[stationIndex]; + LocationXY8 entranceLoc = ride->entrances[stationIndex]; + LocationXY8 exitLoc = ride->exits[stationIndex]; + uint8 entranceExitHeight = ride->station_heights[stationIndex]; + bool fixEntrance = false; + bool fixExit = false; + rct_map_element * mapElement; // Skip if the station has no entrance - if (entranceLoc.xy == RCT_XY8_UNDEFINED) + if (entranceLoc.xy != RCT_XY8_UNDEFINED) + { + mapElement = map_get_ride_entrance_element_at(entranceLoc.x * 32, entranceLoc.y * 32, entranceExitHeight, false); + + if (mapElement == NULL || mapElement->properties.entrance.ride_index != rideIndex || map_element_get_station(mapElement) != stationIndex) + { + fixEntrance = true; + } + } + + if (exitLoc.xy != RCT_XY8_UNDEFINED) + { + mapElement = map_get_ride_exit_element_at(exitLoc.x * 32, exitLoc.y * 32, entranceExitHeight, false); + + if (mapElement == NULL || mapElement->properties.entrance.ride_index != rideIndex || map_element_get_station(mapElement) != stationIndex) + { + fixExit = true; + } + } + + if (!fixEntrance && !fixExit) { continue; } - rct_map_element * mapElement = map_get_ride_entrance_element_at(entranceLoc.x * 32, entranceLoc.y * 32, entranceHeight, false); - - if (mapElement != NULL && mapElement->properties.entrance.ride_index == rideIndex && map_element_get_station(mapElement) == stationIndex) - { - continue; - } - - // At this point, we know we have a disconnected entrance. + // At this point, we know we have a disconnected entrance or exit. // Search the map to find it. Skip the outer ring of invisible tiles. - bool alreadyFoundOne = false; + bool alreadyFoundEntrance = false; + bool alreadyFoundExit = false; for (uint8 x = 1; x < MAXIMUM_MAP_SIZE_TECHNICAL - 1; x++) { for (uint8 y = 1; y < MAXIMUM_MAP_SIZE_TECHNICAL - 1; y++) @@ -8269,10 +8287,6 @@ void fix_ride_entrance_locations() { continue; } - if (mapElement->properties.entrance.type != ENTRANCE_TYPE_RIDE_ENTRANCE) - { - continue; - } if (mapElement->properties.entrance.ride_index != rideIndex) { continue; @@ -8281,21 +8295,41 @@ void fix_ride_entrance_locations() { continue; } - // There are some cases (like Belmont Shores), where there is both a sunk and a disconnected entrance. - // Not sure why, but in this case, pick the highest one. - if (alreadyFoundOne && ride->station_heights[stationIndex] > mapElement->base_height) + + if (fixEntrance && mapElement->properties.entrance.type == ENTRANCE_TYPE_RIDE_ENTRANCE) { - continue; + // There are some cases (like Belmont Shores), where there is both a sunk and a disconnected entrance. + // Not sure why, but in this case, pick the highest one. + if (alreadyFoundEntrance && ride->station_heights[stationIndex] > mapElement->base_height) + { + continue; + } + + // Found our entrance + ride->entrances[stationIndex].x = x; + ride->entrances[stationIndex].y = y; + ride->station_heights[stationIndex] = mapElement->base_height; + + alreadyFoundEntrance = true; + + log_info("Fixed disconnected entrance of ride %d, station %d to x = %d, y = %d and z = %d.", rideIndex, stationIndex, x, y, mapElement->base_height); } + else if (fixExit && mapElement->properties.entrance.type == ENTRANCE_TYPE_RIDE_EXIT) + { + if (alreadyFoundExit && ride->station_heights[stationIndex] > mapElement->base_height) + { + continue; + } - // Found our entrance - ride->entrances[stationIndex].x = x; - ride->entrances[stationIndex].y = y; - ride->station_heights[stationIndex] = mapElement->base_height; + // Found our exit + ride->exits[stationIndex].x = x; + ride->exits[stationIndex].y = y; + ride->station_heights[stationIndex] = mapElement->base_height; - alreadyFoundOne = true; + alreadyFoundExit = true; - log_info("Fixed disconnected entrance of ride %d, station %d to x = %d, y = %d and z = %d.", rideIndex, stationIndex, x, y, mapElement->base_height); + log_info("Fixed disconnected exit of ride %d, station %d to x = %d, y = %d and z = %d.", rideIndex, stationIndex, x, y, mapElement->base_height); + } } while (!map_element_is_last_for_tile(mapElement++)); } diff --git a/src/openrct2/ride/ride.h b/src/openrct2/ride/ride.h index 794f8ebfe0..3d625555e4 100644 --- a/src/openrct2/ride/ride.h +++ b/src/openrct2/ride/ride.h @@ -1214,7 +1214,7 @@ void ride_stop_peeps_queuing(sint32 rideIndex); LocationXY16 ride_get_rotated_coords(sint16 x, sint16 y, sint16 z); -void fix_ride_entrance_locations(); +void fix_ride_entrance_and_exit_locations(); #ifdef __cplusplus } diff --git a/src/openrct2/world/map.c b/src/openrct2/world/map.c index a1c9a111ed..c641ae045d 100644 --- a/src/openrct2/world/map.c +++ b/src/openrct2/world/map.c @@ -3856,6 +3856,30 @@ rct_map_element * map_get_ride_entrance_element_at(sint32 x, sint32 y, sint32 z, return NULL; } +rct_map_element * map_get_ride_exit_element_at(sint32 x, sint32 y, sint32 z, bool ghost) +{ + rct_map_element * mapElement = map_get_first_element_at(x >> 5, y >> 5); + do + { + if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_ENTRANCE) + continue; + + if (mapElement->base_height != z) + continue; + + if (mapElement->properties.entrance.type != ENTRANCE_TYPE_RIDE_EXIT) + continue; + + if ((ghost == false) && (mapElement->flags & MAP_ELEMENT_FLAG_GHOST)) + continue; + + return mapElement; + } + while (!map_element_is_last_for_tile(mapElement++)); + + return NULL; +} + rct_map_element *map_get_small_scenery_element_at(sint32 x, sint32 y, sint32 z, sint32 type, uint8 quadrant) { rct_map_element *mapElement = map_get_first_element_at(x >> 5, y >> 5); diff --git a/src/openrct2/world/map.h b/src/openrct2/world/map.h index 7aaab7d8c2..e0f45028bf 100644 --- a/src/openrct2/world/map.h +++ b/src/openrct2/world/map.h @@ -416,6 +416,7 @@ rct_map_element *map_get_wall_element_at(sint32 x, sint32 y, sint32 z, sint32 di rct_map_element *map_get_small_scenery_element_at(sint32 x, sint32 y, sint32 z, sint32 type, uint8 quadrant); rct_map_element *map_get_park_entrance_element_at(sint32 x, sint32 y, sint32 z, bool ghost); rct_map_element * map_get_ride_entrance_element_at(sint32 x, sint32 y, sint32 z, bool ghost); +rct_map_element * map_get_ride_exit_element_at(sint32 x, sint32 y, sint32 z, bool ghost); sint32 map_element_height(sint32 x, sint32 y); void sub_68B089(); sint32 map_coord_is_connected(sint32 x, sint32 y, sint32 z, uint8 faceDirection);