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);
}