unit th;
// Модуль игры
interface
uses JSMEngine,Sys_U,Math,Audio;
const
GMWALK = 100;
GMAUTO = 101;
  MMenu = 1;
  MLogo = 0;
  MGame = 2;
  MPred = 3; // Предыстория
  MWin = 4;
  MOut = 5;
  MLoad = 6;
type
  TPoint = record
  x,y: integer;
  end;
var mouse: TPoint;
mode: integer = MLogo;
oldmode: integer = -1;
im: array[1..10] of integer;
mt: array[1..30] of integer;
gamer,mo,level,width,height,wp,au: integer;
x,y,ang,life,aum,TIMS: single;
GameMode: integer = GMWalk;

procedure DrawMap;
procedure DrawGamer;
procedure Steep;
procedure Shoot;
procedure LoadCFG;
procedure SaveCFG;
procedure GamerMove(n: single);
procedure LoadMap;
procedure DrawStat;
procedure AddBot(x,y,typs: integer);

implementation
const
  MapW = 50;
  MapH = 50;
  ShC = 200;
type
  TSh = record
  x,y,ox,oy,sx,sy: single;
  z: boolean;
  end;
  TBot = record
  x,y,timer,life,a: single;
  typ: integer; // 1,2
  z: boolean;
  end;
var
  map: array[1..MapW,1..MapH] of integer;
  bot: array[1..200] of TBot;
  cll: array[1..MapW,1..MapH] of boolean;
  dx,dy: single; ds: single;
  sh: array[1..shc] of Tsh;
  ddx,ddy: integer;

procedure DrawStat;
begin
  case GameMode of
  GMWalk:
    begin
    Eng.ShowText(10,10,'Здоровье: '+IntToStr(trunc(life))+'%',red);
    Eng.ShowText(10,40,'Патроны: '+IntToStr(wp),blue);
    end;
  GMAuto:
    begin
    Eng.ShowText(10,10,'Здоровье: '+IntToStr(trunc(life))+'%',red);
    Eng.ShowText(10,40,'Осталось: '+IntToStr(trunc(TIMS))+'m',white);
    end;  
  end;
end;

