unit uMain;

interface

uses windows,
     zglHeader,
     uVar,
     uzglMyPart,
     uSmoke,
     uSmplPart,
     uAdd;

procedure GameInit;
procedure GameRender;
procedure GameUpdate;
procedure GameOff;

implementation

function tu_check(): integer;
var i: integer;
begin
  result := 0;
  for I := 1 to 3 do
    if (tu_cd[i] <= 0) and (tu_ammo[i] > 0) then
       begin
         result := i;
         break;
       end;
end;

procedure tu_cds;
var i: integer;
begin
  for i := 1 to 3 do
      dec(tu_cd[i]);
end;

procedure Add_bomb(x, y, fx, fy : single);
var i: integer;
begin
    for I := 0 to 127 do
       if not bombs[i].exist then
          begin
            bombs[i].exist := true;
            bombs[i].x := x;
            bombs[i].y := y;
            bombs[i].fy:= fy;
            bombs[i].fx:= fx;
            bombs[i].ang := m_Angle(fx, fy, x, y);
            bombs[i].spd := random(50)/100 + 0.5;
            break;
          end;
end;

procedure Add_explode(x, y: single; b : word);
var j: integer;
begin
  for j := 0 to 63 do
      if not expls[j].exist then
         begin
           expls[j].exist := true;
           expls[j].x   := x;
           expls[j].y   := y;
           expls[j].r   := 6;
           expls[j].bon := b;
           if b <> 3 then AddPartGFO( texExpl, pt( x, y), 255, 4, 3) else
              AddPartGFO( texExpl, pt( x, y), 255, 4, 4);
           snd_Play( sndExpl, FALSE, CalcX2D(x), CalcY2D(y) );
           break;
         end;
end;

function Check_bomb(): boolean;
var i: integer;
begin
  result := true;
  for i := 0 to 127 do
    if bombs[i].exist then
       begin
         result := false;
         break;
       end;
end;

// 1 - скорость перезарядки  (30% шанс)
// 2 - боезапас (+2)         (25% шанс)             55
// 3 - радиус взрыва         (20% шанс)           75
// 4 - Цепная реация         (15% шанс)             90
// 5 - Осколочные снаряды    (10% шанс)          100
function Add_Prize(): integer;
var i : integer;
begin
  i := random(100);
  if (i >= 0) and (i < 31) then result := 1;
  if (i > 30) and (i < 56) then result := 2;
  if (i > 55) and (i < 76) then result := 3;
  if (i > 75) and (i < 91) then result := 4;
  if (i > 90) then result := 5;
end;

procedure NewLevel;
var i, k: integer;
begin
  if tu_bonus[1] <> 2 then tu_ammo[1]:= 5 else tu_ammo[1] := 7;
  if tu_bonus[2] <> 2 then tu_ammo[2]:= 5 else tu_ammo[2] := 7;
  if tu_bonus[3] <> 2 then tu_ammo[3]:= 5 else tu_ammo[3] := 7;

  city := city + round((100 - city)*0.25);
  for i := 2 to 63 do
    if SmPlace[i].exist then
       begin
         k := random(1000);
         if k > 500 then SmPlace[i].exist := false;
       end;
end;

procedure NewGame;
var i: integer;
begin
  for i := 0 to 63 do SmPlace[i].exist := false;
  for i := 0 to 63 do missles[i].exist := false;
  for i := 0 to 63 do expls[i].exist := false;
  for i := 0 to 63 do bombs[i].exist := false;
  plane.exist := false;
  prize.exist := false;

  tu_pos[1].x := 115;
  tu_pos[1].y := 525;
  tu_pos[2].x := 415;
  tu_pos[2].y := 525;
  tu_pos[3].x := 715;
  tu_pos[3].y := 525;

  tu_ammo[1] := 5;
  tu_ammo[2] := 5;
  tu_ammo[3] := 5;

  tu_bonus[1] := 0;
  tu_bonus[2] := 0;
  tu_bonus[3] := 0;

  tu_cd[1] := 0;
  tu_cd[2] := 0;
  tu_cd[3] := 0;

  level := 1;
  city  := 100;
  level_timer := 0;
  level_timing:= 0;
  end_timing  := 0;
  tGiO_timer  := 0;
  combo_timer := 200;
  combo_buffer:= 0;
  combo_points:= 0;
  score := 0;

  py := 200;
  px := -6500;
