Unit *UnitNearestFind(I64 row, I64 col, I64 player, Bool in_LOS, F64 range=-1)
{
    I64   i;
    F64   dd, best_dd = F64_MAX, x1, y1, x2, y2;
    Unit *best = NULL;

    //Sqrt() is slow, so work with squared distances.
    if (range < 0)
        range = F64_MAX;
    else
        range *= range;
    RowCol2XY(&x1, &y1, row, col);
    for (i = 0; i < UNITS_NUM; i++)
        if (units[player][i].life > 0)
        {
            if (!in_LOS || LOS(row, col, units[player][i].row, units[player][i].col))
            {
                RowCol2XY(&x2, &y2, units[player][i].row, units[player][i].col);
                dd = Sqr(x2 - x1) + Sqr(y2 - y1);
                if (dd <= range && dd < best_dd)
                {
                    best = &units[player][i];
                    best_dd = dd;
                }
            }
        }

    return best;
}

U0 PlayerIndirect()
{
    Unit *target, *tmpu;
    I64   i;

    for (i = 0; i < UNITS_NUM; i++)
    {
        UserCheck;
        tmpu = &units[cur_player][i];
        if (    tmpu->life > 0 && tmpu->indirect_fire &&
                (target = UnitNearestFind(tmpu->row, tmpu->col, enemy_player, TRUE, tmpu->range * 2 * HEX_RADIUS)))
            IndirectAdd(tmpu, target->row, target->col);
    }
    throw('PhaseOvr', TRUE);
}

U0 PlayerMove()
{
    Unit *target, *tmpu;
    I64   i;
    F64   x, y;

    for (i = 0; i < UNITS_NUM; i++)
    {
        UserCheck;
        tmpu = &units[cur_player][i];
        if (tmpu->life>0)
        {
            //Cheats because it violates Line-of-Sight
            if (target = UnitNearestFind(tmpu->row, tmpu->col, enemy_player, FALSE))
            {
                RowCol2XY(&x, &y, target->row, target->col);
                if (!UnitMove(tmpu, x, y))
                {
                    RowCol2XY(&x, &y, tmpu->row, tmpu->col);
                    UnitMove(tmpu, x + RandI16, y + RandI16);
                }
            }
        }
    }
    throw('PhaseOvr', TRUE);
}

U0 PlayerDirect()
{
    Unit *target, *tmpu;
    I64   i;

    for (i = 0; i < UNITS_NUM; i++)
    {
        UserCheck;
        tmpu = &units[cur_player][i];
        if (tmpu->life > 0 && !tmpu->indirect_fire &&
            (target = UnitNearestFind(tmpu->row, tmpu->col, enemy_player, TRUE, tmpu->range * 2 * HEX_RADIUS)))
        {
            UnitDirectFire(tmpu, target);
            Sleep(250 * animation_delay);
        }
    }
    throw('PhaseOvr', TRUE);
}