procedure Steep;
var i,j,ax,ay: integer; r: single;
begin
ang:=Math.ArcTan2(mouse.y-dy-y,mouse.x-dx-x)*180/3.14;
if Tims>0 then tims:=tims-0.05;
  if life<=0 then begin Mode:=MOut; level:=1; life:=100; end;
  if GameMode=GMWalk then
    begin
      for i:=1 to 200 do
      if bot[i].z then
      begin
        r:=sqrt(sqr(bot[i].x-x)+sqr(bot[i].y-y));
        if bot[i].typ=1 then
        begin
        bot[i].timer:=bot[i].timer-0.008;
        if bot[i].timer<=0 then bot[i].timer:=1+random(5);
        end;
          if bot[i].typ=1 then
          if bot[i].timer<=1 then
          if r<=(1-bot[i].timer)*300 then life:=life-0.2;
        if r<60 then life:=life-0.5;
        if (r<160) and (r>50) then
          begin
            if bot[i].x>x then bot[i].x:=bot[i].x-0.4;
            if bot[i].x<x then bot[i].x:=bot[i].x+0.4;
            if bot[i].y>y then bot[i].y:=bot[i].y-0.4;
            if bot[i].y<y then bot[i].y:=bot[i].y+0.4;
          end;
        if bot[i].typ=1 then
        if bot[i].life>50 then bot[i].a:=bot[i].a+5 else bot[i].a:=bot[i].a-2;
        for j:=1 to shc do
        if sh[j].z then
        if sqr(sh[j].x-bot[i].x)+sqr(sh[j].y-bot[i].y)<=sqr(30) then
        begin
          bot[i].life:=bot[i].life-34;
          sh[j].z:=false;
        end;
        if bot[i].life<=0 then bot[i].z:=false;
      end;
       dx:=400-x;
       dy:=300-y;
       ddx:=trunc(x) div 60 + 1;
       ddy:=trunc(y) div 60 + 1;
       if ddx<1 then ddx:=1; if ddx>MapW then ddx:=MapW;
       if ddy<1 then ddy:=1; if ddy>MapH then ddy:=MapH;
       case map[ddx,ddy] of
         15: begin map[ddx,ddy]:=1; wp:=wp+50; Audio.play(13); end;
         14: begin map[ddx,ddy]:=1; life:=100; Audio.play(13); end;
         20: begin Level:=level+1; SaveCFG; LoadCFG; LoadMap; end;
       end;
    end;
  if GameMode=GMAuto then
  begin
  ds:=ds-3;
  for i:=1 to 200 do
      if bot[i].z then
      begin
        //r:=sqrt(sqr(bot[i].x-x)+sqr(bot[i].y-y));
        if bot[i].x<350 then bot[i].x:=bot[i].x+0.1;
        if bot[i].x<100 then bot[i].x:=bot[i].x+0.6;
        bot[i].y:=300+200*sin(bot[i].a*3.14/1800);
        bot[i].a:=bot[i].a+1;
        if abs(bot[i].y-y)<40 then life:=life-0.05;
        for j:=1 to shc do
        if sh[j].z then
        if sqr(sh[j].x-bot[i].x)+sqr(sh[j].y-bot[i].y)<=sqr(70) then
        begin
          bot[i].life:=bot[i].life-50;
          sh[j].z:=false;
        end;
        if bot[i].life<=0 then bot[i].z:=false;
      end;  
  if ds<-100 then ds:=0;
  if tims<0.1 then begin Level:=level+1; SaveCFG; LoadCFG; LoadMap; end;
  end;
  //a:=a+1; if a>359 then a:=0;
  for i:=1 to shc do
  if sh[i].z then
  begin
    sh[i].ox:=sh[i].x;
    sh[i].oy:=sh[i].y;
    sh[i].x:=sh[i].x+sh[i].sx;
    sh[i].y:=sh[i].y+sh[i].sy;
    ax:=trunc(sh[i].x) div 60 + 1;
    ay:=trunc(sh[i].y) div 60 + 1;
    if (ax<1) or (ax>MapW) then sh[i].z:=false else
    if (ay<1) or (ay>MapH) then sh[i].z:=false else
    if cll[ax,ay] and (GameMode=GMWalk) then
      begin
      if map[ax,ay]=23 then begin map[ax,ay]:=24; cll[ax,ay]:=false; end;
      sh[i].z:=false;
      end;
    if (sh[i].x<0) or (sh[i].x>MapW*60) or (sh[i].y<0) or (sh[i].y>MapH*60) then sh[i].z:=false;
  end;
end;

procedure GamerMove(n: single);
var dx,dy: integer; xx,yy: single;
begin
  if GameMode=GMWalk then
  begin
  xx:=x+n*cos(ang*3.14/180);
  yy:=y+n*sin(ang*3.14/180);
  dx:=trunc(xx) div 60 + 1;
  dy:=trunc(yy) div 60 + 1;
  if dx<1 then dx:=1;
  if dx>50 then dx:=50;
  if dy<1 then dy:=1;
  if dy>50 then dy:=50;
  if not cll[dx,dy] then
  begin
    x:=xx;
    y:=yy;
  end;
  end;
  if GameMode=GMAuto then
  begin
    if n<0 then if y<height-100 then y:=y+0.6;
    if n>0 then if y>100 then y:=y-0.6;
  end;
end;

procedure Shoot;
var i: integer;
begin
  if wp>0 then
begin
  for i:=1 to shc do
  if not sh[i].z then
  begin
    Audio.play(au);
    if au>5 then Audio.stop(au-4);
    au:=au+1;
    if au>10 then au:=2;
    sh[i].z:=true;
    sh[i].x:=x;
    sh[i].y:=y;
    sh[i].sx:=3*cos(ang*3.14/180);
    sh[i].sy:=3*sin(ang*3.14/180);
    if GameMode=GMWalk then
    wp:=wp-1 else wp:=100;
    break;
  end;
end else Audio.play(11);  
end;

