Implement guest surface path finding

This commit is contained in:
Duncan Frost 2015-07-25 11:16:59 +01:00
parent bff00b29bf
commit 812010001d
5 changed files with 141 additions and 4 deletions

View File

@ -67,6 +67,7 @@ static void peep_pick_ride_to_go_on(rct_peep *peep);
static void peep_head_for_nearest_ride_type(rct_peep *peep, int rideType);
static void peep_head_for_nearest_ride_with_flags(rct_peep *peep, int rideTypeFlags);
static void peep_give_real_name(rct_peep *peep);
static int guest_surface_path_finding(rct_peep* peep);
const char *gPeepEasterEggNames[] = {
"MICHAEL SCHUMACHER",
@ -6555,6 +6556,100 @@ static int peep_interact_with_shop(rct_peep* peep, sint16 x, sint16 y, rct_map_e
}
}
/* rct2: 0x0069524E */
static int peep_move_one_tile(uint8 direction, rct_peep* peep){
sint16 x = peep->next_x;
sint16 y = peep->next_y;
x += RCT2_ADDRESS(0x00993CC, sint16)[direction * 2];
y += RCT2_ADDRESS(0x00993CE, sint16)[direction * 2];
if (x >= 8192 || y >= 8192){
// This could loop!
return guest_surface_path_finding(peep);
}
peep->var_78 = direction;
peep->destination_x = x + 16;
peep->destination_y = y + 16;
peep->destination_tolerence = 2;
if (peep->state == PEEP_STATE_QUEUING){
peep->destination_tolerence = (scenario_rand() & 7) + 2;
}
return 0;
}
/* rct2: 0x00694C41 */
static int guest_surface_path_finding(rct_peep* peep){
sint16 x = peep->next_x;
sint16 y = peep->next_y;
sint16 z = peep->next_z;
uint8 randDirection = scenario_rand() & 3;
if (!fence_in_the_way(x, y, z, z + 4, randDirection)){
x += RCT2_ADDRESS(0x00993CC, sint16)[randDirection * 2];
y += RCT2_ADDRESS(0x00993CE, sint16)[randDirection * 2];
randDirection ^= (1 << 1);
if (!fence_in_the_way(x, y, z, z + 4, randDirection)){
randDirection ^= (1 << 1);
if (!map_surface_is_blocked(x, y)){
return peep_move_one_tile(randDirection, peep);
}
}
}
randDirection++;
uint8 rand_backwards = scenario_rand() & 1;
if (rand_backwards){
randDirection -= 2;
}
randDirection &= 3;
if (!fence_in_the_way(x, y, z, z + 4, randDirection)){
x += RCT2_ADDRESS(0x00993CC, sint16)[randDirection * 2];
y += RCT2_ADDRESS(0x00993CE, sint16)[randDirection * 2];
randDirection ^= (1 << 1);
if (!fence_in_the_way(x, y, z, z + 4, randDirection)){
randDirection ^= (1 << 1);
if (!map_surface_is_blocked(x, y)){
return peep_move_one_tile(randDirection, peep);
}
}
}
randDirection -= 2;
randDirection &= 3;
if (!fence_in_the_way(x, y, z, z + 4, randDirection)){
x += RCT2_ADDRESS(0x00993CC, sint16)[randDirection * 2];
y += RCT2_ADDRESS(0x00993CE, sint16)[randDirection * 2];
randDirection ^= (1 << 1);
if (!fence_in_the_way(x, y, z, z + 4, randDirection)){
randDirection ^= (1 << 1);
if (!map_surface_is_blocked(x, y)){
return peep_move_one_tile(randDirection, peep);
}
}
}
randDirection--;
if (rand_backwards){
randDirection += 2;
}
return peep_move_one_tile(randDirection, peep);
}
/* rct2: 0x00694C35 */
static int guest_path_finding(rct_peep* peep){
sint16 x, y, z;
if (peep->next_var_29 & 0x18){
return guest_surface_path_finding(peep);
}
//694DA8
}
/**
*
* rct2: 0x00693C9E

View File

@ -698,7 +698,8 @@ void footpath_interrupt_peeps(int x, int y, int z)
}
}
bool sub_6E59DC(int x, int y, int z0, int z1, int direction)
/* rct2: 0x006E59DC */
bool fence_in_the_way(int x, int y, int z0, int z1, int direction)
{
rct_map_element *mapElement;
@ -899,7 +900,7 @@ static rct_map_element *footpath_get_element(int x, int y, int z0, int z1, int d
static bool sub_footpath_disconnect_queue_from_path(int x, int y, rct_map_element *mapElement, int action, int direction) {
if (((mapElement->properties.path.edges & (1 << direction)) == 0) ^ (action < 0))
return false;
if ((action < 0) && sub_6E59DC(x, y, mapElement->base_height, mapElement->clearance_height, direction))
if ((action < 0) && fence_in_the_way(x, y, mapElement->base_height, mapElement->clearance_height, direction))
return false;
int x1 = x + TileDirectionDelta[direction].x;
@ -1018,7 +1019,7 @@ static void loc_6A6D7E(
loc_6A6F1F:
if (query) {
if (sub_6E59DC(x, y, mapElement->base_height, mapElement->clearance_height, direction ^ 2)) {
if (fence_in_the_way(x, y, mapElement->base_height, mapElement->clearance_height, direction ^ 2)) {
return;
}
if (footpath_element_is_queue(mapElement)) {
@ -1061,7 +1062,7 @@ static void loc_6A6C85(
int x, int y, int direction, rct_map_element *mapElement,
int flags, bool query, rct_neighbour_list *neighbourList
) {
if (query && sub_6E59DC(x, y, mapElement->base_height, mapElement->clearance_height, direction))
if (query && fence_in_the_way(x, y, mapElement->base_height, mapElement->clearance_height, direction))
return;
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE) {

View File

@ -61,6 +61,7 @@ void footpath_bridge_get_info_from_pos(int screenX, int screenY, int *x, int *y,
void footpath_remove_litter(int x, int y, int z);
void footpath_connect_edges(int x, int y, rct_map_element *mapElement, int flags);
void sub_6A759F();
bool fence_in_the_way(int x, int y, int z0, int z1, int direction);
void footpath_chain_ride_queue(int rideIndex, int entranceIndex, int x, int y, rct_map_element *mapElement, int direction);
void footpath_bridge_get_info_from_pos(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement);

View File

@ -3612,3 +3612,42 @@ int map_get_tile_quadrant(int mapX, int mapY)
(subMapY < 16 ? 2 : 3);
}
/* rct2: 0x00693BFF */
bool map_surface_is_blocked(sint16 x, sint16 y){
rct_map_element *mapElement;
if (x >= 8192 || y >= 8192)
return true;
mapElement = map_get_surface_element_at(x / 32, y / 32);
sint16 water_height = mapElement->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK;
water_height *= 2;
if (water_height > mapElement->base_height)
return true;
sint16 base_z = mapElement->base_height;
sint16 clear_z = mapElement->base_height + 2;
if (mapElement->properties.surface.slope & (1 << 4))
clear_z += 2;
while (!map_element_is_last_for_tile(mapElement++)){
if (clear_z >= mapElement->clearance_height)
continue;
if (base_z < mapElement->base_height)
continue;
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_PATH ||
map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_FENCE)
continue;
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_SCENERY)
return true;
rct_scenery_entry* scenery = g_smallSceneryEntries[mapElement->properties.scenery.type];
if (scenery->small_scenery.flags & SMALL_SCENERY_FLAG_FULL_TILE)
return true;
}
return false;
}

View File

@ -283,6 +283,7 @@ int map_coord_is_connected(int x, int y, int z, uint8 faceDirection);
void sub_6A876D();
int map_is_location_owned(int x, int y, int z);
int map_is_location_in_park(int x, int y);
bool map_surface_is_blocked(sint16 x, sint16 y);
int map_get_station(rct_map_element *mapElement);
void map_element_remove(rct_map_element *mapElement);
void map_remove_all_rides();