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