From 5e104477d328bf09a8261ac2a0a737d19eb7292c Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 15:22:52 +0200 Subject: [PATCH] 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 935f059ee0..20d85834b6 100644 --- a/src/map.c +++ b/src/map.c @@ -328,4 +328,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 355767bc81..069c0d52c9 100644 --- a/src/map.h +++ b/src/map.h @@ -195,5 +195,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 5b301cfd36..32f500d1ea 100644 --- a/src/ride.c +++ b/src/ride.c @@ -195,51 +195,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) { @@ -251,37 +221,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++; */ - /* } */ } @@ -294,14 +236,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); @@ -312,18 +254,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; @@ -333,7 +274,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]; @@ -341,7 +283,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; @@ -351,7 +295,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; @@ -370,7 +314,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++) { @@ -383,8 +326,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 6dc29fa1bf..5ae95f70e1 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -574,6 +574,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) {