//Uses fixed-point. <1>/* Graphics Not Rendered in HTML */ <2>/* Graphics Not Rendered in HTML */ <3>/* Graphics Not Rendered in HTML */ <4>/* Graphics Not Rendered in HTML */ <5>/* Graphics Not Rendered in HTML */ #define FRAMES 6 U8 *imgs[FRAMES]={ <1>,<2>,<3>,<4>,<3>,<2>}; F64 fire_end_time; class Trooper { I64 x,y,dx,dy,att,def,rng,player; F64 animate_time_base,fire_end_time; Trooper *target; }; #define TROOPERS_NUM 100 Trooper tr[2][TROOPERS_NUM]; Bool time_lapse=FALSE; #define TAP_MODE_RADIUS 50 Bool tap_mode; #define AI_NOTHING 0 #define AI_TARGET 1 #define AI_RANDOM 2 #define AI_AI_NUM 3 I64 ai_mode; I64 ai_targets[10]; U0 DrawTrooper(CTask *,CDC *dc,Trooper *tmpt) { U8 *tmps; I64 x,y,gx,gy; F64 speed,tt; if (tmpt->def>0) { x=tmpt->dx>>28; y=tmpt->dy>>28; speed=0.5*Sqrt(x*x+y*y); tt=tmpt->animate_time_base+tS*speed; if (time_lapse) { x=(tmpt->x+500*tmpt->dx)>>32; y=(tmpt->y+500*tmpt->dy)>>32; } else { x=tmpt->x.i32[1]; y=tmpt->y.i32[1]; } if (tmpt->target) { gx=x;gy=y; if (tmpt->dx<0) { dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR; DCSymmetrySet(dc,x,y,x,y+1); gx-=13; gy-=7; } else { dc->flags&=~DCF_SYMMETRY|DCF_JUST_MIRROR; gx+=13; gy-=7; } dc->color=BLACK; Sprite3(dc,x+1,y,0,<5>); if (!tmpt->player) dc->color=LTCYAN; else dc->color=LTPURPLE; Sprite3(dc,x,y,0,<5>); dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR); if (!tmpt->player) dc->color=WHITE; else dc->color=LTBLUE; GrLine3(dc,gx,gy,0,tmpt->target->x.i32[1],tmpt->target->y.i32[1],0); } else { if (tmpt->dx<0) { dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR; DCSymmetrySet(dc,x,y,x,y+1); } else dc->flags&=~DCF_SYMMETRY|DCF_JUST_MIRROR; tmps=SpriteInterpolate(tt%1.0,imgs[tt%FRAMES],imgs[(tt+1.0)%FRAMES]); dc->color=BLACK; Sprite3(dc,x+1,y,0,tmps); if (!tmpt->player) dc->color=LTCYAN; else dc->color=LTPURPLE; Sprite3(dc,x,y,0,tmps); Free(tmps); dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR); } } } U0 DrawIt(CTask *task,CDC *dc) { Trooper *tmpt=tr; I64 i,j,cnt[2], x=ms.pos.x-task->pix_left-task->scroll_x, y=ms.pos.y-task->pix_top-task->scroll_y; Bool repulsive=ms.pos.z>0 ^^ ms.rb, active=!winmgr.grab_scroll && (ms.lb||ms.rb); for (j=0;j<2;j++) { cnt[j]=0; for (i=0;i<TROOPERS_NUM;i++,tmpt++) { if (tmpt->def>0) { DrawTrooper(task,dc,tmpt); cnt[j]++; } } } if (tap_mode) { dc->color=YELLOW; GrCircle(dc,x,y,TAP_MODE_RADIUS); } else { if (repulsive) { if (active) dc->color=LTRED; else dc->color=RED; } else { if (active) dc->color=LTBLUE; else dc->color=BLUE; } GrCircle(dc,x,y,AbsI64(ms.pos.z)); } dc->color=LTCYAN; GrPrint(dc,(task->win_right-8)*FONT_WIDTH,0,"%03d",cnt[0]); dc->color=LTPURPLE; GrPrint(dc,(task->win_right-4)*FONT_WIDTH,0,"%03d",cnt[1]); } U0 DoAiTarget() { I64 i,j; Trooper *tmpt1,*tmpt0; for (i=0;i<10;i++) { tmpt0=&tr[0][ai_targets[i]]; for (j=0;j<10;j++) { tmpt1=&tr[1][i*10+j]; tmpt1->dx=(tmpt0->x-tmpt1->x)>>11; tmpt1->dy=(tmpt0->y-tmpt1->y)>>11; } } } U0 UpdatePos() { I64 i,j; Trooper *tmpt=tr; for (j=0;j<2;j++) for (i=0;i<TROOPERS_NUM;i++,tmpt++) { tmpt->x+=tmpt->dx; if (tmpt->x>=GR_WIDTH<<32) tmpt->x-=GR_WIDTH<<32; if (tmpt->x<0) tmpt->x+=GR_WIDTH<<32; tmpt->y+=tmpt->dy; if (tmpt->y>=GR_HEIGHT<<32) tmpt->y-=GR_HEIGHT<<32; if (tmpt->y<0) tmpt->y+=GR_HEIGHT<<32; } } U0 ResolveFiring() { I64 i,j,dd,dx,dy; Trooper *tmpt=tr,*tmpt0,*tmpt1; for (j=0;j<2;j++) for (i=0;i<TROOPERS_NUM;i++,tmpt++) { if (tmpt->target && tmpt->fire_end_time<tS) { tmpt->target->def-=tmpt->att; tmpt->fire_end_time=0; tmpt->target=NULL; } } for (i=0;i<TROOPERS_NUM;i++) { tmpt0=&tr[0][i]; for (j=0;j<TROOPERS_NUM;j++) { tmpt1=&tr[1][j]; if (tmpt0->def>0 && tmpt1->def>0) { dx=(tmpt0->x-tmpt1->x)>>32; dy=(tmpt0->y-tmpt1->y)>>32; dd=dx*dx+dy*dy; if (dd<tmpt0->rng && !tmpt0->target) { fire_end_time=tmpt0->fire_end_time=tS+0.125; Snd(86); tmpt0->target=tmpt1; } if (dd<tmpt1->rng && !tmpt1->target) { fire_end_time=tmpt1->fire_end_time=tS+0.125; Snd(86); tmpt1->target=tmpt0; } } } } if (tS>=fire_end_time) Snd; } U0 UpdateHumanVelocities() { F64 intensity; I64 i,j,dx,dy,d, x=ms.pos.x-Fs->pix_left-Fs->scroll_x, y=ms.pos.y-Fs->pix_top-Fs->scroll_y; Bool active=!winmgr.grab_scroll&&(ms.lb||ms.rb); Trooper *tmpt=&tr[0][0]; if (tap_mode) { for (i=0;i<TROOPERS_NUM;i++,tmpt++) { dx=x- tmpt->x.i32[1]; dy=y- tmpt->y.i32[1]; if ((d=dx*dx+dy*dy) && d<TAP_MODE_RADIUS*TAP_MODE_RADIUS) { intensity=SqrI64(SqrI64(SqrI64(TAP_MODE_RADIUS)-d)); dx=intensity*dx/d; dy=intensity*dy/d; tmpt->dx=tmpt->dx-dx; tmpt->dy=tmpt->dy-dy; } else { tmpt->dx-=0.2*tmpt->dx; tmpt->dy-=0.2*tmpt->dy; } } } else if (active) { j=400000000*ms.pos.z; if (ms.rb) j=-j; for (i=0;i<TROOPERS_NUM;i++,tmpt++) { dx=x- tmpt->x.i32[1]; dy=y- tmpt->y.i32[1]; if (d=dx*dx+dy*dy) { dx=j*dx/d; dy=j*dy/d; tmpt->dx=tmpt->dx-dx; tmpt->dy=tmpt->dy-dy; } } } } U0 Init() { I64 i,j,dx,dy; Trooper *tmpt; MsSet(,,25); tap_mode=FALSE; time_lapse=FALSE; fire_end_time=0; MemSet(tr,0,sizeof(tr)); for (i=0;i<10;i++) { ai_targets[i]=RandU16%TROOPERS_NUM; dx=RandI32; dy=RandI32; for (j=0;j<10;j++) { tmpt=&tr[0][i*10+j]; tmpt->x=(GR_WIDTH-100-i*10)<<32; tmpt->y=(GR_HEIGHT>>1-50+j*10)<<32; tmpt->att=3; tmpt->def=10; tmpt->rng=50*50; tmpt->animate_time_base=10*Rand; tmpt->player=0; tmpt=&tr[1][i*10+j]; tmpt->x=(100+i*10)<<32; tmpt->y=(GR_HEIGHT>>1-50+j*10)<<32; if (ai_mode==AI_RANDOM) { tmpt->dx=dx; tmpt->dy=dy; } tmpt->att=3; tmpt->def=10; tmpt->rng=50*50; tmpt->animate_time_base=10*Rand; tmpt->player=1; } } ai_mode=RandU16%AI_AI_NUM; } U0 BattleLines() { CMenuEntry *tmpse; MenuPush( "File {" " Abort(,CH_SHIFT_ESC);" " Exit(,CH_ESC);" "}" "Play {" " Restart(,'\n');" " TimeLapse(,'1');" " TapMode(,'2');" "}" ); SettingsPush; //See SettingsPush Fs->text_attr=GREEN<<4+WHITE; AutoComplete; WinBorder; WinMax; DocCursor; DocClear; Init; Fs->draw_it=&DrawIt; PopUpOk("The mouse wheel controls\n" "the command force.\n" "Attract or repel with\n" "left or right bttn.\n\n"); Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS -WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU; try { while (TRUE) { switch (ScanChar) { case '1': time_lapse=!time_lapse; tmpse=MenuEntryFind(Fs->cur_menu,"Play/TimeLapse"); tmpse->checked=time_lapse; break; case '2': tap_mode=!tap_mode; tmpse=MenuEntryFind(Fs->cur_menu,"Play/TapMode"); tmpse->checked=tap_mode; break; case CH_ESC: case CH_SHIFT_ESC: goto wg_done; case '\n': Init; break; } Sleep(40); if (ai_mode==AI_TARGET) DoAiTarget; UpdateHumanVelocities; UpdatePos; ResolveFiring; } wg_done: } catch PutExcept; SettingsPop; MenuPop; } BattleLines;