unit _World;

interface

uses
  OpenGL,
  _OpenGL,
  _Geometry,
  _Noise,
  _Forms,
  _SysUtils,
  _2d;

Const
  //texture
  ws=512;
  hs=512;

  //map
  l_Size = 40;
  Ocean_Size = 1000;
  //bots
  max_bots = 39;
  //vp
  max_vp = 10;  
  max_bullets = 5000;
  max_parts = 10000;
  //map
  map_x = 99;
  map_y = 99;

  max_vic_points = 50000;
  max_frags = 100;

  life_maximum = 100;

type

 TBot = record
  tip:byte; {0-none 1-bot 2-cannon}
  poz,np:TPoint;
  Ang:TPoint;{AX,AY,AZ of plain corpus}
  speed,jump:single;
  H:single;
  Life,step_anim:Integer;
  make_fire:boolean;
  Side:byte;
  //cel
  wp,ma:single;
  cx,cy,target:byte;
  //gun
  bullets:integer;
  rel:byte;
  cel:integer;
  fail_grad:byte;
  anim:byte;
 end;

 TVictory_point = record
//  tip:byte; {0-none 1-bot 2-cannon}
  poz:TPoint;
  Life:Integer;
  Side:byte;
 end;

 TBullet = record
  Poz,PPoz:TPoint;
  Vect:TPoint;
  tip:byte;//0-none 1-usual
  damage:integer;
  side,life:byte;
 end;

 Tpart = record
  Poz:TPoint;
  Vect:TPoint;
  tip:byte;//0-none 1-usual
  life:byte;
 end;

 TMap = record
   tip:byte;//0-none 1-half wall 2-full wall
   view:integer;
   side:byte;
   sel:boolean;
 end;

 TWorld = class
   private
    Water_Texture,
    Cloud_Texture:Cardinal;
    K,CK:TPoint;
    control_:boolean;
    //plains
    procedure Draw_Ocean;
    procedure draw_Bots;        
    procedure Draw_Bullets;
    procedure Draw_Parts;
    procedure Generate_Texture;
    Procedure Draw_Pricel; 
    procedure Draw_Map;
    procedure add_map(t,x,y:byte);   
    procedure fire_bot(num:integer);
    procedure move_bot(num:byte;ang:single);
    procedure clear_map;
 //   Procedure jump(num:byte);
   public                   
    game_mode:byte;
    AX,AY,PX,PY,AL:single;//rotate/scale
    Wind,Gravity:Tpoint;//wind(x,y) and gravity(z)
    Bot:Array [0.. max_Bots] of TBot;
    bullet:Array [0.. max_bullets] of TBullet;
    part:Array [0.. max_parts] of Tpart;
    map:Array [0.. map_x,0..map_y] of TMap;
    player_bot:integer;
    map_view:boolean;
    sit:boolean;//player_sit
    pain:array[0..3] of byte;
    points:array[0..4] of integer;    
    message_time:byte;
    Constructor Create;
    Procedure Render;
    procedure Move;
    procedure Control(cx,cy,cz:single);
    Procedure Jump(i:byte);
    Procedure reload;
    procedure fire;
    procedure Granade;
    Procedure add_bullet(poz,vect:TPoint;tip,damage,side:byte);
    Procedure add_part(poz,vect:TPoint;tip:byte);
    procedure gen_random_level(tip:byte);
    procedure show_message(str:string);  
    procedure mess;
    procedure on_planet;
 end;

Var World:TWorld;
    test:Single;
    sp:TPoint;

implementation
//texture

{$REGION 'sun'}
procedure Set_Sun;
Var
 p:TPlane;
begin
 p:=Plane(Get_X_V(test,10),Get_Y_V(test,10),15,1);
 glLightFV(Gl_LIGHT0,Gl_Position,@p);          {ligth pozition}
// test:=Get_R(Test+1);
end;
{$ENDREGION}

{$REGION 'Show_message'}
procedure TWorld.show_message(str:string);
begin
 message_time:=190;
 Menu.Panel[7].Text:=str;
end;
{$ENDREGION}

{$REGION 'Gen texture'}
function GenTexture(mode:cardinal;Var pData: Pointer;Width: LongWord;Height: LongWord; var Texture: GLuint): Boolean;
begin
  if (Assigned(pData)) then
    Result := True
  else
  begin
    Result := False;
    exit;
  end;
  glGenTextures(1, @Texture);
  glBindTexture(GL_TEXTURE_2D, Texture);
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  {Texture blends with object background}
//  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);  {Texture does NOT blend with object background}
//  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);  {Texture does NOT blend with object background}
//  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);  {Texture does NOT blend with object background}
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,mode);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,mode);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { only first two can be used }
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); { all of the above can be used }
//  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, pData);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pData);  // Use when not wanting mipmaps to be built by openGL
end;
{$ENDREGION}

{$REGION 'Gen_tex'}
procedure TWorld.Generate_Texture;
var
  i,j,ws,hs:integer;        {для циклов}
  TA:array of byte;
  S:Pointer;
begin
 ws:=64;
 hs:=64;
 SetLength(TA,ws*hs*4);
 For j:=0 to hs-1 do {проходим все строки}
  For i:=0 to ws-1 do {элементы в строке}
  begin
   {TA[i*4+(j)*ws*4+0]:=100+Random(125);
   TA[i*4+(j)*ws*4+1]:=100+Random(125);
   TA[i*4+(j)*ws*4+2]:=100+Random(125);       }
   TA[i*4+(j)*ws*4+0]:=100+Random(25);
   TA[i*4+(j)*ws*4+1]:=140+Random(15){+80*(((trunc(i/8)+trunc(j/8)) mod 2))};
   TA[i*4+(j)*ws*4+2]:=100+Random(25) ;
   TA[i*4+(j)*ws*4+3]:=255;
  end;
 S:=TA;
 GenTexture(GL_Repeat,S,Ws,Hs,Water_Texture);
end;
{$ENDREGION}

{$REGION 'add_map'}
procedure TWorld.add_map(t,x,y:byte);
begin
 if (x<2) or (x>map_x-2) or (y<2) or (y>map_y-2) then exit;
 if (map[x,y].tip=3) or
    (map[x+1,y].tip=3) or
    (map[x,y+1].tip=3) or
    (map[x-1,y].tip=3) or
    (map[x,y-1].tip=3) then exit;
 case t of
  1:begin
     map[x+1,y].tip:=1;
     map[x,y].tip:=1;
     map[x-1,y].tip:=1;
    end;
  2:begin
     map[x,y+1].tip:=1;
     map[x,y].tip:=1;
     map[x,y-1].tip:=1;
    end;
  3:begin
     map[x+1,y].tip:=2;
     map[x,y].tip:=2;
     map[x-1,y].tip:=2;
    end;
  4:begin
     map[x,y+1].tip:=2;
     map[x,y].tip:=2;
     map[x,y-1].tip:=2;
    end;
 end;
 map[x,y].view:=t;
end;
{$ENDREGION}

{$REGION 'Create'}
Constructor TWorld.Create;
var
 i,j,n,m:byte;
 p:TPoint;
begin
 Create_Noise();
 Generate_Texture();       
 glEnable(Gl_alpha_test);
 glClearColor(0.4,0.4,0.9,1);
 Preload(100);
 gen_random_level(0);
 on_planet;
 K:=Point(0,0,0);
 AL:=400;
 PX:=90;
 map_view:=false;
 Show_Message('Тактик вошел в систему.');
end;
{$ENDREGION}

{$REGION 'ocean'}
procedure TWorld.Draw_Ocean;
begin
 //sea          
 glPushMatrix();    
 glTranslatef(-K[0],-K[1],-K[2]);
 glEnable(Gl_Texture_2d);
 glBindTexture(GL_Texture_2d,Water_Texture);
 glDisable(GL_Lighting);
 glBegin(gl_Quads);
 glColor3f(1,1,1);
 //glColor3f(1,1,1);
 glNormal3f(-10,-10,1);
 glTexCoord2f( 4,-4);glVertex3f(Round(k[0]/10)*10-l_Size,Round(k[1]/10)*10+l_Size,0);
 glTexCoord2f(-4,-4);glVertex3f(Round(k[0]/10)*10+l_Size,Round(k[1]/10)*10+l_Size,0);
 glTexCoord2f(-4, 4);glVertex3f(Round(k[0]/10)*10+l_Size,Round(k[1]/10)*10-l_Size,0);
 glTexCoord2f( 4, 4);glVertex3f(Round(k[0]/10)*10-l_Size,Round(k[1]/10)*10-l_Size,0);
 glTexCoord2f(-Ocean_Size/10, Ocean_Size/10);glVertex3f(-Ocean_Size, Ocean_Size,-0.01);
 glTexCoord2f( Ocean_Size/10, Ocean_Size/10);glVertex3f( Ocean_Size, Ocean_Size,-0.01);
 glTexCoord2f( Ocean_Size/10,-Ocean_Size/10);glVertex3f( Ocean_Size,-Ocean_Size,-0.01);
 glTexCoord2f(-Ocean_Size/10,-Ocean_Size/10);glVertex3f(-Ocean_Size,-Ocean_Size,-0.01);
 glEnd;
 glPopMatrix();
