Index: common/unit.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/unit.h,v retrieving revision 1.78 diff -u -r1.78 unit.h --- common/unit.h 2001/09/16 09:38:08 1.78 +++ common/unit.h 2001/10/06 13:09:50 @@ -121,6 +121,7 @@ int bribe_cost; struct unit_ai ai; enum unit_activity activity; + int goto_src_x, goto_src_y; int goto_dest_x, goto_dest_y; int activity_count; int activity_target; Index: server/gotohand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/gotohand.c,v retrieving revision 1.121 diff -u -r1.121 gotohand.c --- server/gotohand.c 2001/10/06 12:01:29 1.121 +++ server/gotohand.c 2001/10/06 13:09:51 @@ -431,35 +431,43 @@ } /************************************************************************** -Return the direction that takes us most directly to dest_x,dest_y. -The direction is a value for use in DIR_DX[] and DIR_DY[] arrays. - -FIXME: This is a bit crude; this only gives one correct path, but sometimes - there can be more than one straight path (fx going NW then W is the - same as going W then NW) +Return the direction to the next point/tile/position in the line from +(punit->goto_src_x, punit->goto_src_y) to (punit->goto_dest_x, +punit->goto_dest_y). **************************************************************************/ -static int straightest_direction(int src_x, int src_y, int dest_x, int dest_y) +static int next_step_on_line(struct unit *punit) { - int best_dir; - int go_x, go_y; + int dx, dy, new_unit_x, new_unit_y; - /* Should we go up or down, east or west: go_x/y is the "step" in x/y. - Will allways be -1 or 1 even if src_x == dest_x or src_y == dest_y. */ - go_x = dest_x > src_x ? - (dest_x-src_x < map.xsize/2 ? 1 : -1) : - (src_x-dest_x < map.xsize/2 ? -1 : 1); - go_y = dest_y > src_y ? 1 : -1; - - if (src_x == dest_x) - best_dir = (go_y > 0) ? 6 : 1; - else if (src_y == dest_y) - best_dir = (go_x > 0) ? 4 : 3; - else if (go_x > 0) - best_dir = (go_y > 0) ? 7 : 2; - else /* go_x < 0 */ - best_dir = (go_y > 0) ? 5 : 0; + /* This code is topology-dependent */ + dx = punit->goto_dest_x - punit->goto_src_x; + if (dx < -map.xsize / 2) + dx += map.xsize; + if (dx > map.xsize / 2) + dx -= map.xsize; + dy = punit->goto_dest_y - punit->goto_src_y; + + freelog(LOG_DEBUG, "start=(%d,%d) end=(%d,%d) current=(%d,%d)", + punit->goto_src_x, punit->goto_src_y, punit->goto_dest_x, + punit->goto_dest_y, punit->x, punit->y); + + if (abs(dx) > abs(dy)) { + float m = (float) dy / (float) dx; + float b = punit->goto_src_y - m * punit->goto_src_x; + new_unit_x = + punit->x + ((punit->goto_dest_x < punit->goto_src_x) ? -1 : 1); + new_unit_y = (int) (m * new_unit_x + b + 0.5); + } else { + float m = (float) dx / (float) dy; + float b = punit->goto_src_x - m * punit->goto_src_y; + new_unit_y = + punit->y + ((punit->goto_dest_y < punit->goto_src_y) ? -1 : 1); + new_unit_x = (int) (m * new_unit_y + b + 0.5); + } + freelog(LOG_DEBUG, "next=(%d,%d)", new_unit_x, new_unit_y); - return (best_dir); + return get_direction_for_step(punit->x, punit->y, new_unit_x, + new_unit_y); } /************************************************************************** @@ -624,7 +632,7 @@ psrctile = map_get_tile(x, y); if (restriction == GOTO_MOVE_STRAIGHTEST) - straight_dir = straightest_direction(x, y, dest_x, dest_y); + straight_dir = next_step_on_line(punit); /* Try to move to all tiles adjacent to x,y. The coordinats of the tile we try to move to are x1,y1 */ @@ -1056,6 +1064,9 @@ unit_id = punit->id; dest_x = waypoint_x = punit->goto_dest_x; dest_y = waypoint_y = punit->goto_dest_y; + + punit->goto_src_x = punit->x; + punit->goto_src_y = punit->y; if (same_pos(punit->x, punit->y, dest_x, dest_y) || !goto_is_sane(punit, dest_x, dest_y, 0)) {