U8 movement_costs[16]; movement_costs[PLAINS]=2; movement_costs[TREES]=6; movement_costs[MOUNTAINS]=10; I64 HexMoveOneCost(Unit *tmpu,I64 r,I64 c,I64 facing) { I64 res; if (tmpu->infantry) res=0; else { res=FacingChg(facing,tmpu->facing); if (res>0) res--; } if (roads[r][c] && roads[tmpu->row][tmpu->col]) res+=1; else { if (tmpu->infantry) res+=2; else { res+=movement_costs[terrain[r][c]]; if (rivers[r][c]) res=tmpu->movement; } } return res; } I64 HexMoveOne(I64 *_row,I64 *_col,F64 x,F64 y) { I64 direction,best_direction=-1,r,c; F64 dd,best_dd,x1,y1; RowCol2XY(&x1,&y1,*_row,*_col); best_dd=Sqr(x1-x)+Sqr(y1-y); for (direction=0; direction<6; direction++) { r=*_row; c=*_col; Toward(&r,&c,direction); RowCol2XY(&x1,&y1,r,c); dd=Sqr(x1-x)+Sqr(y1-y); if (0<=r<map_rows && 0<=c<map_cols && dd<best_dd) { best_dd=dd; best_direction=direction; } } if (best_direction>=0) { Toward(_row,_col,best_direction); return best_direction; } else return -1; } Bool UnitMovePlot(U0,I64 x,I64 y,I64) { move_x=x; move_y=y; Sleep(5*animation_delay); return TRUE; } U0 UnitMoveAnimation(Unit *tmpu,I64 r,I64 c,I64 facing) { F64 x1,y1,x2,y2,f=facing*60.0*pi/180.0; moving_unit=tmpu; RowCol2XY(&x1,&y1,tmpu->row,tmpu->col); move_x=x1; move_y=y1; moving=TRUE; if (tmpu->infantry) Snd(53); else { move_facing=tmpu->facing*60.0*pi/180.0; Snd(41); while (Wrap(f-move_facing,-pi)<=0) { move_facing-=0.03; Sleep(5*animation_delay); } while (Wrap(f-move_facing,-pi)>0) { move_facing+=0.03; Sleep(5*animation_delay); } Snd(34); } move_facing=f; RowCol2XY(&x2,&y2,r,c); Line(NULL,x1,y1,0,x2,y2,0,&UnitMovePlot); Snd; moving_unit=NULL; moving=FALSE; } Bool UnitMove(Unit *tmpu,I64 x,I64 y) { Unit *target; I64 r,c,r0=tmpu->row,c0=tmpu->col,i,facing; while (tmpu->remaining_movement>0) { r=tmpu->row; c=tmpu->col; if ((facing=HexMoveOne(&r,&c,x,y))<0) break; else { i=HexMoveOneCost(tmpu,r,c,facing); if (i>tmpu->movement) i=tmpu->movement; if (!tmpu->fired && tmpu->remaining_movement>=i && tmpu->remaining_movement>=tmpu->movement>>1 && (target=UnitFind(r,c)) && target->player!=tmpu->player && tmpu->infantry!=target->infantry) { if (!HexOccupy(ToBool(target->infantry),tmpu,target)) { tmpu=NULL; break; } i=tmpu->remaining_movement; } if (tmpu->remaining_movement>=i && !UnitFind(r,c)) { UnitMoveAnimation(tmpu,r,c,facing); tmpu->facing=facing; tmpu->remaining_movement-=i; tmpu->row=r; tmpu->col=c; VisRecalc(VR_UPDATE_FRIENDLY_UNIT,tmpu); LBEqu(&tmpu->vis[enemy_player],0, VisRecalc(VR_ONE_ENEMY_UNIT,tmpu)); } else break; } } if (!tmpu || tmpu->row!=r0 || tmpu->col!=c0) return TRUE; else return FALSE; }