end;


procedure GameInit;
begin

  GUIFont2 := font_LoadFromFile( dirRes + 'Segoe Print-Regular-14pt.zfi');
  GUIFont3 := font_LoadFromFile( dirRes + 'DS-Digital-Bold-48pt.zfi');

  sndExpl := snd_LoadFromFile('data/snd/enemy_expl_fast.wav', 8);

  texLogo := tex_LoadFromFile('data/tex/logo.png');
  igdcLogo:= tex_LoadFromFile('data/tex/contest3.jpg');
  fgLogo  := tex_LoadFromFile('data/tex/fglogo.jpg');
  zglLogo := tex_LoadFromFile('data/tex/zengl.png');
  texFire := tex_LoadFromFile('data/tex/part_fire.png' );
  texExpl := tex_LoadFromFile('data/tex/expl.png' );
  texBomb := tex_LoadFromFile('data/tex/bomb.png' );
  texRock := tex_LoadFromFile('data/tex/rocket.png' );
  texPlane:= tex_LoadFromFile('data/tex/plane.png' );
  texPlne2:= tex_LoadFromFile('data/tex/plane2.png' );
  texTank := tex_LoadFromFile('data/tex/tank.png' );
  texLaun := tex_LoadFromFile('data/tex/launcher.png' );
  texSight:= tex_LoadFromFile('data/tex/sight.png');
  texAmmo := tex_LoadFromFile('data/tex/ammo.png');
  texMouse:= tex_LoadFromFile('data/tex/mouse.png');
  tex_SetFrameSize( texBomb, 36, 44);
  texSmoke:= tex_LoadFromFile('data/tex/part_smoke.png');
  tex_SetFrameSize( texSmoke, 32, 32);

  fr_samp.tex := texFire;
  fr_samp.s_w := 32;
  fr_samp.s_h := 32;
  fr_samp.sc_type := PM_RANDOM;
  fr_samp.s_scale := 2;
  fr_samp.move_type := PM_RANDOM;
  fr_samp.m_speed := 2;
  fr_samp.dir_type:= PM_Random;
  fr_samp.m_angle := 360;
  fr_samp.spin_type := PM_RANDOM;
  fr_samp.s_ang := 0.5;
  fr_samp.live_type := PM_FIXED;
  fr_samp.L_Time := 40;
  fr_samp.spin_type := PM_RANDOM;
  fr_samp.s_ang := 3;
  // создаём эмиттер
  em_fire := TEmitter.Create(1024, 30, 0);
  em_fire.SetPosition( 400, 300);
  em_fire.SetPartSample(fr_samp);
  ShowCursor(false);
  split_stage := 3;
end;

procedure GameRender;
var
  I, k: Integer; t: string;
begin
case gs of

gsSplit:
begin
   case split_stage of
    3  : SSprite2d_Draw( igdcLogo,
                         SCREEN_WIDTH / 2 - igdcLogo.Width / 2,
                         SCREEN_HEIGHT / 2 - igdcLogo.Height / 2,
                         igdclogo.Width, igdclogo.Height,  0, 255);
    1  : SSprite2d_Draw( zglLogo,
                         SCREEN_WIDTH / 2 - zglLogo.Width / 2,
                         SCREEN_HEIGHT / 2 - zglLogo.Height / 2,
                         zgllogo.Width, zgllogo.Height,  0, 255);
    2  : SSprite2d_Draw( fgLogo,
                         SCREEN_WIDTH / 2 - fgLogo.Width / 2,
                         SCREEN_HEIGHT / 2 - fgLogo.Height / 2,
                         fglogo.Width, fglogo.Height,  0, 255);
  end;
  if split_stage <> 1 then Text_DrawEx( GuiFont3, 300, 150, 5, 1, u_IntToStr(split_Stage), 128, $00ff00) else
     Text_DrawEx( GuiFont3, 350, 150, 5, 1, u_IntToStr(split_Stage), 128, $00ff00);
end;

