diff --git a/src/peep/staff.c b/src/peep/staff.c index e4ec137296..90a49bde8b 100644 --- a/src/peep/staff.c +++ b/src/peep/staff.c @@ -557,6 +557,94 @@ bool staff_is_patrol_area_set(int staffIndex, int x, int y) return gStaffPatrolAreas[peepOffset + offset] & (1 << bitIndex); } +/** + * + * rct2: 0x006BFBE8 + * + * Returns 0xFF when no nearby litter or unpathable litter + */ +static uint8 staff_handyman_direction_to_nearest_litter(rct_peep* peep){ + uint16 nearestLitterDist = (uint16)-1; + rct_litter* nearestLitter = NULL; + rct_litter* litter = NULL; + + for(uint16 litterIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_LITTER, uint16); litterIndex != 0xFFFF; litterIndex = litter->next){ + litter = &g_sprite_list[litterIndex].litter; + + uint16 distance = + abs(litter->x - peep->x) + + abs(litter->y - peep->y) + + abs(litter->z - peep->z) / 4; + + if (distance < nearestLitterDist){ + nearestLitterDist = distance; + nearestLitter = litter; + } + } + + if (nearestLitterDist > 0x60){ + return 0xFF; + } + + rct_xy16 litterTile = { + .x = litter->x & 0xFFE0, + .y = litter->y & 0xFFE0 + }; + + if (!staff_is_location_in_patrol(peep, litterTile.x, litterTile.y)){ + return 0xFF; + } + + litterTile.x += 16; + litterTile.y += 16; + + sint16 x_diff = litterTile.x - peep->x; + sint16 y_diff = litterTile.y - peep->y; + + uint8 nextDirection = 0; + + if (abs(x_diff) <= abs(y_diff)){ + nextDirection = y_diff < 0 ? 3 : 1; + } + else { + nextDirection = x_diff < 0 ? 0 : 2; + } + + rct_xy16 nextTile = { + .x = (litter->x & 0xFFE0) - TileDirectionDelta[nextDirection].x, + .y = (litter->y & 0xFFE0) - TileDirectionDelta[nextDirection].y + }; + + sint16 nextZ = ((peep->z + 8) & 0xFFF0) / 8; + + rct_map_element* mapElement = map_get_first_element_at(nextTile.x / 32, nextTile.y / 32); + + do { + if (mapElement->base_height != nextZ) + continue; + if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE || + map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_TRACK){ + return 0xFF; + } + } while(!map_element_is_last_for_tile(mapElement++)); + + nextTile.x = (peep->x & 0xFFE0) + TileDirectionDelta[nextDirection].x; + nextTile.y = (peep->y & 0xFFE0) + TileDirectionDelta[nextDirection].y; + + rct_map_element* mapElement = map_get_first_element_at(nextTile.x / 32, nextTile.y / 32); + + do { + if (mapElement->base_height != nextZ) + continue; + if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE || + map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_TRACK){ + return 0xFF; + } + } while(!map_element_is_last_for_tile(mapElement++)); + + return nextDirection; +} + /** * * rct2: 0x006BFBA8 @@ -569,74 +657,13 @@ static int staff_path_finding_handyman(rct_peep* peep) { if (peep->staff_orders & STAFF_ORDERS_SWEEPING && ((RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) + peep->sprite_index) & 0xFFF) > 110) { - // Split into seperate function - uint16 nearestLitterDist = (uint16)-1; - rct_litter* nearestLitter = NULL; - rct_litter* litter = NULL; - - for(uint16 litterIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_LITTER, uint16); litterIndex != 0xFFFF; litterIndex = litter->next){ - litter = &g_sprite_list[litterIndex].litter; - - uint16 distance = - abs(litter->x - peep->x) + - abs(litter->y - peep->y) + - abs(litter->z - peep->z) / 4; - - if (distance < nearestLitterDist){ - nearestLitterDist = distance; - nearestLitter = litter; - } - } - - if (nearestLitterDist > 0x60){ - //goto 6bfd82 - } - - rct_xy16 litterTile = { - .x = litter->x & 0xFFE0, - .y = litter->y & 0xFFE0 - }; - - if (!staff_is_location_in_patrol(peep, litterTile.x, litterTile.y)){ - //goto 6bfd82 - } - - litterTile.x += 16; - litterTile.y += 16; - - sint16 x_diff = litterTile.x - peep->x; - sint16 y_diff = litterTile.y - peep->y; - - uint8 nextDirection = 0; - - if (abs(x_diff) <= abs(y_diff)){ - nextDirection = y_diff < 0 ? 3 : 1; - } - else { - nextDirection = x_diff < 0 ? 0 : 2; - } - - rct_xy16 nextTile = { - .x = (litter->x & 0xFFE0) - TileDirectionDelta[nextDirection].x; - .y = (litter->y & 0xFFE0) - TileDirectionDelta[nextDirection].y; - }; - - sint16 nextZ = ((peep->z + 8) & 0xFFF0) / 8; - - rct_map_element* mapElement = map_get_first_element_at(nextTile.x / 32, nextTile.y / 32); - - do { - if (mapElement->base_height != nextZ) - continue; - if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE || - map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_TRACK){ - //goto 6bfd82 - } - } while(!map_element_is_last_for_tile(mapElement++)); - - // 6bfd13 + RCT2_GLOBAL(0x00F43918, uint8) = staff_handyman_direction_to_nearest_litter(peep); } - //6bfd82 + + if (RCT2_GLOBAL(0x00F43918, uint8) == 0xFF){ + //6bfd82 + } + //6bfd90 return 0; }