end;
{$ENDREGION}

{$REGION 'messs'}
procedure TWorld.mess;
begin
 if (message_time=0) then
  Menu.Panel[7].Text:='' else
   message_time:=message_time-1;
end;
{$ENDREGION}

{$REGION 'Bot'}
procedure put_bot(col,anim:byte);
var i,j:integer;
begin
 case col of
  0:glColor4f(1,1,1,1);//gray   
  1:glColor4f(1,0,0,1);//red    
  2:glColor4f(0,0,1,1);//blue
  3:glColor4f(0,1,0,1);//green
  4:glColor4f(1,1,0,1);//yellow
 end;
 glDisable(Gl_Texture_2d);
 //corps
 glBegin(GL_Quads);
 for i:=0 to 4 do
   begin
     glNormal3f(Get_x_v(i*90+90,1),Get_y_v(i*90+90,1),0);
     glVertex3f(Get_x_v(i*90+45,0.2),Get_y_v(i*90+45,0.12),0.5);
     glVertex3f(Get_x_v(i*90+45,0.2),Get_y_v(i*90+45,0.12),1.0);
     glVertex3f(Get_x_v(i*90+135,0.2),Get_y_v(i*90+135,0.12),1.0);
     glVertex3f(Get_x_v(i*90+135,0.2),Get_y_v(i*90+135,0.12),0.5);
   end;
 glNormal3f(0,0,1);
 for i:=0 to 3 do
   begin
     glVertex3f(Get_x_v(-i*90+45,0.2),Get_y_v(-i*90+45,0.12),1.0);
   end;

 for i:=0 to 3 do
   begin
     glNormal3f(Get_x_v(i*90+90,1),Get_y_v(i*90+90,1),0);
     glVertex3f(Get_x_v(i*90+45,0.08) +0.08,Get_y_v(i*90+45,0.12) ,0.0 +anim/128*0.24);
     glVertex3f(Get_x_v(i*90+45,0.08) +0.08,Get_y_v(i*90+45,0.08) ,0.35+anim/128*0.24);
     glVertex3f(Get_x_v(i*90+135,0.08)+0.08,Get_y_v(i*90+135,0.08),0.35+anim/128*0.24);
     glVertex3f(Get_x_v(i*90+135,0.08)+0.08,Get_y_v(i*90+135,0.12),0.0 +anim/128*0.24);
   end;
 glNormal3f(Get_x_v(i*90+90,1),Get_y_v(i*90+90,1),1);
 for i:=0 to 3 do
   begin
     glVertex3f(-Get_x_v(i*90+45,0.08) +0.08,Get_y_v(i*90+45,0.08) ,0.35+anim/128*0.24);
   end;
 for i:=0 to 3 do
   begin
     glNormal3f(Get_x_v(i*90+90,1),Get_y_v(i*90+90,1),0);
     glVertex3f(Get_x_v(i*90+45,0.08) -0.08,Get_y_v(i*90+45,0.12) ,0.0 +0.24-anim/128*0.24);
     glVertex3f(Get_x_v(i*90+45,0.08) -0.08,Get_y_v(i*90+45,0.08) ,0.35+0.24-anim/128*0.24);
     glVertex3f(Get_x_v(i*90+135,0.08)-0.08,Get_y_v(i*90+135,0.08),0.35+0.24-anim/128*0.24);
     glVertex3f(Get_x_v(i*90+135,0.08)-0.08,Get_y_v(i*90+135,0.12),0.0 +0.24-anim/128*0.24);
   end;
 glNormal3f(Get_x_v(i*90+90,1),Get_y_v(i*90+90,1),1);
 for i:=0 to 3 do
   begin
     glVertex3f(-Get_x_v(i*90+45,0.08) -0.08,Get_y_v(i*90+45,0.08) ,0.35+0.24-anim/128*0.24);
   end;
 glend;

{ glBegin(GL_Quad_strip);
 for i:=0 to 6 do
   begin
     glNormal3f(Get_x_v(i*60,1),0,Get_y_v(i*60,1));
     glVertex3f(Get_x_v(i*60,0.16),Get_y_v(i*60,0.12),0.0);
     glVertex3f(Get_x_v(i*60,0.16),Get_y_v(i*60,0.12),1.0);
   end;
 glend; }
end;

procedure put_cannon(col:byte);
var i,j:integer;
begin
 case col of
  0:glColor4f(1,1,1,1);//gray
  1:glColor4f(1,0,0,1);//red
  2:glColor4f(0,0,1,1);//blue      
  3:glColor4f(0,1,0,1);//green  
  4:glColor4f(1,1,0,1);//yellow
 end;
 glDisable(Gl_Texture_2d);
 //corps
 glBegin(GL_Quads);
   glNormal3f(0,0,1);
 for i:=0 to 3 do
  begin
   glVertex3f(Get_y_v(i*90+45,0.3),Get_x_v(i*90+45,0.6),0.15);
  end;
   glNormal3f(0,0,-1);
 for i:=0 to 3 do
  begin
   glVertex3f(Get_x_v(i*90+45,0.3),Get_y_v(i*90+45,0.6),-0.15);
  end;
 for i:=0 to 3 do
  begin
   glNormal3f(Get_y_v(i*90+90,1),Get_x_v(i*90+90,1),0);
   glVertex3f(Get_y_v(i*90+45,0.3),Get_x_v(i*90+45,0.6),0.15);
   glVertex3f(Get_y_v(i*90+45,0.3),Get_x_v(i*90+45,0.6),-0.15);
   glVertex3f(Get_y_v(i*90+135,0.3),Get_x_v(i*90+135,0.6),-0.15);
   glVertex3f(Get_y_v(i*90+135,0.3),Get_x_v(i*90+135,0.6),0.15);
  end;
 glend;
end;

procedure put_platf(col:byte);
var i,j:integer;
begin
 case col of
  0:glColor4f(1,1,1,1);//gray
  1:glColor4f(1,0,0,1);//red
  2:glColor4f(0,0,1,1);//blue      
  3:glColor4f(0,1,0,1);//green  
  4:glColor4f(1,1,0,1);//yellow
 end;
 glDisable(Gl_Texture_2d);
 //corps
 glBegin(GL_Quads);
   glNormal3f(0,0,1);
 for i:=0 to 3 do
  begin
   glVertex3f(Get_y_v(i*90+20,0.5),Get_x_v(i*90+20,0.5),0.4);
  end;
 for i:=0 to 3 do
  begin
   glNormal3f(Get_y_v(i*90+45+20,1),Get_x_v(i*90+45+20,1),0);
   glVertex3f(Get_y_v(i*90+20,0.5),Get_x_v(i*90+20,0.5),0.4);
   glVertex3f(Get_y_v(i*90+20,0.5),Get_x_v(i*90+20,0.5),0.0);
   glVertex3f(Get_y_v(i*90+90+20,0.5),Get_x_v(i*90+90+20,0.5),0.0);
   glVertex3f(Get_y_v(i*90+90+20,0.5),Get_x_v(i*90+90+20,0.5),0.4);
  end;
 glend;
end;
  
procedure put_marker(col:byte);
var i,j:integer;
begin
 case col of
  0:glColor4f(1,1,1,1);//gray
  1:glColor4f(1,0,0,1);//red
  2:glColor4f(0,0,1,1);//blue      
  3:glColor4f(0,1,0,1);//green
  4:glColor4f(1,1,0,1);//yellow
 end;
 glDisable(Gl_Texture_2d);
 //corps
 glBegin(GL_Triangle_fan);
 glVertex3f(0,0,0.1);
 for i:=0 to 6 do
   begin
     glNormal3f(0,0,1);
     glVertex3f(Get_y_v(i*60,0.4),Get_x_v(i*60,0.4),0.1);
   end;
 glend;
end;
{$ENDREGION}

{$REGION 'Bullet'}
procedure put_Bullet(poz,ppoz:TPoint;tip:byte);
var i:integer;
t:TPoint;
begin
 //corps
 glColor4f(0.5,0.5,0.5,1);
 case tip of
  1:glColor4f(0.5,0.0,0.0,1);
  2:glColor4f(0.0,0.0,0.5,1);
  3:glColor4f(0.0,0.5,0.0,1);
  4:glColor4f(0.5,0.5,0.0,1);
 end;
 t:=plus(poz,multi(minus(ppoz,poz),0.3));
 glBegin(gl_triangles);
  glVertex3f(poz[0],poz[1],poz[2]-0.05);
  glVertex3f(poz[0],poz[1],poz[2]+0.05);
  glVertex3f(t[0],t[1],t[2]);
  glVertex3f(poz[0],poz[1],poz[2]+0.05);
  glVertex3f(poz[0],poz[1],poz[2]-0.05);
  glVertex3f(t[0],t[1],t[2]);
 glend;

 glBegin(gl_quads);
  glVertex3f(poz[0]+sp[0]*0.05,poz[1]+sp[1]*0.05,poz[2]);
  glVertex3f(poz[0]           ,poz[1]           ,poz[2]+0.05);
  glVertex3f(poz[0]-sp[0]*0.05,poz[1]-sp[1]*0.05,poz[2]);
  glVertex3f(poz[0]           ,poz[1]           ,poz[2]-0.05);
 glend;