gsStart:
begin
  pr2d_rect(0, 0,   800, 600, $5555ff, 255, pr2d_fill);
  //Text_DrawEx( GuiFont4, 150, 150, 1.5, 1, 'Clear Sky', 255, $99ff99);
  SSprite2d_Draw( texLogo, 150, 150, 564, 140, 0);

                if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 400, 800, 30)) then
                   begin
                     fx2d_SetVCA( $000000, $00FF00, $00FF00, $000000, 0 , 200, 200, 0 );
                     pr2d_Rect( 0, 400, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                     fx2d_SetVCA( $00FF00, $000000, $000000, $00FF00, 200, 0, 0, 200);
                     pr2d_Rect( 400, 400, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                   end;

                if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 430, 800, 30)) then
                   begin
                     fx2d_SetVCA( $000000, $00FF00, $00FF00, $000000, 0 , 200, 200, 0 );
                     pr2d_Rect( 0, 430, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                     fx2d_SetVCA( $00FF00, $000000, $000000, $00FF00, 200, 0, 0, 200);
                     pr2d_Rect( 400, 430, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                   end;

                if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 460, 800, 30)) then
                   begin
                     fx2d_SetVCA( $000000, $00FF00, $00FF00, $000000, 0 , 200, 200, 0 );
                     pr2d_Rect( 0, 460, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                     fx2d_SetVCA( $00FF00, $000000, $000000, $00FF00, 200, 0, 0, 200);
                     pr2d_Rect( 400, 460, 400, 30, $000000, 255, FX2D_VCA or PR2D_FILL );
                   end;


  Text_Draw( GuiFont2, 200, 400, 'Играть!' );
  Text_Draw( GuiFont2, 250, 430, 'Кто это сделал?');
  Text_Draw( GUIFont2, 300, 460, 'Я больше не могу на это смотреть!');
end;

gsCutScene:
begin
  pr2d_rect(0, 0,   800, 600, $5555ff, 255, pr2d_fill);
  if (scene_timing > 100)and(scene_timing < 500) then text_DrawEx( GuiFont2, 100, 500, 1, 1, 'Ух, тишина-то какая... Ляпота!', 255, $000000);
  if (scene_timing > 600)and(scene_timing < 1000) then text_DrawEx( GuiFont2, 100, 500, 1, 1, 'А небо такое чистое-чистое...', 255, $000000);
  if (scene_timing > 1100)and(scene_timing < 1800) then text_DrawEx( GuiFont2, 100, 500, 1, 1, 'Нигде уже такого не осталось. Везде дым, да гарь...', 255, $000000);
  if (scene_timing > 2000)and(scene_timing < 2300) then text_DrawEx( GuiFont2, 100, 500, 1, 1, 'Эх...', 255, $000000);
  if (scene_timing > 2700)and(scene_timing < 3000) then text_DrawEx( GuiFont2, 100, 500, 1, 1, 'WTF?!', 255, $000000);
  if (scene_timing > 3500)and(scene_timing < 4000) then text_DrawEx( GuiFont2, 100, 500, 1, 1, 'RAAAAAAAGGEEEEEE!!!!!!111111', 255, $000000);
  ssprite2d_draw( texPlne2, px, py, 200, 200, 0);
  DrawParts;
  Text_Draw(GuiFont2, 100, 580, 'Нажмите "Пробел", чтобы пропустить сюжетную вставку.');
end;

gsGameOver:
begin
  text_DrawEx( GuiFont3, 140, 230, 2, 0, 'GAME OVER', 255, $00ff00 );
  text_DrawEx( GuiFont3, 320, 380, 1, 0, 'SCORE', 255, $00ff00 );
  k := Length(u_IntToStr(Score));
  k := 5 - k;
  if k > 0 then
     for I := 0 to k - 1 do
       t := t + '0';
  text_DrawEx( GuiFont3, 320, 430, 1, 0, t + u_IntToStr(Score), 255, $00ff00 );
end;

gsLevel:
begin
  text_DrawEx( GuiFont3, 350, 10, 0.5, 0, 'SCORE', 255, $00ff00 );
  k := Length(u_IntToStr(Score));
  k := 5 - k;
  if k > 0 then
     for I := 0 to k - 1 do
       t := t + '0';
  text_DrawEx( GuiFont3, 350, 35, 0.5, 0, t + u_IntToStr(Score), 255, $00ff00 );

case level of
1: begin
     text_DrawEx( GuiFont3, 270, 230, 2, 0, '05 57', 255, $00ff00 );
     if level_Timer < 50 then
        text_DrawEx( GuiFont3, 400, 230, 2, 0, ':', 255, $00ff00 );
end;
2: begin
     text_DrawEx( GuiFont3, 270, 230, 2, 0, '10 43', 255, $00ff00 );
     if level_Timer < 50 then
        text_DrawEx( GuiFont3, 370, 230, 2, 0, ':', 255, $00ff00 );
   end;

3: begin
     text_DrawEx( GuiFont3, 270, 230, 2, 0, '12 00', 255, $00ff00 );
     if level_Timer < 50 then
        text_DrawEx( GuiFont3, 370, 230, 2, 0, ':', 255, $00ff00 );
end;

4: begin
     text_DrawEx( GuiFont3, 270, 230, 2, 0, '17 12', 255, $00ff00 );
     if level_Timer < 50 then
        text_DrawEx( GuiFont3, 370, 230, 2, 0, ':', 255, $00ff00 );
end;

5: begin
     text_DrawEx( GuiFont3, 270, 230, 2, 0, '21 02', 255, $00ff00 );
     if level_Timer < 50 then
        text_DrawEx( GuiFont3, 370, 230, 2, 0, ':', 255, $00ff00 );
end;

end;

end;

gsGame:
begin
  pr2d_rect(0, 0,   800, 600, $5555ff, 255, pr2d_fill);
  pr2d_rect(0, 580, 800, 60,  $00aa00, 255, pr2d_fill);

  if combo_timer < 150 then
     Text_DrawEx( guiFont2, cx, cy, 1 + combo_timer/200, 0, 'x'+u_IntToStr(Combo_points), 255 - combo_timer, $000000);

  for I := 0 to 31 do
    if missles[i].exist then
       begin
         ssprite2d_Draw( texRock, missles[i].x - 16, missles[i].y - 8, 32, 16, missles[i].ang);
       end;

  ssprite2d_Draw( texLaun, 115 - 20, 525, 32, 18, m_Angle(Mouse_X, Mouse_y, 115 - 20, 525));
  ssprite2d_Draw( texTank, 115 - 32, 530, 64, 50, 0);

  ssprite2d_Draw( texLaun, 415 - 20, 525, 32, 18, m_Angle(Mouse_X, Mouse_y, 415 - 20, 525));
  ssprite2d_Draw( texTank, 415 - 32, 530, 64, 50, 0);

  ssprite2d_Draw( texLaun, 715 - 20, 525, 32, 18, m_Angle(Mouse_X, Mouse_y, 715 - 20, 525));
  ssprite2d_Draw( texTank, 715 - 32, 530, 64, 50, 0);

  if plane.exist then
     ssprite2d_draw( texPlane, plane.x - 32, plane.y - 27, 64, 54, 0);
     pr2d_circle(plane.x, plane.y, 16, $ff0000);

 
  for I := 0 to 63 do
    if expls[i].exist then
       pr2d_circle(expls[i].x, expls[i].y, expls[i].r, $000000);
    

  for I := 0 to 127 do
    if bombs[i].exist then
       begin
         asprite2d_Draw( texBomb, bombs[i].x - 8, bombs[i].y - 10, 16, 20, 0, b_fr);
       end;

  if prize.exist then
     Text_Draw( guiFont3, prize.x, prize.y, u_IntToStr(prize.pType));

  fx_SetBlendMode( FX_BLEND_ADD );
   em_fire.Draw;
   smoke_draw();
  fx_SetBlendMode( FX_BLEND_Normal );
  drawparts;

// элементы интерфейса
  text_Draw( GuiFont2, 370, 20, 'SCORE: '  + u_IntToStr( SCORE ) );
  text_Draw( GuiFont2, 370, 50, 'Smoke: '  + u_IntToStr( 100 - CITY ) + '%' );

  if tu_bonus[1] <> 0 then Text_Draw( guiFont2, 115, 500, '*');
  if tu_bonus[2] <> 0 then Text_Draw( guiFont2, 415, 500, '*');
  if tu_bonus[3] <> 0 then Text_Draw( guiFont2, 715, 500, '*');

  if tu_cd[1] > 0 then
     begin
       pr2d_rect(115 - 21, 500, 42, 6, $dd0000);
       pr2d_rect(115 - 20, 500, 40*tu_cd[1]/250,  6, $ee0000, 255, pr2d_fill);
     end;

  if tu_ammo[1] > 0 then
     for I := 0 to tu_ammo[1] - 1 do
         ssprite2d_draw( texAmmo, 115 - 21 + i*3, 480, 16, 16, 0);

   if tu_cd[2] > 0 then
     begin
       pr2d_rect(415 - 21, 500, 42, 6, $dd0000);
       pr2d_rect(415 - 20, 500, 40*tu_cd[2]/250,  6, $ee0000, 255, pr2d_fill);
     end;

   if tu_ammo[2] > 0 then
     for I := 0 to tu_ammo[2] - 1 do
         ssprite2d_draw( texAmmo, 415 - 21 + i*3, 480, 16, 16, 0);

    if tu_cd[3] > 0 then
     begin
       pr2d_rect(715 - 21, 500, 42, 6, $dd0000);
       pr2d_rect(715 - 20, 500, 40*tu_cd[3]/250,  6, $ee0000, 255, pr2d_fill);
     end;

    if tu_ammo[3] > 0 then
     for I := 0 to tu_ammo[3] - 1 do
         ssprite2d_draw( texAmmo, 715 - 21 + i*3, 480, 16, 16, 0);

    case hint_id of
       0 :  if hint_timer < 255 then
            SSprite2d_Draw( texMouse, 275, 150, 250, 250, 0, 255 - hint_timer);
       2 :  if hint_timer < 255 then
            Text_DrawEx( GuiFont2, 300, 430, 1, 1, HINT_2, 255 - hint_timer, $000000 );
       3 :  if hint_timer < 255 then
            Text_DrawEx( GuiFont2, 270, 430, 1, 1, HINT_3, 255 - hint_timer, $000000 );
       5 :  if hint_timer < 255 then
            Text_DrawEx( GuiFont2, 270, 430, 1, 1, HINT_5, 255 - hint_timer, $000000 );
       6 :  if hint_timer < 255 then
            Text_DrawEx( GuiFont2, 270, 430, 1, 1, HINT_6, 255 - hint_timer, $000000 );
       7 :  if hint_timer < 255 then
            Text_DrawEx( GuiFont2, 270, 430, 1, 1, HINT_7, 255 - hint_timer, $000000 );
       8 :  if hint_timer < 255 then
            Text_DrawEx( GuiFont2, 270, 430, 1, 1, HINT_8, 255 - hint_timer, $000000 );
       9 :  if hint_timer < 255 then
            Text_DrawEx( GuiFont2, 270, 430, 1, 1, HINT_9, 255 - hint_timer, $000000 );
     end;

     if (level = 5) and (end_timing > 500) then
        begin
          //Text_DrawEx( GuiFont4, 150, 150, 1.5, 1, 'Clear Sky', round((end_timing - 500)/1000*255), $99ff99);
          SSprite2d_Draw( texLogo, 150, 150, 564, 140, 0, round((end_timing - 500)/1000*255));
          Text_DrawEx( GuiFont2, 300, 300,   3, 1, u_IntToStr(Score), round((end_timing - 500)/1000*255), $99ff99);
        end;
end;


end;



  ssprite2d_Draw(texSight, Mouse_x - 32, Mouse_Y - 32, 64, 64, 0);
end;

procedure GameUpdate;
var i, j, k: integer; mx, my : single;   ch : integer;
begin

case gs of

gsSplit:
begin
  inc(split_timer);
  if split_timer >= 100 then
     begin
       split_timer := 0;
       dec(split_stage);
       if split_stage < 0 then gs:=gsStart;
       
     end;
end;

gsStart:
begin
  if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 400, 800, 30)) and Mouse_Click(M_BLEFT) then
  begin
    gs := gsCutScene;
    NewGame;
    hint_id := 0;
  end;

  if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 430, 800, 30)) then
  begin

  end;

  if col2d_PointInRect(Mouse_X, Mouse_Y, r(0, 460, 800, 30)) and Mouse_Click(M_BLEFT) then
  begin
    zgl_Exit;
  end;

