U8 movement_costs[16];
movement_costs[PLAINS]		= 2;
movement_costs[TREES]		= 6;
movement_costs[MOUNTAINS]	= 10;

I64 HexMoveOneCost(Unit *tmpu, I64 r, I64 c, I64 facing)
{
	I64 res;

	if (tmpu->infantry)
		res = 0;
	else
	{
		res = FacingChange(facing, tmpu->facing);
		if (res > 0)
			res--;
	}
	if (roads[r][c] && roads[tmpu->row][tmpu->col])
		res += 1;
	else
	{
		if (tmpu->infantry)
			res += 2;
		else
		{
			res += movement_costs[terrain[r][c]];
			if (rivers[r][c])
				res = tmpu->movement;
		}
	}

	return res;
}

I64 HexMoveOne(I64 *_row, I64 *_col, F64 x, F64 y)
{
	I64 direction, best_direction = -1, r, c;
	F64 dd, best_dd, x1, y1;

	RowCol2XY(&x1, &y1, *_row, *_col);
	best_dd = Sqr(x1 - x) + Sqr(y1 - y);
	for (direction = 0; direction < 6; direction++)
	{
		r = *_row;
		c = *_col;
		Toward(&r, &c, direction);
		RowCol2XY(&x1, &y1, r, c);
		dd = Sqr(x1 - x) + Sqr(y1 - y);
		if (0 <= r < map_rows && 0 <= c < map_cols && dd<best_dd)
		{
			best_dd = dd;
			best_direction = direction;
		}
	}
	if (best_direction >= 0)
	{
		Toward(_row, _col, best_direction);
		return best_direction;
	}
	else
		return -1;
}

Bool UnitMovePlot(U0, I64 x, I64 y, I64)
{
	move_x = x;
	move_y = y;
	Sleep(5 * animation_delay);

	return TRUE;
}

U0 UnitMoveAnimation(Unit *tmpu, I64 r, I64 c, I64 facing)
{
	F64 x1, y1, x2, y2, f = facing * 60.0 * ã / 180.0;

	moving_unit = tmpu;
	RowCol2XY(&x1, &y1, tmpu->row, tmpu->col);
	move_x = x1;
	move_y = y1;
	moving = TRUE;
	if (tmpu->infantry)
		Sound(53);
	else
	{
		move_facing = tmpu->facing * 60.0 * ã / 180.0;
		Sound(41);
		while (Wrap(f - move_facing, -ã) <= 0)
		{
			move_facing -= 0.03;
			Sleep(5  *animation_delay);
		}
		while (Wrap(f - move_facing, -ã) > 0)
		{
			move_facing += 0.03;
			Sleep(5 * animation_delay);
		}
		Sound(34);
	}
	move_facing = f;
	RowCol2XY(&x2, &y2, r, c);
	Line(NULL, x1, y1, 0, x2, y2, 0, &UnitMovePlot);
	Sound;
	moving_unit = NULL;
	moving = FALSE;
}
 
Bool UnitMove(Unit *tmpu, I64 x, I64 y)
{
	Unit *target;
	I64   r, c, r0 = tmpu->row, c0=tmpu->col, i, facing;

	while (tmpu->remaining_movement > 0)
	{
		r = tmpu->row;
		c = tmpu->col;
		if ((facing = HexMoveOne(&r, &c, x, y)) < 0)
			break;
		else
		{
			i = HexMoveOneCost(tmpu, r, c, facing);
			if (i > tmpu->movement)
				i = tmpu->movement;
			if (!tmpu->fired && tmpu->remaining_movement >= i &&
				tmpu->remaining_movement >= tmpu->movement >> 1 &&
				(target = UnitFind(r, c)) && target->player != tmpu->player &&
				tmpu->infantry != target->infantry)
			{
				if (!HexOccupy(ToBool(target->infantry), tmpu, target))
				{
					tmpu = NULL;
					break;
				}
				i = tmpu->remaining_movement;
			}
			if (tmpu->remaining_movement >= i && !UnitFind(r, c))
			{
				UnitMoveAnimation(tmpu, r, c, facing);
				tmpu->facing=facing;
				tmpu->remaining_movement -= i;
				tmpu->row = r;
				tmpu->col = c;
				VisRecalc(VR_UPDATE_FRIENDLY_UNIT, tmpu);
				LBEqual(&tmpu->vis[enemy_player], 0, VisRecalc(VR_ONE_ENEMY_UNIT, tmpu));
			}
			else
				break;
		}
	}
	if (!tmpu || tmpu->row != r0 || tmpu->col != c0)
		return TRUE;
	else
		return FALSE;
}