end;
{$ENDREGION}

{$REGION 'Map'}
procedure put_Map(tip:byte);
var i:integer;
begin
 glColor3f(0.5,0.5,0.5);
 case tip of
  1:begin
     glbegin(gl_Quads);
     //up
      glNormal3f(0,0,1);
      glVertex3f( 0.05-1, 0.05,0.6);
      glVertex3f( 0.05-1, 0.95,0.6);
      glVertex3f( 0.95+1, 0.95,0.6);
      glVertex3f( 0.95+1, 0.05,0.6);
     //sides
      glNormal3f(-1,0,0);
      glVertex3f( 0.05-1, 0.95,0.6);
      glVertex3f( 0.05-1, 0.05,0.6);
      glVertex3f( 0.05-1, 0.05,0.0);
      glVertex3f( 0.05-1, 0.95,0.0);

      glNormal3f(+1,0,0);
      glVertex3f( 0.95+1, 0.05,0.6);
      glVertex3f( 0.95+1, 0.95,0.6);
      glVertex3f( 0.95+1, 0.95,0.0);
      glVertex3f( 0.95+1, 0.05,0.0);

      glNormal3f(0,-1,0);
      glVertex3f( 0.05-1, 0.05,0.6);
      glVertex3f( 0.95+1, 0.05,0.6);
      glVertex3f( 0.95+1, 0.05,0.0);
      glVertex3f( 0.05-1, 0.05,0.0);

      glNormal3f(0,+1,0);
      glVertex3f( 0.95+1, 0.95,0.6);
      glVertex3f( 0.05-1, 0.95,0.6);
      glVertex3f( 0.05-1, 0.95,0.0);
      glVertex3f( 0.95+1, 0.95,0.0);
     glend;
    end;//half north
  2:begin
     glbegin(gl_Quads);
     //up
      glNormal3f(0,0,1);
      glVertex3f( 0.05, 0.05-1,0.6);
      glVertex3f( 0.05, 0.95+1,0.6);
      glVertex3f( 0.95, 0.95+1,0.6);
      glVertex3f( 0.95, 0.05-1,0.6);
     //sides
      glNormal3f(-1,0,0);
      glVertex3f( 0.05, 0.95+1,0.6);
      glVertex3f( 0.05, 0.05-1,0.6);
      glVertex3f( 0.05, 0.05-1,0.0);
      glVertex3f( 0.05, 0.95+1,0.0);

      glNormal3f(+1,0,0);
      glVertex3f( 0.95, 0.05-1,0.6);
      glVertex3f( 0.95, 0.95+1,0.6);
      glVertex3f( 0.95, 0.95+1,0.0);
      glVertex3f( 0.95, 0.05-1,0.0);

      glNormal3f(0,-1,0);
      glVertex3f( 0.05, 0.05-1,0.6);
      glVertex3f( 0.95, 0.05-1,0.6);
      glVertex3f( 0.95, 0.05-1,0.0);
      glVertex3f( 0.05, 0.05-1,0.0);

      glNormal3f(0,+1,0);
      glVertex3f( 0.95, 0.95+1,0.6);
      glVertex3f( 0.05, 0.95+1,0.6);
      glVertex3f( 0.05, 0.95+1,0.0);
      glVertex3f( 0.95, 0.95+1,0.0);
     glend;
    end;//half west
  3:begin
     glbegin(gl_Quads);
     //up
      glNormal3f(0,0,1);
      glVertex3f( 0.05-1, 0.05,1.0);
      glVertex3f( 0.05-1, 0.95,1.0);
      glVertex3f( 0.95+1, 0.95,1.0);
      glVertex3f( 0.95+1, 0.05,1.0);
     //sides
      glNormal3f(-1,0,0);
      glVertex3f( 0.05-1, 0.95,1.0);
      glVertex3f( 0.05-1, 0.05,1.0);
      glVertex3f( 0.05-1, 0.05,0.0);
      glVertex3f( 0.05-1, 0.95,0.0);

      glNormal3f(+1,0,0);
      glVertex3f( 0.95+1, 0.05,1.0);
      glVertex3f( 0.95+1, 0.95,1.0);
      glVertex3f( 0.95+1, 0.95,0.0);
      glVertex3f( 0.95+1, 0.05,0.0);

      glNormal3f(0,-1,0);
      glVertex3f( 0.05-1, 0.05,1.0);
      glVertex3f( 0.95+1, 0.05,1.0);
      glVertex3f( 0.95+1, 0.05,0.0);
      glVertex3f( 0.05-1, 0.05,0.0);

      glNormal3f(0,+1,0);
      glVertex3f( 0.95+1, 0.95,1.0);
      glVertex3f( 0.05-1, 0.95,1.0);
      glVertex3f( 0.05-1, 0.95,0.0);
      glVertex3f( 0.95+1, 0.95,0.0);
     glend;
    end;//full north
  4:begin
     glbegin(gl_Quads);
     //up
      glNormal3f(0,0,1);
      glVertex3f( 0.05, 0.05-1,1.0);
      glVertex3f( 0.05, 0.95+1,1.0);
      glVertex3f( 0.95, 0.95+1,1.0);
      glVertex3f( 0.95, 0.05-1,1.0);
     //sides
      glNormal3f(-1,0,0);
      glVertex3f( 0.05, 0.95+1,1.0);
      glVertex3f( 0.05, 0.05-1,1.0);
      glVertex3f( 0.05, 0.05-1,0.0);
      glVertex3f( 0.05, 0.95+1,0.0);

      glNormal3f(+1,0,0);
      glVertex3f( 0.95, 0.05-1,1.0);
      glVertex3f( 0.95, 0.95+1,1.0);
      glVertex3f( 0.95, 0.95+1,0.0);
      glVertex3f( 0.95, 0.05-1,0.0);

      glNormal3f(0,-1,0);
      glVertex3f( 0.05, 0.05-1,1.0);
      glVertex3f( 0.95, 0.05-1,1.0);
      glVertex3f( 0.95, 0.05-1,0.0);
      glVertex3f( 0.05, 0.05-1,0.0);

      glNormal3f(0,+1,0);
      glVertex3f( 0.95, 0.95+1,1.0);
      glVertex3f( 0.05, 0.95+1,1.0);
      glVertex3f( 0.05, 0.95+1,0.0);
      glVertex3f( 0.95, 0.95+1,0.0);
     glend;
    end;//full west
 end;
 //corps
end;
{$ENDREGION}

{$REGION 'victory point'}
procedure put_vp(col:byte;a:integer);
var
 i:byte;
 s:single;
begin
 s:=0.6+cos(a/5)*0.5;
 case col of
  0:glColor4f(5,5,5,s);//gray
  1:glColor4f(5,0,0,s);//red
  2:glColor4f(0,0,5,s);//blue
  3:glColor4f(0,5,0,s);//green
  4:glColor4f(5,5,0,s);//yellow
 end;
 //corps
 glBegin(GL_Quads);
   glNormal3f(0,0,1);
   glVertex3f(0-0.5,0,0.0);
   glVertex3f(0+0.5,0,0.0);
 case col of
  0:glColor4f(5,5,5,0);//gray
  1:glColor4f(5,0,0,0);//red
  2:glColor4f(0,0,5,0);//blue
  3:glColor4f(0,5,0,0);//green
  4:glColor4f(5,5,0,0);//yellow
 end;
   glVertex3f(0+0.5,0,10.0);
   glVertex3f(0-0.5,0,10.0);
 glend;
end;

procedure put_vp_platform(col:byte);
var i:byte;
begin
 case col of
  0:glColor4f(5,5,5,1);//gray
  1:glColor4f(5,0,0,1);//red
  2:glColor4f(0,0,5,1);//blue
  3:glColor4f(0,5,0,1);//green
  4:glColor4f(5,5,0,1);//yellow
 end;
 //corps
 glDisable(Gl_Texture_2d);
 glNormal3f(0,0,1);
 glBegin(GL_Triangle_fan);
 glVertex3f(0,0,0.01);
 for i:=0 to 12 do
   begin
     glVertex3f(Get_y_v(i*30,0.8),Get_x_v(i*30,0.8),0.01);
   end;
 glend;
end;
{$ENDREGION}

{$REGION 'draw_Bots'}
procedure TWorld.draw_Bots;
var i:byte;
begin
 glEnable(GL_Lighting);
 glPushMatrix();
 glTranslatef(0,0,0);
 Set_Sun;
 glTranslatef(-K[0],-K[1],-K[2]);
 for i:=0 to Max_Bots do
  if (bot[i].tip>0) then
   begin
    glPushMatrix();
     if (AL>10) then
     begin
      glTranslatef(Bot[i].Poz[0],Bot[i].Poz[1],Bot[i].Poz[2]);
      put_marker(Bot[i].side);
     end
     else
     case bot[i].tip of
      1:begin
         glTranslatef(Bot[i].Poz[0],Bot[i].Poz[1],Bot[i].Poz[2]);
         glRotatef(-Bot[i].Ang[1],0,0,1);
         if (i<>player_bot) then
          put_Bot(Bot[i].side,abs(Bot[i].anim-128));
        end;
      2:begin
         glTranslatef(Bot[i].Poz[0],Bot[i].Poz[1],Bot[i].Poz[2]);
         put_platf(Bot[i].side);
         glRotatef(-Bot[i].Ang[1],0,0,1);
         glTranslatef(0,0,0.7);
         glRotatef(Bot[i].Ang[2],1,0,0);
         put_cannon(Bot[i].side);
        end;
     end;

    glPopMatrix();
   end;
 glPopMatrix();
