diff --git a/src/ride/ride.c b/src/ride/ride.c index 92e10545a7..4d43a4780b 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -8691,18 +8691,23 @@ money16 ride_get_price(rct_ride * ride) } /** - * Check for an adjacent station at x,y,z(+-2). + * Return the map_element of an adjacent station at x,y,z(+-2). + * Returns NULL if no suitable map_element is found. */ -static bool check_adjacent_station(int x, int y, int z) { +rct_map_element *get_station_platform(int x, int y, int z, int z_tolerance) { bool foundMapElement = false; rct_map_element *mapElement = map_get_first_element_at(x >> 5, y >> 5); if (mapElement != NULL) { do { if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK) continue; - if (z != mapElement->base_height && - z != mapElement->base_height - 2 && - z != mapElement->base_height + 2 + /* Check if mapElement is a station platform. */ + if (!track_element_is_station(mapElement)) continue; + + if (z - z_tolerance > mapElement->base_height || + z + z_tolerance < mapElement->base_height ) { + /* The base height if mapElement is not within + * the z tolerance. */ continue; } @@ -8711,15 +8716,28 @@ static bool check_adjacent_station(int x, int y, int z) { } while (!map_element_is_last_for_tile(mapElement++)); } if (!foundMapElement) { - return false; + return NULL; } - int rideIndex = mapElement->properties.track.ride_index; - rct_ride *ride = get_ride(rideIndex); - if (!(ride->depart_flags & RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS)) { - return false; + return mapElement; +} + +/** + * Check for an adjacent station to x,y,z in direction. + */ +static bool check_for_adjacent_station(int x, int y, int z, uint8 direction) { + bool found = false; + int adjX = x + TileDirectionDelta[direction].x; + int adjY = y + TileDirectionDelta[direction].y; + rct_map_element *stationElement = get_station_platform(adjX, adjY, z, 2); + if (stationElement != NULL) { + int rideIndex = stationElement->properties.track.ride_index; + rct_ride *ride = get_ride(rideIndex); + if (ride->depart_flags & RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS) { + found = true; + } } - return true; + return found; } /** @@ -8730,35 +8748,27 @@ bool ride_has_adjacent_station(rct_ride *ride) bool found = false; /* Loop through all of the ride stations, checking for an - * adjacent station anywhere. */ + * adjacent station on either side. */ for (int stationNum = 0; stationNum <= 3; stationNum++) { if (ride->station_starts[stationNum] != 0xFFFF) { + /* Get the map element for the station start. */ uint16 stationX = (ride->station_starts[stationNum] & 0xFF) * 32; uint16 stationY = (ride->station_starts[stationNum] >> 8) * 32; uint8 stationZ = ride->station_heights[stationNum]; - rct_map_element *stationElement = map_get_track_element_at(stationX, stationY, stationZ); + rct_map_element *stationElement = get_station_platform(stationX, stationY, stationZ, 0); if (stationElement == NULL) { continue; } /* Check the first side of the station */ int direction = (stationElement->type + 1) & 3; - int adjStationX = stationX + TileDirectionDelta[direction].x; - int adjStationY = stationY + TileDirectionDelta[direction].y; - if (check_adjacent_station(adjStationX, adjStationY, stationZ)) { - found = true; - break; - } + found = check_for_adjacent_station(stationX, stationY, stationZ, direction); + if (found) break; /* Check the other side of the station */ direction ^= 2; - adjStationX = stationX + TileDirectionDelta[direction].x; - adjStationY = stationY + TileDirectionDelta[direction].y; - if (check_adjacent_station(adjStationX, adjStationY, stationZ)) { - found = true; - break; - } + found = check_for_adjacent_station(stationX, stationY, stationZ, direction); + if (found) break; } } - return found; } diff --git a/src/ride/ride.h b/src/ride/ride.h index 871a57d16c..77f8263f32 100644 --- a/src/ride/ride.h +++ b/src/ride/ride.h @@ -1142,6 +1142,7 @@ void game_command_callback_place_ride_entrance_or_exit(int eax, int ebx, int ecx void ride_delete(uint8 rideIndex); money16 ride_get_price(rct_ride * ride); +rct_map_element *get_station_platform(int x, int y, int z, int z_tolerance); bool ride_has_adjacent_station(rct_ride *ride); #endif diff --git a/src/ride/vehicle.c b/src/ride/vehicle.c index 3165ff186a..f8a87629d1 100644 --- a/src/ride/vehicle.c +++ b/src/ride/vehicle.c @@ -2283,29 +2283,17 @@ static rct_synchronised_vehicle* _lastSynchronisedVehicle = NULL; */ static bool try_add_synchronised_station(int x, int y, int z) { - bool foundMapElement = false; - rct_map_element *mapElement = map_get_first_element_at(x >> 5, y >> 5); - if (mapElement != NULL) { - do { - if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK) continue; - if (z != mapElement->base_height && - z != mapElement->base_height - 2 && - z != mapElement->base_height + 2 - ) { - continue; - } - - foundMapElement = true; - break; - } while (!map_element_is_last_for_tile(mapElement++)); - } - if (!foundMapElement) { + rct_map_element *mapElement = get_station_platform(x, y, z, 2); + if (mapElement == NULL) { + /* No station platform element found, + * so no station to synchronise */ return false; } int rideIndex = mapElement->properties.track.ride_index; rct_ride *ride = get_ride(rideIndex); if (!(ride->depart_flags & RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS)) { + /* Ride is not set to synchronise with adjacent stations. */ return false; }