Implement final part of handyman litter locating

Split function up to make it easier to read.
Fixed a syntax issue.
This commit is contained in:
Duncan 2016-02-03 12:41:34 +00:00 committed by duncanspumpkin
parent b2f756ef89
commit 2276bfff33
1 changed files with 94 additions and 67 deletions

View File

@ -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;
}