end;
{$ENDREGION}    

{$REGION 'Draw_Bullets'}
procedure TWorld.Draw_Bullets;
var i:integer;
begin
 glEnable(GL_Lighting);
 glDisable(GL_Texture_2d);
 glPushMatrix();
 Set_Sun;
 glTranslatef(-K[0],-K[1],-K[2]);
 if AL<10 then       
 for i:=0 to Max_Bullets do
  if bullet[i].life>0 then
   begin
      put_Bullet(Bullet[i].Poz,Bullet[i].PPoz,Bullet[i].side);
   end;
 glPopMatrix();
end;
{$ENDREGION}

{$REGION 'Draw_parts'}
procedure put_part(poz:TPoint;tip:byte);
begin
 //corps
 glColor4f(1,1,1,1);
 case tip of
  1:glColor4f(1,0,0,0.5);
  2:glColor4f(0,0,1,0.5);
  3:glColor4f(0,1,0,0.5);
  4:glColor4f(1,1,0,0.5);
 end;
 glBegin(gl_Quads);

  glVertex3f(poz[0]+sp[0]*0.2,poz[1]+sp[1]*0.2,poz[2]);
  glVertex3f(poz[0]          ,poz[1]          ,poz[2]+0.2);
  glVertex3f(poz[0]-sp[0]*0.2,poz[1]-sp[1]*0.2,poz[2]);
  glVertex3f(poz[0]          ,poz[1]          ,poz[2]-0.2);

 glend;
end;

procedure TWorld.Draw_Parts;
var i:integer;
begin
 glDisable(GL_Lighting);
 glDisable(GL_Texture_2d);
 glPushMatrix();
 Set_Sun;
 glTranslatef(-K[0],-K[1],-K[2]);
 if AL<10 then
 for i:=0 to Max_Parts do
  if bullet[i].life>0 then
   begin
      put_part(Part[i].Poz,Part[i].tip);
   end;
 glPopMatrix();
end;
{$ENDREGION}

{$REGION 'Draw_Map'}
procedure TWorld.Draw_Map;
var i,j:byte;
begin               
 glEnable(GL_Lighting);
 glPushMatrix();
 Set_Sun;
 glTranslatef(-K[0],-K[1],-K[2]);
 for i:=0 to Map_x do
 for j:=0 to Map_y do
  if (Map[i,j].tip>0) and (Map[i,j].tip<3) then
   begin
    glPushMatrix();
    glTranslatef(i,j,0);
    put_Map(Map[i,j].view);
    glPopMatrix();
   end;
 for i:=0 to Map_x do
 for j:=0 to Map_y do
 if (map[i,j].tip=3) then
  begin
     glPushMatrix();
     glTranslatef(i,j,0);
     put_vp_platform(map[i,j].side);
     glRotatef(-AY,0,0,1);
     put_VP(map[i,j].side,map[i,j].view);
    glPopMatrix();
  end;
 glPopMatrix();
end;
{$ENDREGION}

{$REGION 'bot_fire'}
procedure TWorld.fire_bot(num:integer);
var speed:single;
begin
 speed:=2.5;
 if (bot[num].rel>0) then exit;
 if (bot[num].bullets>100) then exit;
// bot[player_bot].bullets:=bot[player_bot].bullets+8;  }

 add_bullet(
        plus(
            bot[num].poz,
            Point(0,0,bot[num].H+abs(Get_Y_V(bot[num].Step_anim/100*360,0.05)))),
        Point(Get_Y_V(bot[num].Ang[1]+180,Get_Y_V(-bot[num].Ang[0]+180,speed)),
              Get_X_V(bot[num].Ang[1]+180,Get_Y_V(-bot[num].Ang[0]+180,speed)),
              Get_X_V(-bot[num].Ang[0]+180,speed)),
        1,
        5,
        bot[num].Side);         
 bot[num].bullets:=bot[num].bullets+1;
 bot[num].make_fire:=true;
 bot[num].rel:=5;
 bot[num].Ang[0]:=bot[num].Ang[0]+(Random(100)-45)/150;
 bot[num].Ang[1]:=bot[num].Ang[1]+(Random(100)-50)/200;
end;
{$ENDREGION}

{$REGION 'bot_move'}
procedure TWorld.move_bot(num:byte;ang:single);
var
a,b:byte;
t:TPoint;
begin
// speed:=0.12;
if bot[num].speed<0.12 then bot[num].speed:=bot[num].speed+0.01;

// bot[num].speed:=0.12;
 bot[num].np:=point(
                    Get_X_V(ang,bot[num].speed),
                    Get_Y_V(ang,bot[num].speed),0);
 t:=plus(bot[num].np,bot[num].poz);
 a:=trunc(t[0]);
 if a<0 then a:=0;
 if a> map_x then a:=map_x;
 b:=trunc(t[1]);
 if b<0 then b:=0;
 if b> map_y then b:=map_y;
 if (map[a,b].tip = 1) then
  Jump(num);
 if (map[a,b].tip = 2) then
  bot[num].ma:=get_R(bot[num].ma+(random(2)*2-1)*(60+Random(50)));
end;
{$ENDREGION}

{$REGION 'move'}
procedure TWorld.Move;
var
 i,j,a,b,n,m:integer;
 s,f:single;
 t:TPoint;
begin      
 for i:=0  to 3 do
  if (Pain[i]>0) then pain[i]:=pain[i]-1;
  
{$REGION 'sit and overheat'}
 //bot
 if not sit then
  begin
   if  (bot[player_bot].H<0.65) then bot[player_bot].H:=bot[player_bot].H+0.05;
  end else
   if  (bot[player_bot].H>0.35) then bot[player_bot].H:=bot[player_bot].H-0.05;
//player

//  bot[player_bot].H:=0.35;
{$ENDREGION}
{$REGION 'victory point resolve'}
 for i:= 0 to Map_x do
  for j:= 0 to Map_y do
   if map[i,j].tip=3 then
   begin
    if map[i,j].view<400 then map[i,j].view:=map[i,j].view+1;
    Map[i,j].sel:=true;
    if (game_mode=1) then
     Points[Map[i,j].side]:=Points[Map[i,j].side]+1;
   end;
if game_mode=1 then
 begin
   if Points[1]>max_vic_points then begin show_message('Красные победили!');on_planet;end;
   if Points[2]>max_vic_points then begin show_message('Вы победили!');on_planet;end;
 end;