procedure DrawGamer;
var i: integer;
begin
  if GameMode=GMWalk then
  begin
  r2d.Render4(x+dx-30,y+dy-30,60,60,ang,gamer,0);
  end;
  // Рисуем роботов
  for i:=1 to 200 do
  if bot[i].z then
  begin
  if bot[i].typ=1 then
  r2d.Render4(bot[i].x-30+dx,bot[i].y-30+dy,60,60,bot[i].a,im[4+bot[i].typ],0);
  if bot[i].typ=2 then
  begin
      if abs(bot[i].y-y)<40 then
      begin
        r2d.Render4(bot[i].x,bot[i].y-35,1200,10,0,im[9],0);
        r2d.Render4(bot[i].x,bot[i].y+35,1200,10,0,im[9],0);
        r2d.DrawLine(bot[i].x,bot[i].y+40,width,bot[i].y+40,red,255);
        r2d.DrawLine(bot[i].x,bot[i].y-30,width,bot[i].y-30,red,255);
      end;
  r2d.Render4(bot[i].x-100,bot[i].y-44,200,97,0,im[4+bot[i].typ],0);
  end;
  if (bot[i].timer<=1) and (bot[i].typ=1) then
  begin
  r2d.DrawCircle(bot[i].x+dx,bot[i].y+dy,(1-bot[i].timer)*300,18,false,red,255);
  r2d.DrawCircle(bot[i].x+dx,bot[i].y+dy,(1-bot[i].timer)*250,18,false,red,255);
  end;
  end;
  if GameMode=GMAuto then
  begin
    dx:=0;
    dy:=0;
    x:=width-200;
    r2d.Render4(x-125,y-52,250,105,aum,im[7],0);
    r2d.Render4(x-50,y-50,100,100,ang,im[8],0);
    if aum>0 then aum:=aum-0.1;
    if aum<0 then aum:=aum+0.1;
  end;
  for i:=1 to shc do
  if sh[i].z then
  begin
    if gameMode=GMAuto then
      begin
        r2d.DrawCircle(sh[i].x+dx,sh[i].y+dy-10,3,6,true,White,255);
        r2d.DrawCircle(sh[i].x+dx,sh[i].y+dy+10,3,6,true,White,255);
      end
      else
      r2d.DrawCircle(sh[i].x+dx,sh[i].y+dy,3,6,true,Red,255);
  end;
end;

procedure DrawMap;
var x,y: integer;
begin
  if GameMode=GMAuto then
  begin
  for x:=1 to 10 do
  r2d.Render4((x-1)*100+ds,0,100,600,0,im[1],0);
  end;
  if GameMode=GMWalk then
  begin
    for x:=1 to MapW do
    for y:=1 to MapH do
    begin
    r2d.Render4((x-1)*60+dx,(y-1)*60+dy,60,60,0,mt[map[x,y]],0);
    if (ddx=x) and (ddy=y) then r2d.DrawCircle(ddx*60-30+dx,ddy*60-30+dy,20,18,false,red,255);
    end;
  end;
end;

procedure AddBot(x,y,typs: integer);
var i: integer;
begin
  for i:=1 to 200 do
  if not bot[i].z then
  begin
    if typs=1 then
    begin
    bot[i].x:=x*60-30;
    bot[i].y:=y*60-30;
    bot[i].life:=100;
    bot[i].timer:=random(5)+5;
    end;
    if typs=2 then
    begin
    bot[i].x:=x;
    bot[i].y:=y;
    bot[i].life:=200;
    bot[i].timer:=0;
    end;
    bot[i].typ:=typs;
    bot[i].z:=true;
    break;
  end;
end;

procedure LoadMap;
var F: TextFile; xx,yy,r: integer;
begin
  for r:=1 to 200 do
  begin
    bot[r].z:=false;
  end;
  if (level<>3) and (level<=4) then
  begin
  Assign(F,'res\mps\level'+IntToStr(level)+'.map');
  Reset(f);
  for xx:=1 to MapW do
  for yy:=1 to MapH do
  begin
    Readln(F,r);
    map[xx,yy]:=r;
    cll[xx,yy]:=false;
    if r=19 then
    begin
    x:=xx*60-30;
    y:=yy*60-30;
    map[xx,yy]:=1;
    end;
    case r of
    2..13,18,21,22,23: cll[xx,yy]:=true;
    17: begin AddBot(xx,yy,1); map[xx,yy]:=1; end;
    end;
  end;
  Close(F);
  end;
  if level=3 then begin y:=height div 2; end;
  Mode:=MLoad;
end;

procedure LoadCFG;
var F: TextFile;
begin
  Assign(F,'res\cfg\info.save');
  Reset(f);
  Readln(F,level);
  Close(F);
  wp:=20;
  life:=100;
  GameMode:=GMWalk;
  if level=3 then GameMode:=GMAuto;
  TIMS:=1000;
end;

procedure SaveCFG;
var F: TextFile;
begin
  Assign(F,'res\cfg\info.save');
  ReWrite(f);
  WriteLn(F,level);
  Close(F);
end;

end.
