diff --git a/src/ride/ride.c b/src/ride/ride.c index f5a78109d5..f28e41de56 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -3865,19 +3865,39 @@ int ride_check_station_length(rct_xy_element *input, rct_xy_element *output) * * rct2: 0x006CB2DA */ -int ride_check_start_and_end_is_station(rct_xy_element *input, rct_xy_element *output) +bool ride_check_start_and_end_is_station(rct_xy_element *input, rct_xy_element *output) { - int eax, ebx, ecx, edx, esi, edi, ebp, result; + rct_window *w; + rct_ride *ride; + int rideIndex, trackType; + rct_xy_element trackBack, trackFront; - eax = input->x; - ecx = input->y; - esi = (int)input->element; - result = RCT2_CALLFUNC_X(0x006CB2DA, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - output->x = (uint16)eax; - output->y = (uint16)ecx; - output->element = (rct_map_element*)esi; + rideIndex = input->element->properties.track.ride_index; + ride = GET_RIDE(rideIndex); - return (result & 0x100) != 0; + w = window_find_by_class(WC_RIDE_CONSTRUCTION); + if (w != NULL && _rideConstructionState != RIDE_CONSTRUCTION_STATE_0 && rideIndex == _currentRideIndex) { + sub_6C9627(); + } + + // Check back of the track + track_get_back(input, &trackBack); + trackType = trackBack.element->properties.track.type; + if (!(RCT2_GLOBAL(0x0099BA64 + (trackType * 16), uint32) & 0x10)) { + return false; + } + ride->var_13A = (trackBack.x >> 5) | ((trackBack.y >> 5) << 8); + ride->var_13E = trackBack.element->base_height; + + // Check front of the track + track_get_front(input, &trackFront); + trackType = trackFront.element->properties.track.type; + if (!(RCT2_GLOBAL(0x0099BA64 + (trackType * 16), uint32) & 0x10)) { + return false; + } + ride->var_13C = (trackFront.x >> 5) | ((trackFront.y >> 5) << 8); + ride->var_13F = trackFront.element->base_height; + return true; } /** @@ -4140,7 +4160,7 @@ int ride_is_valid_for_test(int rideIndex, int goingToBeOpen, int isApplying) } RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_RIDE_MUST_START_AND_END_WITH_STATIONS; - if (ride_check_start_and_end_is_station(&trackElement, &problematicTrackElement)) { + if (!ride_check_start_and_end_is_station(&trackElement, &problematicTrackElement)) { loc_6B528A(&problematicTrackElement); return 0; } @@ -4257,19 +4277,13 @@ int ride_is_valid_for_open(int rideIndex, int goingToBeOpen, int isApplying) } RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_STATION_NOT_LONG_ENOUGH; - if (ride_check_station_length(&trackElement, &problematicTrackElement)) { - - // This is to prevent a bug in the check_station_length function - // remove when check_station_length is reveresed and fixed. Prevents - // null dereference. Does not prevent moving screen to top left corner. - if (map_element_get_type(problematicTrackElement.element) != MAP_ELEMENT_TYPE_TRACK) - loc_6B528A(&trackElement); - else loc_6B528A(&problematicTrackElement); + if (!ride_check_station_length(&trackElement, &problematicTrackElement)) { + loc_6B528A(&problematicTrackElement); return 0; } RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_RIDE_MUST_START_AND_END_WITH_STATIONS; - if (ride_check_start_and_end_is_station(&trackElement, &problematicTrackElement)) { + if (!ride_check_start_and_end_is_station(&trackElement, &problematicTrackElement)) { loc_6B528A(&problematicTrackElement); return 0; } diff --git a/src/ride/track.c b/src/ride/track.c index 95ac0c2378..297fe71508 100644 --- a/src/ride/track.c +++ b/src/ride/track.c @@ -4274,3 +4274,37 @@ bool track_circuit_iterator_next(track_circuit_iterator *it) return track_block_get_next(&it->last, &it->current, &it->currentZ, &it->currentDirection); } } + +void track_get_back(rct_xy_element *input, rct_xy_element *output) +{ + rct_xy_element lastTrack; + track_begin_end currentTrack; + bool result; + + lastTrack = *input; + do { + result = track_block_get_previous(lastTrack.x, lastTrack.y, lastTrack.element, ¤tTrack); + if (result) { + lastTrack.x = currentTrack.begin_x; + lastTrack.y = currentTrack.begin_y; + lastTrack.element = currentTrack.begin_element; + } + } while (result); + *output = lastTrack; +} + +void track_get_front(rct_xy_element *input, rct_xy_element *output) +{ + rct_xy_element lastTrack, currentTrack; + int z, direction; + bool result; + + lastTrack = *input; + do { + result = track_block_get_next(&lastTrack, ¤tTrack, &z, &direction); + if (result) { + lastTrack = currentTrack; + } + } while (result); + *output = lastTrack; +} diff --git a/src/ride/track.h b/src/ride/track.h index a45588ac9c..1a757d0b7d 100644 --- a/src/ride/track.h +++ b/src/ride/track.h @@ -522,4 +522,7 @@ void game_command_set_brakes_speed(int *eax, int *ebx, int *ecx, int *edx, int * void track_circuit_iterator_begin(track_circuit_iterator *it, rct_xy_element first); bool track_circuit_iterator_next(track_circuit_iterator *it); +void track_get_back(rct_xy_element *input, rct_xy_element *output); +void track_get_front(rct_xy_element *input, rct_xy_element *output); + #endif