if game_mode>1 then
 begin
   if Points[1]>max_frags then begin show_message('Красные победили!');on_planet;end;
   if Points[2]>max_frags then begin show_message('Вы победили!');on_planet;end;
   if Points[3]>max_frags then begin show_message('Зеленые победили!');on_planet;end;
   if Points[4]>max_frags then begin show_message('Желтые победили!');on_planet;end;
 end;
{$ENDREGION}
if (bot[player_bot].tip=0) then
 begin
  map_view:=true;
 end;

 for i:= 0 to Max_Bots do
  if bot[i].tip>0 then
   begin
 if (bot[i].bullets>99) then
   begin
    bot[i].bullets:=bot[player_bot].bullets+1;
   end;
 if bot[i].bullets>=300 then
   bot[i].bullets:=0;
 Bot[i].anim:=Bot[i].anim+10;
{$REGION 'bot_reload,map move, victory point select'}

    if bot[i].rel>0 then bot[i].rel:=bot[i].rel-1;
    //new pozition
    a:=trunc(bot[i].np[0]+bot[i].poz[0]);
    if a<0 then a:=0;
    if a> map_x then a:=map_x;
    b:=trunc(bot[i].np[1]+bot[i].poz[1]);
    if b<0 then b:=0;
    if b> map_y then b:=map_y;
    if (map[a,b].tip = 0) or
       (map[a,b].tip = 3) or// no walls
       ((map[a,b].tip = 1) and (bot[i].poz[2]>=0.6)) or // half walls
       ((map[a,b].tip = 2) and (bot[i].poz[2]>=1.0)) // full walls
       then
         bot[i].poz:=plus(bot[i].np,bot[i].poz); //move
      bot[i].np:=point(0,0,0);
      a:=trunc(bot[i].poz[0]);
      if a<0 then a:=0;
      if a> map_x then a:=map_x;
      b:=trunc(bot[i].poz[1]);
      if b<0 then b:=0;
      if b> map_y then b:=map_y;
      if (bot[i].poz[2]>0) or
         ((bot[i].poz[2]>0.6) and (map[a,b].tip = 1)) or
         ((bot[i].poz[2]>1.0) and (map[a,b].tip = 2)) or
         (bot[i].jump>0) then
       begin
        bot[i].poz[2]:=bot[i].poz[2]+bot[i].jump;
        bot[i].jump:=bot[i].jump-0.004;
       end;
      if (bot[i].poz[2]<0) then
       begin
        bot[i].poz[2]:=0;
        bot[i].jump:=0;
       end else
      if (bot[i].poz[2]<0.6) and (map[a,b].tip = 1) then
       begin
        bot[i].poz[2]:=0.6;
        bot[i].jump:=0;
       end else
      if (bot[i].poz[2]<1.0) and (map[a,b].tip = 2) then
       begin
        bot[i].poz[2]:=1.0;
        bot[i].jump:=0;
       end;
     //map border
      if (bot[i].poz[0]<-15) then bot[i].poz[0]:=-15;
      if (bot[i].poz[1]<-15) then bot[i].poz[1]:=-15;
      if (bot[i].poz[0]>Map_X+15) then bot[i].poz[0]:=Map_X+15;
      if (bot[i].poz[1]>Map_Y+15) then bot[i].poz[1]:=Map_Y+15;

    if a<2 then a:=2;
    if a> map_x-2 then a:=map_x-2;
    if b<2 then b:=2;
    if b> map_y-2 then b:=map_y-2;
    for n := a-2 to a+2 do        
     for m := b-2 to b+2 do
    if (Map[n,m].tip=3) and Map[n,m].sel
     and (Map[n,m].side<>bot[i].Side)
     then
     begin
      Map[n,m].view:= Map[n,m].view-2;
      Map[n,m].sel:=false;
      if (Map[n,m].view<=0) then
       begin
        if (Map[n,m].side<>0) then
         begin
          Map[n,m].side:=0;
          Map[n,m].view:=100;
         end else
         begin
          map[n,m].side:=bot[i].Side;
          if game_mode=1 then          
          case bot[i].Side of
           1:Show_Message('Красные захватили точку');
           2:Show_Message('Синие захватили точку');
           3:Show_Message('Зеленые захватили точку');
           4:Show_Message('Желтые захватили точку');
          end;
         end;
       end;
     end;
{$ENDREGION}
{$REGION 'bot fire'}
     //bot fire
     if (Bot[i].cel<0) then
     if (Random(3)=0) then
     for j:= 0 to Max_Bots do
      if (Random(8)=0) then
       if (bot[j].tip>0) and (bot[j].Side<>bot[i].Side) and (i<>j) then
       if (30*30>((bot[i].poz[0]-bot[j].poz[0])*(bot[i].poz[0]-bot[j].poz[0])+
       (bot[i].poz[0]-bot[j].poz[0])*(bot[i].poz[0]-bot[j].poz[0]))) then
        begin
         Bot[i].cel:=j;
        end;
      if (bot[i].cel>=0) then
      begin
       if (bot[bot[i].cel].Life<=0) then bot[i].cel:=-1;
       bot[i].Ang[1]:=Random(bot[i].fail_grad*2)-bot[i].fail_grad+Get_R(270-Get_A(bot[i].poz[0],bot[i].poz[1],bot[bot[i].cel].poz[0],bot[bot[i].cel].poz[1]));
       bot[i].Ang[0]:=Random(bot[i].fail_grad*2)-bot[i].fail_grad+90+Get_A(
              Get_S(bot[i].poz[0],bot[i].poz[1],bot[bot[i].cel].poz[0],bot[bot[i].cel].poz[1]),
             bot[bot[i].cel].poz[2]-bot[i].poz[2]-bot[i].h-0.05);
       if (Random(3)=0) and (i<>player_bot) then
        fire_bot(i);
      end;


{$ENDREGION}
{$REGION 'bot_move'}
 if (i<>player_bot) and (bot[i].tip=1) then
  begin
  if (Random(1400)=0)  then
   begin
    Bot[i].cel:=-1;
   end;

  if (Random(140)=0)  then
   begin
    Jump(i);
   end;
  if (Random(240)=0)  then
   begin
    bot[i].ma:=random(360);
    bot[i].speed:=0.0;
   end;
  if (Random(20)=0) then
   begin
    bot[i].wp:=Map_X+Map_y;
    for n := 0 to Map_x do
     for m := 0 to Map_y do
      if (Map[n,m].tip=3) and (Map[n,m].side<>Bot[i].Side) and (random(3)>0)then
       if (bot[i].wp>Get_s(Bot[i].poz[0],Bot[i].poz[1],n,m)) then
       begin
        bot[i].wp:=Get_s(Bot[i].poz[0],Bot[i].poz[1],n,m);
        bot[i].cx:=n;
        bot[i].cy:=m;
        bot[i].ma:=Get_A(Bot[i].poz[0],Bot[i].poz[1],bot[i].cx,bot[i].cy)+Random(10)-5;
        bot[i].Ang[0]:=bot[i].ma;
        bot[i].speed:=0.0;
        break
       end;
   end;
   if (Bot[i].wp>=1)  then
    move_bot(i,bot[i].ma)
    else
     if (random(240)=0) then
     begin
      bot[i].ma:=get_R(bot[i].ma+random(10)-5);
        bot[i].speed:=0.04;
      move_bot(i,bot[i].ma);
     end;
  end;

{$ENDREGION}
   end
   else
   begin
    bot[i].Life:=bot[i].Life-10;
    if (bot[i].Life<-5000) and (bot[i].Side>0) then
     begin
       bot[i].tip:=1;
       bot[i].Life:=life_maximum;
       bot[i].bullets:=0;
       if (bot[i].side=1) then
        begin
         bot[i].poz:=Point(Random(20)+5,Random(20)+5,0);
        end else
       if (bot[i].side=2) then
        begin
         bot[i].poz:=Point(Map_X-Random(20)+5,Map_X-Random(20)+5,0);
        end else
       if (bot[i].side=3) then
        begin
         bot[i].poz:=Point(Map_X-Random(20)+5,Random(20)+5,0);
        end else
       if (bot[i].side=4) then
        begin
         bot[i].poz:=Point(Random(20)+5,Map_X-Random(20)+5,0);
        end
     end;
   end;
 //bullets
 for i:=0 to Max_Bullets do
  if bullet[i].life>0 then
   begin
{$REGION 'bullets'}
    bullet[i].life:=bullet[i].life-1;
    bullet[i].PPoz:=bullet[i].Poz;
    bullet[i].Poz:=plus(bullet[i].Poz,bullet[i].Vect);
    for j:=0 to 5 do
    begin
     t:=plus(bullet[i].poz,multi(minus(bullet[i].ppoz,bullet[i].poz),j*0.2));
     a:=trunc(t[0]);
     if a<0 then a:=0;
     if a> map_x then a:=map_x;
     b:=trunc(t[1]);
     if b<0 then b:=0;
     if b> map_y then b:=map_y;
     if (bullet[i].poz[2]<0) or
       ((bullet[i].poz[2]<=0.6) and (map[a,b].tip = 1)) or
       ((bullet[i].poz[2]<=1.0) and (map[a,b].tip = 2)) then
      begin
{       if (bullet[i].tip=2) then
         for m:=0 to 40 do
          add_part(Point(t[0],t[1],0.0),
                   Point((Random(10)-5)*0.05,(Random(10)-5)*0.05,(Random(5))*0.05),1);
  }     bullet[i].life:=0;
      end;
    end;

     for j:=0 to Max_bots do
      if (bot[j].tip>0) then
      if (bot[j].side<>bullet[i].side) then
      if (bot[j].poz[0]>bullet[i].poz[0]-2) then
      if (bot[j].poz[0]<bullet[i].poz[0]+2) then
      if (bot[j].poz[1]>bullet[i].poz[1]-2) then
      if (bot[j].poz[1]<bullet[i].poz[1]+2) then
      if (bot[j].poz[2]<bullet[i].poz[2]) then
      if (bot[j].poz[2]>bullet[i].poz[2]-bot[j].h) then
     begin
      S:=Get_lp_S(
        bullet[i].poz[0],bullet[i].poz[1],
        bullet[i].ppoz[0],bullet[i].ppoz[1],
        bot[j].poz[0],bot[j].poz[1]);
      f:=Get_S(bullet[i].poz,bot[j].poz);
      if (S<0.4) and (f<=2.5) then
       begin
         bot[j].Life:=bot[j].Life-bullet[i].damage;   
         if bot[j].Life<=0 then
         begin
          bot[j].tip:=0;
          if (game_mode>1) then
           points[bullet[i].side]:=points[bullet[i].side]+1;
         end;
         
         for m:=0 to 6 do
          add_part(Point(bot[j].poz[0],bot[j].poz[1],0.4+Random(2)*0.2),
                   Point((Random(10)-5)*0.03,(Random(10)-5)*0.03,(Random(5))*0.03),bot[j].Side);
         if (j=player_bot) then
          begin
           s:=Get_A(bot[j].poz[0],bot[j].poz[1],bullet[i].ppoz[0],bullet[i].ppoz[1]);
           s:=Get_R(s-bot[j].Ang[1]);
           n:=trunc((s)/90);
           if n<0 then n:=0;
           if n>3 then n:=3;
           if pain[n]+50<255 then
            pain[n]:=pain[n]+100;
          end;
         if random(7)=0 then bot[j].cel:=-1;
        // bot[j].side:=random(3);
         bullet[i].life:=0;
       end;
     end;
{$ENDREGION}
   end;
 //not realistic move :(
 if (bot[player_bot].poz[2]=0) and Control_ then 
  bot[player_bot].step_anim:=bot[player_bot].step_anim+3;
 if bot[player_bot].Step_anim>100 then bot[player_bot].Step_anim:=0;
 Control_:=false;
 {$REGION 'parts'}
 for i:=0 to Max_Parts do
  if (part[i].tip>0) then
   begin
    part[i].life:=part[i].life-1;
    if (part[i].life=0) then part[i].tip:=0;
    part[i].Poz:=plus(part[i].Poz,part[i].Vect);
    part[i].Vect:=plus(part[i].Vect,Point(0,0,-0.01));
   end;
 {$ENDREGION}

 //main plain
 K:=plus(bot[player_bot].Poz,point(0,0,bot[player_bot].H+abs(Get_Y_V(bot[player_bot].Step_anim/100*360,0.05))));
 bot[player_bot].ang[0]:=Get_R(-AY);
 bot[player_bot].ang[1]:=Get_R(90-AX);
