/************************************************************************** Return the direction that takes us most directly to dest_x,dest_y. **************************************************************************/ static int straightest_direction(int src_x, int src_y, int dest_x, int dest_y) { static int tx[8] = { DIR8_SOUTHEAST, DIR8_EAST, DIR8_NORTHEAST, DIR8_NORTH, DIR8_SOUTHWEST, DIR8_SOUTH, DIR8_NORTHWEST, DIR8_WEST }; int temp, delta_x, delta_y, nn= 0; /* Sanitize */ normalize_map_pos(&src_x, &src_y); normalize_map_pos(&dest_x, &dest_y); /* compute sign and magnitude of x delta */ if( (delta_x= dest_x - src_x) < 0 ) nn|= 4, delta_x= -delta_x; /* if wrapped and closer, flip sign and save new delta */ if( has_mapwrap(MAP_TYPE_WRAPX) && (temp= map.xsize - delta_x) < delta_x ) nn^= 4, delta_x= temp; /* compute sign and magnitude of y delta */ if( (delta_y= dest_y - src_y) < 0 ) nn|= 2, delta_y= -delta_y; /* if wrapped and closer, flip sign and save new delta */ if( has_mapwrap(MAP_TYPE_WRAPY) && (temp= map.ysize - delta_y) < delta_y ) nn^= 2, delta_y= temp; /* * - 3 - If point is closer to the cardinal axes vs diagonals * 7 s 1 then update the index nn using these index positions. * - 5 - Test for 2 dy < dx (or dy < dx-dy) for cardinal x, etc. * diagonal move--^ ^--residual x move */ if( delta_y < delta_x ) { if( delta_y+delta_y < delta_x ) nn= ((nn & 4) ? 7 : 1); } else if( delta_x+delta_x < delta_y ) nn= ((nn & 2) ? 3 : 5); /* * 6 3 2 nn should now be one of these 8 possibilities. * 7 s 1 Translate (tx) it to your favourite DX ordering. * 4 5 0 */ return tx[nn]; }