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++) { UserChk; 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++) { UserChk; 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++) { UserChk; 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); }