end;
{$ENDREGION}

{$REGION 'pricel'}
procedure put_fire_splash;
var i:byte;
begin
 GlColor3f(0.75,0.8,0.1);
 for i:=0 to 5 do
 begin
 glbegin(gl_triangles);
  glVertex3f(5.45,-3,11.0);
  glVertex3f(5.45+(Random(100)-50)/15,-3+(Random(100)-50)/15,11.0);
  glVertex3f(5.45+(Random(100)-50)/15,-3+(Random(100)-50)/15,11.0);
 glend;
 end;
end;

Procedure TWorld.Draw_Pricel;
var
 i:byte;
 a,b:single;
begin
//pricel
 glLoadIdentity();     {'zero' projection matrix}
 glDisable(GL_DEPTH_TEST);
 glDisable(gl_Texture_2d);
{$REGION 'pricel'}
 glBegin(gl_Quads);
 GlColor4f(0,0,0,1);
 for i:=0  to 3 do
   begin
     glVertex3f(Get_x_v(i*90-13,0.15),Get_y_v(i*90-13,0.15),0.0);
     glVertex3f(Get_x_v(i*90-13,0.32),Get_y_v(i*90-13,0.32),0.0);
     glVertex3f(Get_x_v(i*90+13,0.32),Get_y_v(i*90+13,0.32),0.0);
     glVertex3f(Get_x_v(i*90+13,0.15),Get_y_v(i*90+13,0.15),0.0);
   end;
 GlColor4f(5,5,5,1);
 for i:=0  to 3 do
   begin
     glVertex3f(Get_x_v(i*90-10,0.15),Get_y_v(i*90-10,0.15),0.0);
     glVertex3f(Get_x_v(i*90-10,0.3 ),Get_y_v(i*90-10,0.3 ),0.0);
     glVertex3f(Get_x_v(i*90+10,0.3 ),Get_y_v(i*90+10,0.3 ),0.0);
     glVertex3f(Get_x_v(i*90+10,0.15),Get_y_v(i*90+10,0.15),0.0);
   end;
 glend;

{$ENDREGION}
 //gun
 a:=-abs(Get_Y_V(bot[player_bot].Step_anim/100*360,0.1));
 gldepthmask(false);
{$REGION 'gun'}
 if bot[player_bot].make_fire then
  put_fire_splash;
 case bot[player_bot].Side of
  0:glColor4f(0.6,0.6,0.6,1);//gray
  1:glColor4f(0.6,  0,  0,1);//red
  2:glColor4f(0  ,  0,0.6,1);//blue
  3:glColor4f(0  ,0.6,  0,1);//green  
  4:glColor4f(0.6,0.6,  0,1);//yellow
 end;
 glBegin(gl_Quads);
 glNormal3f(-1,0,0);
 glVertex3f(4.3,-3-1.3+a,-30);
 glVertex3f(4.3,-3+1.3+a,-30);
 glVertex3f(4.3,-3+1.3+a,10);
 glVertex3f(4.3,-3-1.3+a,10);
 glNormal3f(0,1,0);
 glVertex3f(4.5,-3+1.6+a,-30);
 glVertex3f(6.3,-3+1.6+a,-30);
 glVertex3f(6.3,-3+1.6+a,10);
 glVertex3f(4.5,-3+1.6+a,10);
 glNormal3f(-0.707,0.707,0);
 glVertex3f(4.3,-3+1.3+a,10);
 glVertex3f(4.3,-3+1.3+a,-30);
 glVertex3f(4.5,-3+1.6+a,-30);
 glVertex3f(4.5,-3+1.6+a,10);
 glNormal3f(-1,0,0);
 glVertex3f(4.6,-1-0.3+a,-22);
 glVertex3f(4.6,-1+0.3+a,-22);
 glVertex3f(4.6,-1+0.3+a,-5);
 glVertex3f(4.6,-1-0.3+a,-5);
 glNormal3f(0,1,0);
 glVertex3f(4.8,-1+0.6+a,-22);
 glVertex3f(5.3,-1+0.6+a,-22);
 glVertex3f(5.3,-1+0.6+a,-5);
 glVertex3f(4.8,-1+0.6+a,-5);
 glNormal3f(-0.707,0.707,0);
 glVertex3f(4.6,-1+0.3+a,-5);
 glVertex3f(4.6,-1+0.3+a,-22);
 glVertex3f(4.8,-1+0.6+a,-22);
 glVertex3f(4.8,-1+0.6+a,-5);
 bot[player_bot].make_fire:=false;
 glend;
{$ENDREGION}
{$REGION 'pain'}
 glBegin(gl_Quads);
// pain[0]:=255;
 if pain[0]>0 then //up
  begin
   glColor4f(5,0,0,0);//red
   glVertex3f( 3,5,0);
   glVertex3f(-3,5,0);
   glColor4f(5,0,0,pain[0]/255);//red
   glVertex3f(-2,3,0);
   glVertex3f( 2,3,0);
  end;
 if pain[3]>0 then //rigth
  begin
   glColor4f(5,0,0,0);//red
   glVertex3f(5,-3,0);
   glVertex3f(5, 3,0);
   glColor4f(5,0,0,pain[0]/255);//red
   glVertex3f(3, 2,0);
   glVertex3f(3,-2,0);
  end;
 if pain[2]>0 then //down
  begin
   glColor4f(5,0,0,0);//red
   glVertex3f(-3,-5,0);
   glVertex3f( 3,-5,0);
   glColor4f(5,0,0,pain[0]/255);//red
   glVertex3f( 2,-3,0);
   glVertex3f(-2,-3,0);
  end;
 if pain[1]>0 then //left
  begin
   glColor4f(5,0,0,0);//red
   glVertex3f(-5, 3,0);
   glVertex3f(-5,-3,0);
   glColor4f(5,0,0,pain[0]/255);//red
   glVertex3f(-3,-2,0);
   glVertex3f(-3, 2,0);
  end;
  glNormal3f(0,0,-1);
 glend;
{$ENDREGION}
{$REGION 'points'}
glColor4f(1,1,1,1);
if game_mode=1 then
begin
glbegin(GL_Quads);
glNormal3f(0,0,-1);
a:=8.35;
b:=-0.15;
glColor4f(0,0,0,0.5);
glVertex2f(2.6 +b,-0.2+a);
glVertex2f(0.4 +b,-0.45+a);
glVertex2f(0.5 +b,-0.7+a);
glVertex2f(2.4 +b,-0.7+a);
glVertex2f(2.35+b,-0.83+a);
glVertex2f(0.5 +b,-0.8+a);
glVertex2f(0.48+b,-1.05+a);
glVertex2f(2.1 +b,-1.25+a);
glVertex2f(2.0 +b,-1.35+a);
glVertex2f(0.46+b,-1.15+a);
glVertex2f(0.35+b,-1.35+a);
glVertex2f(1.4 +b,-1.7+a);
glVertex2f(0.4 +b,-0.8+a);
glVertex2f(0.25+b,-0.45+a);
glVertex2f(0.25+b,-1.25+a);
glVertex2f(0.4 +b,-1.05+a);
a:=8.4;
b:=-0.2;
glColor3f(0,0,5);
glVertex2f(2.6 +b,-0.2+a);
glVertex2f(0.4 +b,-0.45+a);
glVertex2f(0.5 +b,-0.7+a);
glVertex2f(2.4 +b,-0.7+a);
glVertex2f(2.35+b,-0.83+a);
glVertex2f(0.5 +b,-0.8+a);
glVertex2f(0.48+b,-1.05+a);
glVertex2f(2.1 +b,-1.25+a);
glVertex2f(2.0 +b,-1.35+a);
glVertex2f(0.46+b,-1.15+a);
glVertex2f(0.35+b,-1.35+a);
glVertex2f(1.4 +b,-1.7+a);
glVertex2f(0.4 +b,-0.8+a);
glVertex2f(0.25+b,-0.45+a);
glVertex2f(0.25+b,-1.25+a);
glVertex2f(0.4 +b,-1.05+a);   
a:=8.35;
b:=0.25;
glColor4f(0,0,0,0.5);
glVertex2f(-0.4 +b,-0.45+a);
glVertex2f(-2.6 +b,-0.2+a);
glVertex2f(-2.4 +b,-0.7+a);
glVertex2f(-0.5 +b,-0.7+a);
glVertex2f(-0.5 +b,-0.8+a);
glVertex2f(-2.35+b,-0.83+a);
glVertex2f(-2.1 +b,-1.25+a);
glVertex2f(-0.48+b,-1.05+a);
glVertex2f(-0.46+b,-1.15+a);
glVertex2f(-2.0 +b,-1.35+a);
glVertex2f(-1.4 +b,-1.7+a);
glVertex2f(-0.35+b,-1.35+a);
glVertex2f(-0.25+b,-0.45+a);
glVertex2f(-0.4 +b,-0.8+a);
glVertex2f(-0.4 +b,-1.05+a);
glVertex2f(-0.25+b,-1.25+a);
a:=8.4;
b:=0.2;
glColor3f(5,0,0);
glVertex2f(-0.4 +b,-0.45+a);
glVertex2f(-2.6 +b,-0.2+a);
glVertex2f(-2.4 +b,-0.7+a);
glVertex2f(-0.5 +b,-0.7+a);
glVertex2f(-0.5 +b,-0.8+a);
glVertex2f(-2.35+b,-0.83+a);
glVertex2f(-2.1 +b,-1.25+a);
glVertex2f(-0.48+b,-1.05+a);
glVertex2f(-0.46+b,-1.15+a);
glVertex2f(-2.0 +b,-1.35+a);
glVertex2f(-1.4 +b,-1.7+a);
glVertex2f(-0.35+b,-1.35+a);
glVertex2f(-0.25+b,-0.45+a);
glVertex2f(-0.4 +b,-0.8+a);
glVertex2f(-0.4 +b,-1.05+a);
glVertex2f(-0.25+b,-1.25+a);
glend;
end;
{$ENDREGION}

