From 1dc5b6576700b1f2db5c8bba2750b6f78b6a31d3 Mon Sep 17 00:00:00 2001 From: lnz Date: Wed, 21 May 2014 14:04:08 +0200 Subject: [PATCH 1/4] Initial implementation of ride reachability checks --- src/ride.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++ src/ride.h | 5 +- src/scenario.c | 2 +- 3 files changed, 209 insertions(+), 2 deletions(-) diff --git a/src/ride.c b/src/ride.c index 42f32287ff..296936e935 100644 --- a/src/ride.c +++ b/src/ride.c @@ -19,6 +19,9 @@ *****************************************************************************/ #include "addresses.h" +#include "map.h" +#include "news_item.h" +#include "sprite.h" #include "ride.h" #include "sprite.h" #include "peep.h" @@ -200,3 +203,204 @@ void ride_update_favourited_stat() window_invalidate_by_id(WC_RIDE_LIST, 0); } + +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +{ + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate / 4]; + + do { + rct_map_element_path_properties props = tile->properties.path; + uint8 path_type = props.type >> 2, path_dir = props.type & 3; + uint8 element_type = tile->type & 0x3C; + + if (!(element_type & PATH_ROAD)) + continue; + + if (path_type & 1) { + if (path_dir == face_direction) { + if (height == tile->base_height + 2) + return 1; + } + else if (path_dir ^ 2 == face_direction && height == tile->base_height) { + return 1; + } + } else { + if (height == tile->base_height) + return 1; + } + + } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); + + return 0; +} + + + +/** + * rct2: 0x006B7C59 + * @return 1 if the coordinate is reachable or has no entrance, 0 otw + */ +int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { + int x = ((coordinate >> 8) & 0xFF) << 5, // cx + y = (coordinate & 0xFF) << 5; // ax + uint8 station_height = ride->pad_05A[index]; // pad_05a is uint8 station_base_height[4] + int tile_idx = ((x << 8) | y) >> 3; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + + while(1) { + uint8 element_type = tile->type & 0x3C; + if (element_type == MAP_ELEMENT_TYPE_ENTRANCE && station_height == tile->base_height) { + break; + } else if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) { + return 1; + } + tile++; + } + + uint8 face_direction = tile->type & 3; + y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; + x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; + tile_idx = ((x << 8) | y) >> 3; + + return map_coord_is_connected(tile_idx, station_height, face_direction); + /* while (1) { */ + /* rct_map_element_path_properties props; */ + + /* element_type = tile->type & 0x3C; */ + /* if (!(element_type & MAP_ELEMENT_TYPE_PATH)) */ + /* goto end; */ + + /* props = tile->properties.path; */ + /* if ( props.type & PATH_ROAD) { // with roads slopes count as connected sometimes */ + /* if ((props.type & 3) == face_direction) { */ + /* if (station_height == tile->base_height + 2) */ + /* return 1; */ + /* } */ + /* else { */ + /* uint8 madness = (props.type & 3) ^ 2; */ + /* if (madness == face_direction && station_height == tile->base_height) */ + /* return 1; */ + /* } */ + /* } else { // off-road only same height counts as connected */ + /* if (station_height == tile->base_height) */ + /* return 1; */ + /* } */ + + /* end: */ + /* if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) */ + /* return 0; */ + /* tile++; */ + /* } */ +} + + +void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) +{ + for (int i = 0; i < 4; ++i) { + uint16 station_start = ride->station_starts[i], + entrance = ride->entrances[i], + exit = ride->exits[i]; + + if (station_start == -1 ) + continue; + if (entrance != -1 && !ride_is_reachable(entrance, ride, i)) { + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb26, ride_idx); + ride->var_1AF = 3; + } + + if (exit != -1 && !ride_is_reachable(exit, ride, i)) { + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb27, ride_idx); + ride->var_1AF = 3; + } + + } +} + + +void blue_reachable(rct_ride* ride, int ride_idx) +{ + uint16 coordinate = ride->station_starts[ride_idx]; + int x = ((coordinate >> 8) & 0xFF) << 5, // cx + y = (coordinate & 0xFF) << 5; // ax + uint16 magic = 0; + int tile_idx = ((x << 8) | y) >> 3, count = 0; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + + while (1) { + // First find the appropriate track element for our ride + uint8 element_type = tile->type & 0x3C; + if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) + break; + + if(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) + return; + tile++; + } + + uint8 track_type = tile->properties.track.type; + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { + magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; + } else { + magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; + } + + magic = magic << (tile->type & 3); + magic = ((magic >> 12) | magic) & 0xF; + + for (int count = 0; magic != 0; ++count) { + if (!(magic & 1)) { + magic >>= 1; + continue; + } + + uint8 face_direction = count ^ 2; + y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; + x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; + tile_idx = ((x << 8) | y) >> 3; + + if (map_coord_is_connected(tile, tile->base_height, face_direction)) + return; + } + + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb26, ride_idx); + ride->var_1AF = 3; +} + + + +/** + * rct2: 0x006B7A5E + **/ +void ride_check_all_reachable() +{ +/* XXX: coordinates gleich um 5 shiften und / 4 ueberall weg */ + rct_ride *ride; + + for (int i = 0; i < MAX_RIDES; i++) { + ride = GET_RIDE(i); + if (ride->type == RIDE_TYPE_NULL) + continue; + if (ride->var_1AF != 0) + ride->var_1AF--; + if (ride->status != RIDE_STATUS_OPEN || ride->var_1AF != 0) + continue; + + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { + //lightblue + blue_reachable(ride, i); + return; + } + else { + //pink + ride_entrance_exit_connected(ride, i); + } + + } +} + diff --git a/src/ride.h b/src/ride.h index 84eb778120..a782f19f64 100644 --- a/src/ride.h +++ b/src/ride.h @@ -79,7 +79,9 @@ typedef struct { uint16 var_196; uint8 pad_198; uint8 var_199; - uint8 pad_19A[0x1A]; + uint8 pad_19A[0x15]; + uint8 var_1AF; + uint32 pad_1B0; sint32 profit; // 0x1B4 uint8 queue_time[4]; // 0x1B8 uint8 pad_1BC[0x12]; @@ -262,5 +264,6 @@ int ride_get_max_queue_time(rct_ride *ride); void ride_init_all(); void reset_all_ride_build_dates(); void ride_update_favourited_stat(); +void ride_check_all_reachable(); #endif diff --git a/src/scenario.c b/src/scenario.c index 81f97bbd08..c71abc6b55 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -874,7 +874,7 @@ void scenario_update() finance_pay_interest(); scenario_marketing_update(); peep_problem_warnings_update(); - RCT2_CALLPROC_EBPSAFE(0x006B7A5E); // check ride reachability + ride_check_all_reachable(); ride_update_favourited_stat(); if (month <= 1 && RCT2_GLOBAL(0x009ADAE0, sint32) != -1 && RCT2_GLOBAL(0x009ADAE0 + 14, uint16) & 1) { From 8bdba74ba690be5507567fb62cc96f1172f9eb3d Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 15:22:52 +0200 Subject: [PATCH 2/4] Cleanup and refactoring of ride reachability stuff --- src/map.c | 38 +++++++++++++++++++- src/map.h | 2 ++ src/ride.c | 95 ++++++++++---------------------------------------- src/scenario.c | 1 + 4 files changed, 59 insertions(+), 77 deletions(-) diff --git a/src/map.c b/src/map.c index 581eabdf30..b7e1ca0ae4 100644 --- a/src/map.c +++ b/src/map.c @@ -329,4 +329,40 @@ void sub_68B089() } while (mapElement->base_height == 255); mapElement++; RCT2_GLOBAL(0x0140E9A4, rct_map_element*) = mapElement; -} \ No newline at end of file +} + + +/** + * Checks if the tile at coordinate at height counts as connected. + * @return 1 if connected, 0 otherwisei + */ +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +{ + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate]; + + do { + rct_map_element_path_properties props = tile->properties.path; + uint8 path_type = props.type >> 2, path_dir = props.type & 3; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; + + if (!(element_type & PATH_ROAD)) + continue; + + if (path_type & 1) { + if (path_dir == face_direction) { + if (height == tile->base_height + 2) + return 1; + } + else if (path_dir ^ 2 == face_direction && height == tile->base_height) { + return 1; + } + } else { + if (height == tile->base_height) + return 1; + } + + } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); + + return 0; +} + diff --git a/src/map.h b/src/map.h index 88e76d7e11..1a44bd616c 100644 --- a/src/map.h +++ b/src/map.h @@ -186,5 +186,7 @@ void map_init(); void map_update_tile_pointers(); int map_element_height(int x, int y); void sub_68B089(); +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction); + #endif diff --git a/src/ride.c b/src/ride.c index 296936e935..34cba0b8ef 100644 --- a/src/ride.c +++ b/src/ride.c @@ -204,51 +204,21 @@ void ride_update_favourited_stat() } -int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) -{ - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate / 4]; - - do { - rct_map_element_path_properties props = tile->properties.path; - uint8 path_type = props.type >> 2, path_dir = props.type & 3; - uint8 element_type = tile->type & 0x3C; - - if (!(element_type & PATH_ROAD)) - continue; - - if (path_type & 1) { - if (path_dir == face_direction) { - if (height == tile->base_height + 2) - return 1; - } - else if (path_dir ^ 2 == face_direction && height == tile->base_height) { - return 1; - } - } else { - if (height == tile->base_height) - return 1; - } - - } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); - - return 0; -} - /** * rct2: 0x006B7C59 * @return 1 if the coordinate is reachable or has no entrance, 0 otw */ -int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { +int ride_entrance_exit_is_reachable(uint16 coordinate, rct_ride* ride, int index) { int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint8 station_height = ride->pad_05A[index]; // pad_05a is uint8 station_base_height[4] - int tile_idx = ((x << 8) | y) >> 3; - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + int tile_idx = ((x << 8) | y) >> 5; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; while(1) { - uint8 element_type = tile->type & 0x3C; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if (element_type == MAP_ELEMENT_TYPE_ENTRANCE && station_height == tile->base_height) { break; } else if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) { @@ -260,37 +230,9 @@ int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { uint8 face_direction = tile->type & 3; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; - tile_idx = ((x << 8) | y) >> 3; + tile_idx = ((x << 8) | y) >> 5; return map_coord_is_connected(tile_idx, station_height, face_direction); - /* while (1) { */ - /* rct_map_element_path_properties props; */ - - /* element_type = tile->type & 0x3C; */ - /* if (!(element_type & MAP_ELEMENT_TYPE_PATH)) */ - /* goto end; */ - - /* props = tile->properties.path; */ - /* if ( props.type & PATH_ROAD) { // with roads slopes count as connected sometimes */ - /* if ((props.type & 3) == face_direction) { */ - /* if (station_height == tile->base_height + 2) */ - /* return 1; */ - /* } */ - /* else { */ - /* uint8 madness = (props.type & 3) ^ 2; */ - /* if (madness == face_direction && station_height == tile->base_height) */ - /* return 1; */ - /* } */ - /* } else { // off-road only same height counts as connected */ - /* if (station_height == tile->base_height) */ - /* return 1; */ - /* } */ - - /* end: */ - /* if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) */ - /* return 0; */ - /* tile++; */ - /* } */ } @@ -303,14 +245,14 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) if (station_start == -1 ) continue; - if (entrance != -1 && !ride_is_reachable(entrance, ride, i)) { + if (entrance != -1 && !ride_entrance_exit_is_reachable(entrance, ride, i)) { RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb26, ride_idx); ride->var_1AF = 3; } - if (exit != -1 && !ride_is_reachable(exit, ride, i)) { + if (exit != -1 && !ride_entrance_exit_is_reachable(exit, ride, i)) { RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb27, ride_idx); @@ -321,18 +263,17 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) } -void blue_reachable(rct_ride* ride, int ride_idx) +void ride_is_shop_reachable(rct_ride* ride, int ride_idx) { uint16 coordinate = ride->station_starts[ride_idx]; int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint16 magic = 0; - int tile_idx = ((x << 8) | y) >> 3, count = 0; - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + int tile_idx = ((x << 8) | y) >> 5, count = 0; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; while (1) { - // First find the appropriate track element for our ride - uint8 element_type = tile->type & 0x3C; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) break; @@ -342,7 +283,8 @@ void blue_reachable(rct_ride* ride, int ride_idx) } uint8 track_type = tile->properties.track.type; - if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { + ride = GET_RIDE(tile->properties.track.ride_index); + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { // buggy but why magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; } else { magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; @@ -350,7 +292,9 @@ void blue_reachable(rct_ride* ride, int ride_idx) magic = magic << (tile->type & 3); magic = ((magic >> 12) | magic) & 0xF; - + if (magic == 0) + return; + for (int count = 0; magic != 0; ++count) { if (!(magic & 1)) { magic >>= 1; @@ -360,7 +304,7 @@ void blue_reachable(rct_ride* ride, int ride_idx) uint8 face_direction = count ^ 2; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; - tile_idx = ((x << 8) | y) >> 3; + tile_idx = ((x << 8) | y) >> 5; if (map_coord_is_connected(tile, tile->base_height, face_direction)) return; @@ -379,7 +323,6 @@ void blue_reachable(rct_ride* ride, int ride_idx) **/ void ride_check_all_reachable() { -/* XXX: coordinates gleich um 5 shiften und / 4 ueberall weg */ rct_ride *ride; for (int i = 0; i < MAX_RIDES; i++) { @@ -392,8 +335,8 @@ void ride_check_all_reachable() continue; if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { - //lightblue - blue_reachable(ride, i); + //blue + ride_is_shop_reachable(ride, i); return; } else { diff --git a/src/scenario.c b/src/scenario.c index c71abc6b55..e3137d1296 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -858,6 +858,7 @@ void scenario_update() RCT2_CALLPROC_EBPSAFE(0x0069E79A); // daily profit update RCT2_CALLPROC_EBPSAFE(0x0069C35E); // some kind of peeps days_visited update loop get_local_time(); + ride_check_all_reachable(); RCT2_CALLPROC_EBPSAFE(0x0066A13C); // objective 6 dragging if (objective_type == 10 || objective_type == 9 || objective_type == 8 || objective_type == 6 || objective_type == 5) { From 4993e6bed0c9b499934a6534a12c952d488c5e2f Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 17:39:18 +0200 Subject: [PATCH 3/4] Fix lots of disgusting bugs --- src/map.c | 6 +++--- src/ride.c | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/map.c b/src/map.c index b7e1ca0ae4..ce32cde185 100644 --- a/src/map.c +++ b/src/map.c @@ -336,16 +336,16 @@ void sub_68B089() * Checks if the tile at coordinate at height counts as connected. * @return 1 if connected, 0 otherwisei */ -int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +int map_coord_is_connected(uint16 tile_idx, uint8 height, uint8 face_direction) { - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate]; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; do { rct_map_element_path_properties props = tile->properties.path; uint8 path_type = props.type >> 2, path_dir = props.type & 3; uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; - if (!(element_type & PATH_ROAD)) + if (element_type != PATH_ROAD) continue; if (path_type & 1) { diff --git a/src/ride.c b/src/ride.c index 34cba0b8ef..8a8aba7d39 100644 --- a/src/ride.c +++ b/src/ride.c @@ -284,10 +284,10 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) uint8 track_type = tile->properties.track.type; ride = GET_RIDE(tile->properties.track.ride_index); - if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { // buggy but why - magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; - } else { + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; + } else { + magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; } magic = magic << (tile->type & 3); @@ -295,18 +295,19 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) if (magic == 0) return; - for (int count = 0; magic != 0; ++count) { + for (int count = 0; magic != 0; ++count) { if (!(magic & 1)) { - magic >>= 1; + magic >>= 1; continue; } + magic >>= 1; uint8 face_direction = count ^ 2; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; tile_idx = ((x << 8) | y) >> 5; - if (map_coord_is_connected(tile, tile->base_height, face_direction)) + if (map_coord_is_connected(tile_idx, tile->base_height, face_direction)) return; } @@ -337,7 +338,6 @@ void ride_check_all_reachable() if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { //blue ride_is_shop_reachable(ride, i); - return; } else { //pink From ee67b3b7037adface5d38dc6e92e00597d543852 Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 18:19:34 +0200 Subject: [PATCH 4/4] More critical bugfixes for the reachability code. --- src/ride.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ride.c b/src/ride.c index 8a8aba7d39..0110d83caa 100644 --- a/src/ride.c +++ b/src/ride.c @@ -265,13 +265,17 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) void ride_is_shop_reachable(rct_ride* ride, int ride_idx) { - uint16 coordinate = ride->station_starts[ride_idx]; + uint16 coordinate = ride->station_starts[0]; + if (coordinate == 0xFFFF) + return; + int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint16 magic = 0; int tile_idx = ((x << 8) | y) >> 5, count = 0; rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; + while (1) { uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx)