U0 Toward(I64 *_row, I64 *_col, I64 direction)
{
	switch (direction)
	{
		case 0:
			*_row -= 2;
			break;

		case 1:
			if (*_row & 1)
				*_col += 1;
			*_row -= 1;
			break;

		case 2:
			if (*_row & 1)
				*_col += 1;
			*_row += 1;
			break;

		case 3:
			*_row += 2;
			break;

		case 4:
			if (!(*_row & 1))
				*_col -= 1;
			*_row += 1;
			break;

		case 5:
			if (!(*_row&1))
				*_col -= 1;
			*_row -= 1;
			break;
	}
}

I64 FacingChange(I64 f1, I64 f2)
{
	I64 res = (f1 + 6 - f2 ) %6;

	if (res >= 3)
		return 6 - res;
	else
		return res;
}

U0 RowCol2XY(F64 *_x, F64 *_y, I64 row, I64 col)
{
	Pt *c;

	row = ClampI64(row, 0, map_rows);
	col = ClampI64(col, 0, map_cols);
	c = &hex_centers[row][col];
	*_x = c->x;
	*_y = c->y;
}

U0 XY2RowCol(I64 *_row, I64 *_col, F64 x, F64 y)
{
	*_col = (x - DCOS / 2) / (HEX_SIDE + DCOS);
	if (*_col & 1)
		*_row = ToI64((y - DSIN) / (2 * DSIN)) * 2 + 1;
	else
		*_row = ToI64(y / (2 * DSIN)) * 2;
	*_col >>= 1;
	*_row = ClampI64(*_row, 0, map_rows - 1);
	*_col = ClampI64(*_col, 0, map_cols - 1);
}

Unit *UnitFind(I64 row, I64 col)
{//Finds unit in a hexagon.
	I64 i, j;

	for (j = 0; j < 2; j++)
		for (i = 0; i < UNITS_NUM; i++)
			if (	units[j][i].life > 0 &&
					units[j][i].row == row &&
					units[j][i].col == col)
				return &units[j][i];
	return NULL;
}

Bool CursorInWin(CTask *task, I64 x, I64 y)
{
	if (	0 <= x + task->scroll_x < task->pix_width &&
			0 <= y + task->scroll_y < task->pix_height)
		return TRUE;
	else
		return FALSE;
}

U0 CursorUpdate(CTask *task, I64 x, I64 y)
{
	if (CursorInWin(task, x, y))
		XY2RowCol(&cursor_row, &cursor_col, x, y);
}

class LOSCtrl
{
	I64 r1, c1, r2, c2, distance;
};

Bool LOSPlot(LOSCtrl *l, I64 x, I64 y, I64 z)
{//We got tricky and used z as the distance from the start of the line.
	I64 row, col;

	XY2RowCol(&row, &col, x, y);
	if ((row != l->r1 || col != l->c1) &&
		(row != l->r2 || col != l->c2) &&
		terrain[row][col] != PLAINS)
	{
		if (terrain[l->r1][l->c1] == MOUNTAINS)
		{
			if (terrain[row][col] == MOUNTAINS || z>l->distance >> 1)
				return FALSE;
		}
		else if (terrain[l->r2][l->c2] == MOUNTAINS)
		{
			if (terrain[row][col] == MOUNTAINS || z <= l->distance >> 1)
				return FALSE;
		}
		else
			return FALSE;
	}

	return TRUE;
}

Bool LOS(I64 r1, I64 c1, I64 r2, I64 c2)
{
	F64 x1, y1, x2, y2;

	LOSCtrl l;
	RowCol2XY(&x1, &y1, r1, c1);
	RowCol2XY(&x2, &y2, r2, c2);
	l.r1 = r1;
	l.c1 = c1;
	l.r2 = r2;
	l.c2 = c2;
	l.distance = Sqrt(SqrI64(x1 - x2) + SqrI64(y1 - y2));

	return Line(&l, x1, y1, 0, x2, y2, l.distance, &LOSPlot);
}