end;

gsCutScene:
begin
  inc(scene_timing);
  px := px + 2;
  AddPartFadeOut(texSmoke, pt(px + 120, py + 85), 255, 1, 32 + random(8), 1.5, 3.0 + random(48)/100);
  UpdParts;
  if scene_timing > 4000 then gs:=gsLevel;
  if Key_Press(K_SPACE) then gs:= gsLevel;
end;

gsGameOver:
begin
  if Key_Press(K_SPACE) or Key_Press(K_ENTER) then gs:= gsStart;
  if Mouse_Click(M_BLEFT) then gs := gsStart;
end;

gsLevel:
begin
  inc(level_timer);
  inc(start_timer);
  if level_timer > 100 then level_timer := 0;
  if start_timer > 350 then 
     begin
       start_timer := 0;
       gs:= gsGame;
       inactive := false;
     end;
  UpdParts;
  em_fire.Update;
end;
gsGame:
begin
//   кадры
  inc(frame_timer);
  if frame_timer > 10 then
     begin
       frame_timer := 0;
       inc(b_fr);
       if b_fr > 5 then b_fr := 1;
     end;

  if frame_timer div 3 = frame_timer/3 then smoke_update;
  

// кд турелей
  tu_cds;
  ch := tu_check;

// hint'ы
  inc(hint_timer);
  inc(level_timing);

// GameOver
  if City <= 00 then
     begin
       inactive := true;
       inc(tGiO_timer);
       if tGiO_timer > 300 then gs:=gsGameOver;
     end;

// начисление очков
  inc(combo_timer);
  if combo_timer >= 150 then
     begin
       // каждое комбо очко свыше 1 добавляет 5% к очкам текущей серии
       score := score + round(combo_buffer * (1 + (combo_points - 1) * 5 / 100));
       combo_points := 0;
       combo_buffer := 0;
     end;

  if prize.exist then
     begin
       k := 2;
       prize.y := prize.y + 2;
       if prize.y + 30 > 580 then
          begin
            prize.exist := false;
            if prize.x < 266 then k := 1;
            if prize.x > 534 then k := 3;
            if tu_bonus[k] <> 0 then
               for i := 1 to 3 do
                 if tu_bonus[i] = 0 then
                    begin
                      k := i;
                      break;
                    end;
            tu_bonus[k] := prize.pType;
            if prize.pType = 2 then tu_ammo[k] := tu_ammo[k] + 2;
            case prize.pType of
              1 : begin
                    hint_timer := 0;
                    hint_id    := 7;
                  end;
              2 : begin
                    hint_timer := 0;
                    hint_id    := 5;
                  end;
              3 : begin
                    hint_timer := 0;
                    hint_id    := 6;
                  end;
              4 : begin
                    hint_timer := 0;
                    hint_id    := 8;
                  end;
              5 : begin
                    hint_timer := 0;
                    hint_id    := 9;
                  end;
            end;
          end;
     end;

  randomize;