//life //bullets
glDisable(gl_lighting);
glbegin(GL_Quads);
glNormal3f(0,0,-1);
a:=-6;
b:=5.15;
glColor4f(1,0,0,1);
glVertex2f(0.0 +b+bot[player_bot].Life/25,-0.5-(100-bot[player_bot].Life)/100*0.7+a);
glVertex2f(0.0 +b,-1.2+a);
glVertex2f(0.0 +b,-2.0+a);
glVertex2f(0.0 +b+bot[player_bot].Life/25,-1.0-(100-bot[player_bot].Life)/100+a);
if (bot[player_bot].bullets<=100) then
begin
glColor4f(0,0,1,1);
glVertex2f(-0.0 -b,-1.2+a);
glVertex2f(-0.0-(100-bot[player_bot].bullets)/25 -b,-0.5-(bot[player_bot].bullets)/100*0.7+a);
glVertex2f(-0.0-(100-bot[player_bot].bullets)/25 -b,-1.0-(bot[player_bot].bullets)/100+a);
glVertex2f(-0.0 -b,-2.0+a);
end;
glend;
 gldepthmask(true);
end;
{$ENDREGION}

{$REGION 'Render'}
Procedure TWorld.Render;
begin
//temp      
 glEnable(GL_Texture_2d);
 sp:=Point(0,1,0);
 sp:=multi(Rotate(AY+90,0,0,-1),sp);
 if Map_View then
 begin
  if AL<140 then
   AL:=AL+(AL+0.1)*0.5 else
   AL:=140;
  AX:=AX*0.8+55*0.2;
//  AX:=AX*0.8+PX*0.2;
 end else
 begin   
  if AL>0.03 then  
   AL:=AL*0.7 else
   AL:=0;
  AX:=AX*0.8+PX*0.2;
 end; 
  AY:=PY;   
 Draw_Ocean;
 Draw_Bots;
 Draw_Bullets;
 Draw_parts;
 Draw_map;
 if not map_view then
  Draw_Pricel;
 if Bot[player_bot].Life>0 then
  begin
   Menu.Panel[2].Text:='';
  end
  else
  begin
   Menu.Panel[2].Text:=IntToStr(trunc(-(Bot[player_bot].Life/50)));
  end;
 if (game_mode=1) then
 begin
  Menu.Panel[3].Text:='';
  Menu.Panel[4].Text:=IntToStr(trunc(points[1]/100));
  Menu.Panel[5].Text:=IntToStr(trunc(points[2]/100));
  Menu.Panel[6].Text:='';  
  Menu.Panel[9].Text:='';
  Menu.Panel[10].Text:='';
  Menu.Panel[11].Text:='';
  Menu.Panel[12].Text:='';
 end
 else
 begin
  Menu.Panel[3].Text:='';
  Menu.Panel[4].Text:='';
  Menu.Panel[5].Text:='';
  Menu.Panel[6].Text:='';
  Menu.Panel[9 ].Text:='Синие   '+IntToStr(trunc(points[2]));
  Menu.Panel[10].Text:='Красные '+IntToStr(trunc(points[1]));
  Menu.Panel[11].Text:='Зеленые '+IntToStr(trunc(points[3]));
  Menu.Panel[12].Text:='Желтые  '+IntToStr(trunc(points[4]));
 end;
// Menu.Panel[3].Text:='';
end;
{$ENDREGION}

{$REGION 'Control'}
Procedure TWorld.Control(cx,cy,cz:single);
var
speed:Single;
begin
 speed:=0.01;
 bot[player_bot].np:=plus(
                bot[player_bot].np,
                point(
                    Get_X_V(bot[player_bot].Ang[0]+90,cx)+Get_X_V(bot[player_bot].Ang[0],cy+Get_Y_V(bot[player_bot].Step_anim/100*360,0.02)),
                    Get_Y_V(bot[player_bot].Ang[0]+90,cx)+Get_Y_V(bot[player_bot].Ang[0],cy+Get_Y_V(bot[player_bot].Step_anim/100*360,0.02)),
                    0));
 control_:=true;
end;
       
Procedure TWorld.Jump(i:byte);
var speed:Single;
begin
 if Bot[i].jump=0 then
   bot[i].jump:=0.08;
 bot[i].Step_anim:=0;
end;

Procedure TWorld.reload;
var speed:Single;
begin
 if (Bot[player_bot].bullets<100) then
 Bot[player_bot].bullets:=105;
end;

procedure TWorld.fire;
var speed:single;
begin
 speed:=2.5;
 if (bot[player_bot].rel>0) then exit;
 if (bot[player_bot].bullets>100) then exit;
// bot[player_bot].bullets:=bot[player_bot].bullets+8;
 add_bullet(
        plus(
            bot[player_bot].poz,
            Point(0,0,bot[player_bot].H+abs(Get_Y_V(bot[player_bot].Step_anim/100*360,0.05)))),
        Point(Get_Y_V(AY+180,Get_Y_V(-AX+180,speed)),
              Get_X_V(AY+180,Get_Y_V(-AX+180,speed)),
              Get_X_V(-AX+180,speed)),
        1,
        5,
        bot[player_bot].Side);
 bot[player_bot].bullets:=bot[player_bot].bullets+1;       
 bot[player_bot].make_fire:=true;
 bot[player_bot].rel:=5;
 px:=px+(Random(100)-45)/150;
 py:=py+(Random(100)-50)/200;
end;

procedure TWorld.Granade;
var speed:single;
i:byte;
begin
 speed:=1.5;
 if (bot[player_bot].rel>0) then exit;
 if (bot[player_bot].bullets>100) then exit;
 for i:=0 to 40 do
 add_bullet(
        plus(
            bot[player_bot].poz,
            Point(0,0,bot[player_bot].H+abs(Get_Y_V(bot[player_bot].Step_anim/100*360,0.05)))),
        plus(Point(Get_Y_V(AY+180,Get_Y_V(-AX+180,speed)),
              Get_X_V(AY+180,Get_Y_V(-AX+180,speed)),
              Get_X_V(-AX+180,speed)),
              Point((Random(10)-5)*0.015,(Random(10)-5)*0.015,(Random(10)-5)*0.015)),
        1,
        10,
        bot[player_bot].Side);
 bot[player_bot].bullets:=200;
 bot[player_bot].make_fire:=true;
 bot[player_bot].rel:=5;
 px:=px+(Random(100)-45)/150;
 py:=py+(Random(100)-50)/200;
end;
{$ENDREGION}

{$REGION 'add bullet'}
Procedure TWorld.add_bullet(poz,vect:TPoint;tip,damage,side:byte);
var i:integer;
begin
 for i:=0 to Max_bullets do
   if Bullet[i].life=0 then
    begin
      Bullet[i].tip:=tip;
      Bullet[i].Poz:=Poz;
      Bullet[i].PPoz:=Poz;
      Bullet[i].Vect:=Vect;
      Bullet[i].damage:=damage;
      Bullet[i].side:=side;
      Bullet[i].life:=20;
      break;
    end;     
