mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-17 03:53:07 +01:00
Move station check before exit/entrance check. Found original bug in station to station.
This commit is contained in:
106
src/ride/ride.c
106
src/ride/ride.c
@@ -2751,7 +2751,7 @@ void ride_music_update_final()
|
||||
*
|
||||
* rct2: 0x006B4CC1
|
||||
*/
|
||||
int ride_mode_check_valid_stations(rct_ride *ride)
|
||||
int ride_mode_check_valid_station_numbers(rct_ride *ride)
|
||||
{
|
||||
uint8 no_stations = 0;
|
||||
for (uint8 station_index = 0; station_index < 4; ++station_index){
|
||||
@@ -2781,6 +2781,33 @@ int ride_mode_check_valid_stations(rct_ride *ride)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* returns stationIndex of first station on success
|
||||
* -1 on failure.
|
||||
*/
|
||||
int ride_mode_check_station_present(rct_ride* ride){
|
||||
int stationIndex = -1;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (ride->station_starts[i] != 0xFFFF) {
|
||||
stationIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stationIndex == -1) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_NOT_YET_CONSTRUCTED;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8), uint32) & 0x8000)
|
||||
return -1;
|
||||
|
||||
if (ride->type == RIDE_TYPE_MAZE)
|
||||
return -1;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_REQUIRES_A_STATION_PLATFORM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return stationIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B5872
|
||||
@@ -2799,21 +2826,19 @@ int ride_check_for_entrance_exit(int rideIndex)
|
||||
continue;
|
||||
|
||||
if (ride->entrances[i] != 0xFFFF) {
|
||||
entrance = 2;
|
||||
entrance = 1;
|
||||
}
|
||||
else if (ride->exits[i] != 0xFFFF) {
|
||||
exit = 2;
|
||||
|
||||
if (ride->exits[i] != 0xFFFF) {
|
||||
exit = 1;
|
||||
}
|
||||
else
|
||||
|
||||
|
||||
// If station start and no entrance/exit
|
||||
if (entrance == 1 && exit == 1){
|
||||
// Sets same error message as no entrance
|
||||
if (ride->exits[i] == 0xFFFF && ride->entrances[i] == 0xFFFF){
|
||||
entrance = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (entrance) entrance = 1;
|
||||
if (exit) exit = 1;
|
||||
}
|
||||
|
||||
if (entrance == 0){
|
||||
@@ -2907,8 +2932,8 @@ int ride_check_track_suitability_a(rct_xy_element *input, rct_xy_element *output
|
||||
ecx = input->y;
|
||||
esi = (int)input->element;
|
||||
result = RCT2_CALLFUNC_X(0x006CB149, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
output->x = eax;
|
||||
output->y = ecx;
|
||||
output->x = (uint16)eax;
|
||||
output->y = (uint16)ecx;
|
||||
output->element = (rct_map_element*)esi;
|
||||
|
||||
return (result & 0x100) != 0;
|
||||
@@ -2926,8 +2951,8 @@ int ride_check_track_suitability_b(rct_xy_element *input, rct_xy_element *output
|
||||
ecx = input->y;
|
||||
esi = (int)input->element;
|
||||
result = RCT2_CALLFUNC_X(0x006CB1D3, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
output->x = eax;
|
||||
output->y = ecx;
|
||||
output->x = (uint16)eax;
|
||||
output->y = (uint16)ecx;
|
||||
output->element = (rct_map_element*)esi;
|
||||
|
||||
return (result & 0x100) != 0;
|
||||
@@ -2941,12 +2966,17 @@ int ride_check_station_length(rct_xy_element *input, rct_xy_element *output)
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp, result;
|
||||
|
||||
// This function has a bug. If the station length is too short and it is
|
||||
// the last station of a ride it will return a pointer to the map_element
|
||||
// where the station piece should go. Instead it should pass the map_element
|
||||
// of the last good station piece. This can cause null pointer dereferences
|
||||
// and cause the map to move to the top left hand corner.
|
||||
eax = input->x;
|
||||
ecx = input->y;
|
||||
esi = (int)input->element;
|
||||
result = RCT2_CALLFUNC_X(0x006CB25D, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
output->x = eax;
|
||||
output->y = ecx;
|
||||
output->x = (uint16)eax;
|
||||
output->y = (uint16)ecx;
|
||||
output->element = (rct_map_element*)esi;
|
||||
|
||||
return (result & 0x100) != 0;
|
||||
@@ -2964,8 +2994,8 @@ int ride_check_start_and_end_is_station(rct_xy_element *input, rct_xy_element *o
|
||||
ecx = input->y;
|
||||
esi = (int)input->element;
|
||||
result = RCT2_CALLFUNC_X(0x006CB2DA, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
output->x = eax;
|
||||
output->y = ecx;
|
||||
output->x = (uint16)eax;
|
||||
output->y = (uint16)ecx;
|
||||
output->element = (rct_map_element*)esi;
|
||||
|
||||
return (result & 0x100) != 0;
|
||||
@@ -3146,14 +3176,18 @@ rct_map_element *loc_6B4F6B(int rideIndex, int x, int y)
|
||||
*/
|
||||
int ride_is_valid_for_open(int rideIndex, int goingToBeOpen, int isApplying)
|
||||
{
|
||||
int i, stationIndex;
|
||||
int stationIndex;
|
||||
rct_ride *ride;
|
||||
rct_xy_element trackElement, problematicTrackElement;
|
||||
|
||||
ride = GET_RIDE(rideIndex);
|
||||
|
||||
window_close_by_class(WC_RIDE_CONSTRUCTION);
|
||||
if (!ride_mode_check_valid_stations(ride))
|
||||
|
||||
stationIndex = ride_mode_check_station_present(ride);
|
||||
if (stationIndex == -1)return 0;
|
||||
|
||||
if (!ride_mode_check_valid_station_numbers(ride))
|
||||
return 0;
|
||||
|
||||
if (!ride_check_for_entrance_exit(rideIndex)) {
|
||||
@@ -3165,30 +3199,10 @@ int ride_is_valid_for_open(int rideIndex, int goingToBeOpen, int isApplying)
|
||||
sub_6B5952(rideIndex);
|
||||
ride->lifecycle_flags |= RIDE_LIFECYCLE_EVER_BEEN_OPENED;
|
||||
}
|
||||
|
||||
stationIndex = -1;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (ride->station_starts[i] != 0xFFFF) {
|
||||
stationIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stationIndex == -1) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_NOT_YET_CONSTRUCTED;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8), uint32) & 0x8000)
|
||||
return 0;
|
||||
|
||||
if (ride->type == RIDE_TYPE_MAZE)
|
||||
return 0;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_REQUIRES_A_STATION_PLATFORM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// z = ride->station_heights[i] * 8;
|
||||
trackElement.x = (ride->station_starts[i] & 0xFF) * 32;
|
||||
trackElement.y = (ride->station_starts[i] >> 8) * 32;
|
||||
trackElement.x = (ride->station_starts[stationIndex] & 0xFF) * 32;
|
||||
trackElement.y = (ride->station_starts[stationIndex] >> 8) * 32;
|
||||
trackElement.element = loc_6B4F6B(rideIndex, trackElement.x, trackElement.y);
|
||||
if (trackElement.element == NULL) {
|
||||
// Maze is strange, station start is 0... investigation required
|
||||
@@ -3246,7 +3260,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)) {
|
||||
loc_6B528A(&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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user