// запуск новой ракеты
  if Mouse_Click(M_BLEFT) and (ch <> 0) and not inactive then
     begin
       mx := mouse_x;
       my := mouse_y;
       for i := 0 to 31 do
         if not missles[i].exist then
            begin
              missles[i].exist := true;
              missles[i].ang := m_Angle(mx, my, tu_pos[ch].x, tu_pos[ch].y );
              missles[i].x := tu_pos[ch].x;
              missles[i].y := tu_pos[ch].y;
              missles[i].fx := Mouse_X;
              missles[i].fy := Mouse_Y;
              missles[i].spd := 1;
              missles[i].bon := tu_bonus[ch];
              dec(tu_ammo[ch]);
              if tu_ammo[ch] = 0 then
                 begin
                   hint_timer := 0;
                   hint_id    := 3;
                 end;
              if tu_bonus[ch] <> 1 then  tu_cd[ch] := 250 else tu_cd[ch] := 100;
              break;
            end;
     end;


  if Mouse_Click(M_BLEFT) and (ch = 0) and not inactive then
    begin
      hint_timer := 0;
      hint_id    := 2;
    end;

  for i := 0 to 31 do
    if missles[i].exist then
       begin
         missles[i].spd := missles[i].spd + 0.2;
         missles[i].x := missles[i].x + m_cos(round(missles[i].ang))*missles[i].spd;
         missles[i].y := missles[i].y + m_sin(round(missles[i].ang))*missles[i].spd;

         AddPartFadeOut(texSmoke, pt(missles[i].x - 16 * m_cos(round(missles[i].ang + 30)), missles[i].Y - 8*m_Sin(round(missles[i].ang + 30))), 255, 5 + random(10), 16, 1.5, 3.0 + random(28)/100);

         if (missles[i].x < 0) or (missles[i].x > 800) or (missles[i].y < 0) or (missles[i].y > 600)  then missles[i].exist:=false;

         // взрыв
         if m_Distance(missles[i].x, missles[i].y, missles[i].fx, missles[i].fy) < 9 then
            begin
              missles[i].exist := false;
              add_explode(missles[i].x, missles[i].y, missles[i].bon);
            end;
       end;


  for I := 0 to 63 do
    if expls[i].exist then
       begin
         if expls[i].bon <> 3 then expls[i].r := expls[i].r + 1.5 else expls[i].r := expls[i].r + 2;
         if (expls[i].r > 70) and (expls[i].bon <> 3) then expls[i].exist := false;
         if (expls[i].r > 90) and (expls[i].bon =  3) then expls[i].exist := false;
       end;

  if plane.exist then
     begin
       plane.x := plane.x + plane.spd;

       if random(100) > plane.hp then
           AddPartFadeOut(texSmoke, pt(plane.x, plane.Y), 255, 5 + random(10), 16, plane.spd, 3.0 + random(28)/100);



       inc(plane.bcd);
       if (plane.bcd > 200) and (plane.x > 0) and (plane.x < 800) then // бросок бомбы самолётом
          begin
            add_bomb(plane.x, plane.y, random(800), 580);
            plane.bcd := 0;
          end;
        for j := 0 to 63 do // проверка на взрыв
           begin
             if expls[j].exist then
             if col2d_Circle(c(plane.x, plane.y, 16),
                             c(expls[j].x, expls[j].y, expls[j].r)) then
                begin
                  plane.hp := plane.hp - 1;
                  if plane.hp <= 0 then
                     begin
                       score := score + 250;
                       em_fire.SetEmitParams(250, 0);
                       em_fire.SetPosition(plane.x - 50 + random(100), plane.y  - 50 + random(100));
                       em_fire.newloop;
                       em_fire.SetEmitParams(100, 0);
                       plane.exist := false;
                       prize.exist := true;
                       prize.x     := plane.x - 50;
                       prize.y     := plane.y - 50;
                       prize.pType := Add_Prize;
                       Add_Explode(plane.x, plane.y, 0);
                     end;
                  break;
                end;
           end;
     end;

  case level of
    1 : begin
          if level_timing = 200 then
             for I := 0 to 2 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 550 then
             for I := 0 to 5 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 1100 then
             for I := 0 to 7 do
               Add_Bomb(random(800), 0, random(800), 580);

          if (level_timing > 1100) and Check_bomb then
             begin
               inactive := true;
               inc(end_timing);
               if end_timing > 500 then
                  begin
                    gs := gsLevel;
                    level_timer := 0;
                    level_timing:= 0;
                    end_timing  := 0;
                    NewLevel;
                    inc(level);
                  end;
             end;
        end;

     2 : begin
          if level_timing = 300 then
             for I := 0 to 7 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 850 then
             begin
               plane.x := 800;
               plane.y := 200;
               plane.spd := -0.5;
               plane.hp  := 75;
               plane.exist := true;
             end;
          if level_timing = 1600 then
             for I := 0 to 11 do
               Add_Bomb(random(800), 0, random(800), 580);

          if (level_timing > 1600) and Check_bomb then
             begin
               inactive := true;
               inc(end_timing);
               if end_timing > 500 then
                  begin
                    gs := gsLevel;
                    level_timer := 0;
                    level_timing:= 0;
                    end_timing  := 0;
                    NewLevel;
                    inc(level);
                  end;
             end;
        end;

     3 : begin
          if level_timing = 200 then
             for I := 0 to 3 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 350 then
             for I := 0 to 3 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 500 then
             for I := 0 to 3 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 750 then
             for I := 0 to 3 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 550 then
             begin
               plane.x := 800;
               plane.y := 200;
               plane.spd := -0.5;
               plane.hp  := 75;
               plane.exist := true;
             end;
          if level_timing = 1500 then
             for I := 0 to 15 do
               Add_Bomb(random(800), 0, random(800), 580);

          if (level_timing > 1500) and Check_bomb then
             begin
               inactive := true;
               inc(end_timing);
               if end_timing > 500 then
                  begin
                    gs := gsLevel;
                    level_timer := 0;
                    level_timing:= 0;
                    end_timing  := 0;
                    NewLevel;
                    inc(level);
                  end;
             end;
        end;
     4 : begin
          if level_timing = 250 then
             begin
               plane.x := 800;
               plane.y := 200;
               plane.spd := -0.5;
               plane.hp  := 75;
               plane.exist := true;
             end;
          if level_timing = 400 then
             for I := 0 to 7 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 850 then
             for I := 0 to 7 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 1100 then
             for I := 0 to 0 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 1500 then
             for I := 0 to 15 do
               Add_Bomb(random(800), 0, random(800), 580);

          if (level_timing > 1500) and Check_bomb then
             begin
               inactive := true;
               inc(end_timing);
               if end_timing > 500 then
                  begin
                    gs := gsLevel;
                    level_timer := 0;
                    level_timing:= 0;
                    end_timing  := 0;
                    NewLevel;
                    inc(level);
                  end;
             end;
        end;
     5 : begin
         if level_timing = 200 then
             for I := 0 to 7 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 550 then
             for I := 0 to 10 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 900 then
             for I := 0 to 13 do
               Add_Bomb(random(800), 0, random(800), 580);


          if level_timing = 2000 then
             for I := 0 to 10 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 2300 then
             for I := 0 to 13 do
               Add_Bomb(random(800), 0, random(800), 580);
          if level_timing = 2600 then
             for I := 0 to 16 do
               Add_Bomb(random(800), 0, random(800), 580);



          if (level_timing > 2600) and Check_bomb then
             begin
               inactive := true;
               inc(end_timing);
               if end_timing > 1500 then
                  begin
                    gs := gsStart;
                  end;
             end;
        end;
  end;


  for I := 0 to 127 do
    if bombs[i].exist then
       begin
         bombs[i].x := bombs[i].x + m_cos(round(bombs[i].ang))*bombs[i].spd;
         bombs[i].y := bombs[i].y + m_sin(round(bombs[i].ang))*bombs[i].spd;
         AddPartFadeOut(texSmoke, pt(bombs[i].x - 6, bombs[i].y - 6), 255, 2, 6, random(10)/100, -1.5 + random(5)/100);

         if bombs[i].y >= 580 then
            begin
              bombs[i].exist := false;
              city := city - round((1 - bombs[i].spd)*25);
              em_fire.SetPosition(bombs[i].x, bombs[i].y);
              em_fire.newloop;
              for j := 0 to 63 do
                if not SmPlace[j].exist then
                   begin
                     SmPlace[j].exist := true;
                     SmPlace[j].x := bombs[i].x;
                     break;
                   end;
            end;

         for j := 0 to 63 do
           begin
             if expls[j].exist then
             if col2d_Circle(c(bombs[i].x, bombs[i].y, 4),
                             c(expls[j].x, expls[j].y, expls[j].r)) then
                begin
                  bombs[i].exist := false;

                  combo_buffer := combo_buffer + 25;
                  combo_timer  := 0;
                  inc(combo_points);
                  cx := bombs[i].x - 50;
                  cy := bombs[i].y - 25;


                  if expls[j].bon = 4 then Add_Explode(bombs[i].x, bombs[i].y, 4);
                  if expls[j].bon = 5 then
                     for k := 0 to 4 do
                         AddSw(pt(bombs[i].x, bombs[i].y), random(627)/100, random(4), 100);
                  em_fire.SetPosition(bombs[i].x, bombs[i].y);
                  em_fire.newloop;
                  break;
                end;
           end;
         for j := 0 to 127 do
           begin
             if sw[j].exist then
             if col2d_Circle(c(bombs[i].x, bombs[i].y, 4),
                             c(sw[j].pos.X, sw[j].pos.y, 12)) then
                begin
                  bombs[i].exist := false;

                  combo_buffer := combo_buffer + 25;
                  combo_timer  := 0;
                  inc(combo_points);
                  cx := bombs[i].x - 50;
                  cy := bombs[i].y - 25;

                  for k := 0 to 4 do
                      AddSw(pt(bombs[i].x, bombs[i].y), random(627)/100, random(4), 100);
                  em_fire.SetPosition(bombs[i].x, bombs[i].y);
                  em_fire.newloop;
                  break;
                end;
           end;
       end;

  for I := 0 to 63 do
    if SmPlace[i].exist then
       AddPartFadeOut(texSmoke, pt(SmPlace[i].x - 10 + random(20), 600), 255, 1 + random(5), 16 + random(8), random(200)/100, -1.5 + random(10)/100);

  if  zgl_Get( RENDER_FPS ) < 24 then em_fire.SetEmitParams(30, 0) else em_fire.SetEmitParams(100, 0);

  UpdParts;
  em_fire.Update;
end;

end;

end;

procedure GameOff;
begin
  em_fire.Free;
end;

end.