end;
{$ENDREGION}

{$REGION 'add part'}
Procedure TWorld.add_part(poz,vect:TPoint;tip:byte);
var i:integer;
begin
 for i:=0 to Max_Parts do
   if Part[i].tip=0 then
    begin
      Part[i].tip:=tip;
      Part[i].Poz:=Poz;
      Part[i].Vect:=Vect;
      Part[i].life:=40;
      break;
    end;     
end;
{$ENDREGION}

{$REGION 'random_lev'}
procedure TWorld.clear_map;
var i,j:byte;
begin
 for i:=0 to Map_X do
 for j:=0 to Map_Y do
 begin
   map[i,j].tip:=0; 
   map[i,j].side:=0;
   map[i,j].view:=0;
   map[i,j].sel:=false;
 end;
end;

procedure TWorld.gen_random_level(tip:byte);
var i,j,n,m:integer;
 p:TVector4f;
begin
 if tip=0 then
  game_mode:=Random(3)+1
 else
  game_mode:=tip;

 K:=Point(0,0,0);
 map_view:=false;
 AL:=140;
 AX:=55;
 p[0]:=0; p[1]:=0; p[2]:=0; p[3]:=1;
 glLightFV(Gl_LIGHT0,GL_AMBIENT,@p);          {set ligth ambient}
 for i:=0 to 4 do
  points[i]:=0;
 clear_map;
 case game_mode of
  1:begin
     player_bot:=max_bots div 2;
     for i:=0 to max_bots  do
      begin
      bot[i].tip:=1;
    if (i>=0) and (i<=19) then
      begin
       bot[i].poz:=Point(Map_X-Random(20)+5,Map_X-Random(20)+5,0);
       bot[i].Side:=2;
      end;
      if (i>=20) and (i<=39) then
      begin
       bot[i].poz:=Point(Random(20)-5,Random(20)-5,0);
       bot[i].Side:=1;
      end;
      bot[i].Ang[0]:=Random(360);
      bot[i].Ang[1]:=Random(50)-25;
      bot[i].speed:=0.1;
      bot[i].H:=0.65;
      bot[i].Life:=life_maximum;
      bot[i].cel:=-1;
      bot[i].fail_grad:=3;
      bot[i].anim:=random(255);
      bot[i].jump:=0;
     end;
     bot[1].tip:=2;
     bot[2].tip:=2;
     bot[max_bots div 2 +1].tip:=2;
     bot[max_bots div 2 +2].tip:=2;
     //d bot[player_bot].Side:=3;

     n:=Random(6)+2;
     m:=Random(6)+2;
     Map[n,m].tip:=3;
     n:=Map_x-Random(6)-2;
     m:=Map_y-Random(6)-2;
     Map[n,m].tip:=3;
       for i:=0 to max_vp do
       begin
        n:=10+Random(80);
        m:=10+Random(80);
        Map[n,m].tip:=3;
        Map[n,m].side:=0;
        Map[n,m].view:=400;
        for j:=0 to 6 do
         add_map((1-Random(2)*Random(2))*2+Random(2),trunc(n)+Random(10)-5,trunc(m)+Random(10)-5);
       end;
     for i:=0 to 40 do
     begin
      add_map(Random(4)+1,Random(100),random(100));
     end;
   end;
  2:begin
     player_bot:=15;
     if random(3)>0 then
     for i:=0 to max_bots  do
      begin
      bot[i].tip:=1;
      if (i>=0) and (i<=9) then
       begin
        bot[i].poz:=Point(Random(20)-5,Random(20)-5,0);
        bot[i].Side:=1;
       end;
       if (i>=10) and (i<=19) then
       begin
        bot[i].poz:=Point(Map_X-Random(20)+5,Map_X-Random(20)+5,0);
        bot[i].Side:=2;
       end;

       if (i>=20) and (i<=29) then
     begin
      bot[i].poz:=Point(Map_X-Random(20)+5,Random(20)-5,0);
      bot[i].Side:=3;
     end;
     if (i>=30) and (i<=39) then
     begin
      bot[i].poz:=Point(Random(20)-5,Map_X-Random(20)+5,0);
      bot[i].Side:=4;
     end;
      bot[i].Ang[0]:=Random(360);
      bot[i].Ang[1]:=Random(50)-25;
      bot[i].speed:=0.1;
      bot[i].H:=0.65;
      bot[i].Life:=life_maximum;
      bot[i].cel:=-1;
      bot[i].fail_grad:=3;
      bot[i].anim:=random(255);
      bot[i].jump:=0;
     end
     else
     
     for i:=0 to max_bots  do
      begin          
      n:=random(3);
      case n of
      0:n:=1;
      1:n:=3;
      2:n:=4;
      end;
      bot[i].tip:=1;
       if (i>=0) and (i<=19) then
       begin
        bot[i].poz:=Point(Map_X-Random(20)+5,Map_X-Random(20)+5,0);
        bot[i].Side:=2;
       end;
     if (i>=20) and (i<=39) then
     begin
      bot[i].poz:=Point(Random(20)-5,Random(20)-5,0);
      bot[i].Side:=n;
     end;
      bot[i].Ang[0]:=Random(360);
      bot[i].Ang[1]:=Random(50)-25;
      bot[i].speed:=0.1;
      bot[i].H:=0.65;
      bot[i].Life:=life_maximum;
      bot[i].cel:=-1;
      bot[i].fail_grad:=3;
      bot[i].anim:=random(255);
      bot[i].jump:=0;
     end;
     n:=Random(6)+2;
     m:=Random(6)+2;
     Map[n,m].tip:=3;
     n:=Map_x-Random(6)-2;
     m:=Map_y-Random(6)-2;
     Map[n,m].tip:=3;
       for i:=0 to max_vp do
       begin
        n:=10+Random(80);
        m:=10+Random(80);
        Map[n,m].tip:=3;
        Map[n,m].side:=0;
        Map[n,m].view:=400;
        for j:=0 to 6 do
         add_map((1-Random(2)*Random(2))*2+Random(2),trunc(n)+Random(10)-5,trunc(m)+Random(10)-5);
       end;
     for i:=0 to 40 do
     begin
      add_map(Random(4)+1,Random(100),random(100));
     end;
    end;    
  3:begin
     player_bot:=15;
     n:=random(3);
     case n of
     0:n:=1;
     1:n:=3;  
     2:n:=4;
     end;
     for i:=0 to max_bots  do
      begin
      bot[i].tip:=1;
      if (i>=0) and (i<=9) then
       begin
        bot[i].poz:=Point(Random(20)-5,Random(20)-5,0);
        bot[i].Side:=n;
       end;
       if (i>=10) and (i<=19) then
       begin
        bot[i].poz:=Point(Map_X-Random(20)+5,Map_X-Random(20)+5,0);
        bot[i].Side:=2;
       end;

       if (i>=20) and (i<=39) then
     begin
      bot[i].poz:=Point(Random(Map_X),Random(Map_Y),0);
      bot[i].Side:=0;
      bot[i].tip:=2;
     end;
      bot[i].Ang[0]:=Random(360);
      bot[i].Ang[1]:=Random(50)-25;
      bot[i].speed:=0.1;
      bot[i].H:=0.65;
      bot[i].Life:=life_maximum;
      bot[i].cel:=-1;
      bot[i].fail_grad:=3;
      bot[i].anim:=random(255);
      bot[i].jump:=0;
     end;
     //d bot[player_bot].Side:=3;

     n:=Random(6)+2;
     m:=Random(6)+2;
     Map[n,m].tip:=3;
     n:=Map_x-Random(6)-2;
     m:=Map_y-Random(6)-2;
     Map[n,m].tip:=3;
       for i:=0 to max_vp do
       begin
        n:=10+Random(80);
        m:=10+Random(80);
        Map[n,m].tip:=3;
        Map[n,m].side:=0;
        Map[n,m].view:=400;
        for j:=0 to 6 do
         add_map((1-Random(2)*Random(2))*2+Random(2),trunc(n)+Random(10)-5,trunc(m)+Random(10)-5);
       end;
     for i:=0 to 40 do
     begin
      add_map(Random(4)+1,Random(100),random(100));
     end;
    end;
 end;
 //bots

end;

procedure TWorld.on_planet;
var
 p:TVector4f;
begin
 game_mode:=0;
 Menu.Panel[0].Text:='';
 Menu.Panel[1].Text:='';
 Menu.Panel[2].Text:='';
 Menu.Panel[3].Text:='';
 Menu.Panel[4].Text:='';
 Menu.Panel[5].Text:='';
 Menu.Panel[6].Text:='';
 Menu.Panel[9].Text:='';
 Menu.Panel[10].Text:='';
 Menu.Panel[11].Text:='';
 Menu.Panel[12].Text:='';
 p[0]:=-0.2; p[1]:=-0.2; p[2]:=-0.2; p[3]:=1;
 glLightFV(Gl_LIGHT0,GL_AMBIENT,@p);          {set ligth ambient}
 clear_map;
end;
{$ENDREGION}
end.