unit EnemyHeap;

interface

uses
  Windows, SysUtils, classes, Graphics, Controls,trigu;
                                                    
const
 E_C_P = 36; //уж не помню, нафиг он нужен?
type
  TTypeEnemy = (teMeloch,teBugay,teharder);

  TEnemy = record
     XPos,yPos:real;
     x_t,y_t:integer;
     _OnTarget:boolean;
     ID:integer;
     _radius:integer;
     helth: integer;
     _use:boolean;
     _speed:real;
     _tip:TTypeEnemy;
     angle:integer;
  end;

  TContenerEnemy = class
     List:TMemoryStream; //долой списки! Stream рулит!
     _wait:boolean;
    public
     _count:integer;
     _more:integer;
     procedure init;
     procedure adden(x,y:integer;TTE:TTypeEnemy);
     procedure delen(ID:integer);
     procedure draw(canvas:Tcanvas; _R:TRect);
     function AI(x,y:integer):integer;
     procedure Rush(x,y,count:integer);
     procedure clear;
     procedure Rushing(count:integer);
  end;

implementation

uses main, baseclass;

procedure TContenerEnemy.init;
var TE:TEnemy;
begin
 List:=TMemoryStream.Create;
 _count:=0;
 _more:=0;

end;

procedure TContenerEnemy.Rush(x,y,count:integer);
var i:integer;
begin
for i:=0 to count do begin
 case random(3) of
 0: adden(random(x),random(y),teMeloch);
 1: adden(random(x),random(y),teBugay);
 2: adden(random(x),random(y),teharder);
 end;
end;
end;

procedure TContenerEnemy.Rushing(count:integer);
var i:integer;
begin
for i:=0 to count-1 do begin
 case random(3) of
 0: adden(random(1280),-20,teMeloch); //top
 1: adden(random(1280),-20,teBugay);
 2: adden(random(1280),-20,teharder);
 end;
end;
for i:=0 to count-1 do begin
 case random(3) of
 0: adden(-20,random(1024),teMeloch);//left
 1: adden(-20,random(1024),teBugay);
 2: adden(-20,random(1024),teharder);
 end;
end;
for i:=0 to count-1 do begin
 case random(3) of
 0: adden(random(1280),1040,teMeloch);
 1: adden(random(1280),1040,teBugay);
 2: adden(random(1280),1040,teharder);
 end;
end;
for i:=0 to count-1 do begin
 case random(3) of
 0: adden(1300,random(1024),teMeloch); //right
 1: adden(1300,random(1024),teBugay);
 2: adden(1300,random(1024),teharder);
 end;
end;
end;

procedure prepareEnemy(var TE:TEnemy);
var i:integer;
begin

{ case TE._tip of
  teMeloch: begin
     te._countusepoint:=33;
     te._frame1[0].x:=-13;  te._frame1[0].y:=-1;
     te._frame1[1].x:=-11;  te._frame1[1].y:=-2;
     te._frame1[2].x:=-10;  te._frame1[2].y:=-2;
     te._frame1[3].x:=-7;  te._frame1[3].y:=;
     te._frame1[4].x:=i+random(2);  te._frame1[4].y:=i+random(2);
     te._frame1[5].x:=i+random(2);  te._frame1[5].y:=i+random(2);
     te._frame1[6].x:=i+random(2);  te._frame1[6].y:=i+random(2);
     te._frame1[7].x:=i+random(2);  te._frame1[7].y:=i+random(2);
     te._frame1[8].x:=i+random(2);  te._frame1[8].y:=i+random(2);
     te._frame1[9].x:=i+random(2);  te._frame1[9].y:=i+random(2);
     te._frame1[10].x:=i+random(2);  te._frame1[10].y:=i+random(2);
  end;
 end; }
end;

procedure Draw_enemy(Canvas:Tcanvas; x,y,angle:integer; TE:TEnemy);
begin
 if angle=360 then angle:=0;
 try
 case TE._tip of
 teharder: begin
  canvas.Brush.Color:=clred;
  canvas.pen.Style:=psClear;

  canvas.Polygon([
  point(Round(((-5)*CosineArray^[Angle]-(-1)*SineArray^[Angle])+x),Round(((-5)*SineArray^[Angle]+(-1)*CosineArray^[Angle])+y) ),
  point(Round(((-3)*CosineArray^[Angle]-(-3)*SineArray^[Angle])+x),Round(((-3)*SineArray^[Angle]+(-3)*CosineArray^[Angle])+y)),
  point(Round(((2)*CosineArray^[Angle]-(-3)*SineArray^[Angle])+x),Round(((2)*SineArray^[Angle]+(-3)*CosineArray^[Angle])+y)),
  point(Round(((3)*CosineArray^[Angle]-(-1)*SineArray^[Angle])+x),Round(((3)*SineArray^[Angle]+(-1)*CosineArray^[Angle])+y)),
  point(Round(((3)*CosineArray^[Angle]-(1)*SineArray^[Angle])+x),Round(((3)*SineArray^[Angle]+(1)*CosineArray^[Angle])+y) ),
  point(Round(((2)*CosineArray^[Angle]-(3)*SineArray^[Angle])+x),Round(((2)*SineArray^[Angle]+(3)*CosineArray^[Angle])+y)),
  point(Round(((-3)*CosineArray^[Angle]-(3)*SineArray^[Angle])+x),Round(((-3)*SineArray^[Angle]+(3)*CosineArray^[Angle])+y)),
  point(Round(((-5)*CosineArray^[Angle]-(1)*SineArray^[Angle])+x),Round(((-5)*SineArray^[Angle]+(1)*CosineArray^[Angle])+y))
    ]);
  
  canvas.Polygon([
  point(Round(((-5)*CosineArray^[Angle]-(-5)*SineArray^[Angle])+x),Round(((-5)*SineArray^[Angle]+(-5)*CosineArray^[Angle])+y)),
  point(Round(((-4)*CosineArray^[Angle]-(-8)*SineArray^[Angle])+x),Round(((-4)*SineArray^[Angle]+(-8)*CosineArray^[Angle])+y)),
  point(Round(((5)*CosineArray^[Angle]-(-6)*SineArray^[Angle])+x),Round(((5)*SineArray^[Angle]+(-7)*CosineArray^[Angle])+y)),
  point(Round(((7)*CosineArray^[Angle]-(-5)*SineArray^[Angle])+x),Round(((7)*SineArray^[Angle]+(-5)*CosineArray^[Angle])+y))]);

  canvas.Polygon([
  point(Round(((-5)*CosineArray^[Angle]-(5)*SineArray^[Angle])+x),Round(((-5)*SineArray^[Angle]+(5)*CosineArray^[Angle])+y)),
  point(Round(((-4)*CosineArray^[Angle]-(8)*SineArray^[Angle])+x),Round(((-4)*SineArray^[Angle]+(8)*CosineArray^[Angle])+y)),
  point(Round(((5)*CosineArray^[Angle]-(6)*SineArray^[Angle])+x),Round(((5)*SineArray^[Angle]+(7)*CosineArray^[Angle])+y)),
  point(Round(((7)*CosineArray^[Angle]-(5)*SineArray^[Angle])+x),Round(((7)*SineArray^[Angle]+(5)*CosineArray^[Angle])+y))]);


  canvas.pen.Style:=psSolid;
 end;
   teMeloch: begin
  canvas.Brush.Color:=$A0E18;
  canvas.pen.Color:=clblack;
 // canvas.pen.Style:=psClear;
  canvas.Polygon([
  point(Round(((9)*CosineArray^[Angle]-(0)*SineArray^[Angle])+x),Round(((9)*SineArray^[Angle]+(0)*CosineArray^[Angle])+y) ),
  point(Round(((7)*CosineArray^[Angle]-(1)*SineArray^[Angle])+x),Round(((7)*SineArray^[Angle]+(1)*CosineArray^[Angle])+y)),
  point(Round(((1)*CosineArray^[Angle]-(1)*SineArray^[Angle])+x),Round(((1)*SineArray^[Angle]+(1)*CosineArray^[Angle])+y)),
  point(Round(((1)*CosineArray^[Angle]-(2)*SineArray^[Angle])+x),Round(((1)*SineArray^[Angle]+(2)*CosineArray^[Angle])+y)),
  point(Round(((3)*CosineArray^[Angle]-(4)*SineArray^[Angle])+x),Round(((3)*SineArray^[Angle]+(4)*CosineArray^[Angle])+y)),
  point(Round(((-1)*CosineArray^[Angle]-(4)*SineArray^[Angle])+x),Round(((-1)*SineArray^[Angle]+(4)*CosineArray^[Angle])+y)),
  point(Round(((-4)*CosineArray^[Angle]-(-2)*SineArray^[Angle])+x),Round(((-4)*SineArray^[Angle]+(-2)*CosineArray^[Angle])+y)),

  point(Round(((-4)*CosineArray^[Angle]-(2)*SineArray^[Angle])+x),Round(((-4)*SineArray^[Angle]+(2)*CosineArray^[Angle])+y)),
  point(Round(((-1)*CosineArray^[Angle]-(-4)*SineArray^[Angle])+x),Round(((-1)*SineArray^[Angle]+(-4)*CosineArray^[Angle])+y)),
  point(Round(((3)*CosineArray^[Angle]-(-4)*SineArray^[Angle])+x),Round(((3)*SineArray^[Angle]+(-4)*CosineArray^[Angle])+y)),
  point(Round(((1)*CosineArray^[Angle]-(-2)*SineArray^[Angle])+x),Round(((1)*SineArray^[Angle]+(-2)*CosineArray^[Angle])+y)),
  point(Round(((1)*CosineArray^[Angle]-(-1)*SineArray^[Angle])+x),Round(((1)*SineArray^[Angle]+(-1)*CosineArray^[Angle])+y)),
  point(Round(((7)*CosineArray^[Angle]-(-1)*SineArray^[Angle])+x),Round(((7)*SineArray^[Angle]+(-1)*CosineArray^[Angle])+y))]
  );
  canvas.Brush.Color:=$3F8383;
  canvas.pen.Style:=psClear;
  canvas.Polygon([
  point(Round(((-2)*CosineArray^[Angle]-(-1)*SineArray^[Angle])+x),Round(((-2)*SineArray^[Angle]+(-1)*CosineArray^[Angle])+y)),
  point(Round(((0)*CosineArray^[Angle]-(-1)*SineArray^[Angle])+x),Round(((0)*SineArray^[Angle]+(-1)*CosineArray^[Angle])+y)),
  point(Round(((0)*CosineArray^[Angle]-(1)*SineArray^[Angle])+x),Round(((0)*SineArray^[Angle]+(1)*CosineArray^[Angle])+y)),
  point(Round(((-2)*CosineArray^[Angle]-(1)*SineArray^[Angle])+x),Round(((-2)*SineArray^[Angle]+(1)*CosineArray^[Angle])+y))]);

  canvas.pen.Style:=psSolid;
  end;

  teBugay: begin
  canvas.Brush.Color:=$A0E18;
  canvas.pen.Color:=clblack;
  canvas.Polygon([
  point(Round(((-5)*CosineArray^[Angle]-(-1)*SineArray^[Angle])+x),Round(((-5)*SineArray^[Angle]+(-1)*CosineArray^[Angle])+y) ),
  point(Round(((-3)*CosineArray^[Angle]-(-3)*SineArray^[Angle])+x),Round(((-3)*SineArray^[Angle]+(-3)*CosineArray^[Angle])+y)),
  point(Round(((2)*CosineArray^[Angle]-(-3)*SineArray^[Angle])+x),Round(((2)*SineArray^[Angle]+(-3)*CosineArray^[Angle])+y)),
  point(Round(((3)*CosineArray^[Angle]-(-1)*SineArray^[Angle])+x),Round(((3)*SineArray^[Angle]+(-1)*CosineArray^[Angle])+y)),
  point(Round(((3)*CosineArray^[Angle]-(1)*SineArray^[Angle])+x),Round(((3)*SineArray^[Angle]+(1)*CosineArray^[Angle])+y) ),
  point(Round(((2)*CosineArray^[Angle]-(3)*SineArray^[Angle])+x),Round(((2)*SineArray^[Angle]+(3)*CosineArray^[Angle])+y)),
  point(Round(((-3)*CosineArray^[Angle]-(3)*SineArray^[Angle])+x),Round(((-3)*SineArray^[Angle]+(3)*CosineArray^[Angle])+y)),
  point(Round(((-5)*CosineArray^[Angle]-(1)*SineArray^[Angle])+x),Round(((-5)*SineArray^[Angle]+(1)*CosineArray^[Angle])+y))
    ]);
  
  canvas.Polygon([
  point(Round(((-5)*CosineArray^[Angle]-(-5)*SineArray^[Angle])+x),Round(((-5)*SineArray^[Angle]+(-5)*CosineArray^[Angle])+y)),
  point(Round(((-4)*CosineArray^[Angle]-(-8)*SineArray^[Angle])+x),Round(((-4)*SineArray^[Angle]+(-8)*CosineArray^[Angle])+y)),
  point(Round(((5)*CosineArray^[Angle]-(-6)*SineArray^[Angle])+x),Round(((5)*SineArray^[Angle]+(-7)*CosineArray^[Angle])+y)),
  point(Round(((7)*CosineArray^[Angle]-(-5)*SineArray^[Angle])+x),Round(((7)*SineArray^[Angle]+(-5)*CosineArray^[Angle])+y))]);

  canvas.Polygon([
  point(Round(((-5)*CosineArray^[Angle]-(5)*SineArray^[Angle])+x),Round(((-5)*SineArray^[Angle]+(5)*CosineArray^[Angle])+y)),
  point(Round(((-4)*CosineArray^[Angle]-(8)*SineArray^[Angle])+x),Round(((-4)*SineArray^[Angle]+(8)*CosineArray^[Angle])+y)),
  point(Round(((5)*CosineArray^[Angle]-(6)*SineArray^[Angle])+x),Round(((5)*SineArray^[Angle]+(7)*CosineArray^[Angle])+y)),
  point(Round(((7)*CosineArray^[Angle]-(5)*SineArray^[Angle])+x),Round(((7)*SineArray^[Angle]+(5)*CosineArray^[Angle])+y))]);


  canvas.pen.Style:=psClear;
  canvas.Brush.Color:=$3F8383;

  canvas.Polygon([
  point(Round(((-2)*CosineArray^[Angle]-(-2)*SineArray^[Angle])+x),Round(((-2)*SineArray^[Angle]+(-2)*CosineArray^[Angle])+y)),
  point(Round(((1)*CosineArray^[Angle]-(-2)*SineArray^[Angle])+x),Round(((1)*SineArray^[Angle]+(-2)*CosineArray^[Angle])+y)),
  point(Round(((1)*CosineArray^[Angle]-(1)*SineArray^[Angle])+x),Round(((1)*SineArray^[Angle]+(1)*CosineArray^[Angle])+y)),
  point(Round(((-2)*CosineArray^[Angle]-(1)*SineArray^[Angle])+x),Round(((-2)*SineArray^[Angle]+(1)*CosineArray^[Angle])+y))]);

  canvas.pen.Style:=psSolid;
  end;

 end;
 except
 end;
end;

procedure TContenerEnemy.adden(x,y:integer;TTE:TTypeEnemy);
var i:integer; TE:TEnemy;
begin
if List.Size<>0 then begin
 for i:=0 to (List.Size div sizeof(TEnemy))-1 do begin
  List.Position:=sizeof(TEnemy)*i;
  List.ReadBuffer(te,sizeof(TEnemy));
  if not(te._use) then begin
   List.Position:=sizeof(TEnemy)*i;
   te.XPos:=x;      //teMeloch,,
   te.YPos:=y;
   te.x_t:=-1;
   te.y_t:=-1;
   te._OnTarget:=false;
  case TTE of
    teMeloch: begin
    te._radius:=3;
    te.helth:=60;
    te._speed:=1.7;
     end;
    teBugay: begin
    te._radius:=5;
    te.helth:=100;
    te._speed:=1;
     end;
    teharder: begin
    te._radius:=9;
    te.helth:=180;
    te._speed:=0.7;
     end;
  end;
   te._tip:=tte;
   te._use:=true;
   te.ID:=i;
   te.angle:=0;
   prepareEnemy(te);
   List.Write(te,sizeof(TEnemy));
   exit;
  end;
 end; end;

 if List.Size<>0 then List.Position:=List.Size;
   te.XPos:=x;
   te.YPos:=y;
   case TTE of
    teMeloch: begin
    te._radius:=3;
    te.helth:=60;
    te._speed:=1.7;
     end;
    teBugay: begin
    te._radius:=5;
    te.helth:=100;
    te._speed:=1;
     end;
    teharder: begin
    te._radius:=9;
    te.helth:=180;
    te._speed:=0.7;
     end;
  end;
   te._tip:=tte;
   te._use:=true;
   te.angle:=0;
   te.x_t:=-1;
   te.y_t:=-1;
   te._OnTarget:=false;
   prepareEnemy(te);
 if List.Size<>0 then te.ID:=(List.Size div sizeof(TEnemy)) else te.ID:=0;
  List.Write(te,sizeof(TEnemy));
end;

procedure TContenerEnemy.delen(ID:integer);
var i:integer; TE:TEnemy;
begin
if List.Size<>0 then
 for i:=0 to (List.Size div sizeof(TEnemy))-1 do begin
  List.Position:=sizeof(TEnemy)*i;
  List.ReadBuffer(te,sizeof(TEnemy));
  if te._use then
  if te.ID=ID then begin
   List.Position:=sizeof(TEnemy)*i;
   te._use:=false;
   List.WriteBuffer(te,sizeof(TEnemy));
   exit;
  end;
 end;
end;

procedure TContenerEnemy.clear;
var i:integer; TE:TEnemy;
begin
if List.Size<>0 then
 for i:=0 to (List.Size div sizeof(TEnemy))-1 do begin
  List.Position:=sizeof(TEnemy)*i;
  List.ReadBuffer(te,sizeof(TEnemy));
  te._use:=false;
  List.Position:=sizeof(TEnemy)*i;
  List.WriteBuffer(te,sizeof(TEnemy));
 end;
end;

function InRect(x,y,left,top,right,down:integer):boolean;
begin
if (x>left)and(x<right)and(y>top)and(y<down) then InRect:=true else InRect:=false;
end;

procedure TContenerEnemy.draw(canvas:Tcanvas; _R:TRect);
var i,ii,Count:integer; TE:TEnemy;
begin
 ii:=0; //Count:=0;
if List.Size<>0 then
 for i:=0 to (List.Size div sizeof(TEnemy))-1 do begin
  List.Position:=sizeof(TEnemy)*i;
  List.ReadBuffer(te,sizeof(TEnemy));
  if te._use then  begin
    ii:=ii+1;
  if  InRect(trunc(te.XPos),trunc(te.yPos),_r.Left-24,_r.Top-24,_r.Right+12,_r.Bottom+12) then begin

  Draw_enemy(Canvas,trunc(te.XPos),trunc(te.yPos),te.angle,te);

  end;

  end;
 end;
// Canvas.TextOut(200,200,inttostr(count));
 _count:=ii;

end;

function GetTrace(x1,y1,x2,y2:integer):integer;
var ix,iy:integer;
begin
 // ix:=x1-x2; //if ix<0 then ix:=ix*(-1);
 // iy:=y1-y2; //if iy<0 then iy:=iy*(-1);
  result:=trunc(sqrt(sqr(x1-x2)+sqr(y1-y2)));
end;

function GetPosOnTargetPoint(x1,y1,x,y,rad:integer):boolean;
begin
if GetTrace(x1,y1,x,y)>rad then result:=true else result:=false;
end;

function GetCoordinate(x1,y1, x,y:integer):TRPoint;
var i:integer;
begin
result.x:=x;
result.y:=y;
randomize;
 if (x1-x)>=0 then  begin
  result.X:=random(x1-x)+x;
  end else begin
  result.X:=random((x1-x)*(-1))*(-1)+x; end;
 if (y1-y)>=0 then
  result.y:=random(y1-y)+y else
  result.y:=random((y1-y)*(-1))*(-1)+y;
end;


function GetTargetPoint(var TE:TEnemy; x,y:integer):boolean;
var ii:integer; TRR:TRPoint;
begin
result:=false;
if te._OnTarget then begin
if GetPosOnTargetPoint(trunc(te.XPos),trunc(te.YPos),te.x_t,te.y_t,3) then begin
ii:=GetAngle(te.x_t,te.y_t,trunc(te.XPos),trunc(te.yPos));
te.angle:=ii;
te.XPos:=te.XPos+(te._speed)*CosineArray^[ii];
te.yPos:=te.yPos+(te._speed)*SineArray^[ii];
end else begin
if GetPosOnTargetPoint(trunc(te.XPos),trunc(te.YPos),x,y,3) then begin
 te._OnTarget:=false;

 end;
end;
end else begin
if GetPosOnTargetPoint(trunc(te.XPos),trunc(te.YPos),x,y,5) then begin
TRR:=GetCoordinate(trunc(te.XPos),trunc(te.YPos),x,y);
te.x_t:=trunc(TRR.X);
te.y_t:=trunc(TRR.Y);
ii:=GetAngle(te.x_t,te.y_t,trunc(te.XPos),trunc(te.yPos));
te.angle:=ii;
te.XPos:=te.XPos+(te._speed)*CosineArray^[ii];
te.yPos:=te.yPos+(te._speed)*SineArray^[ii];
te._OnTarget:=true;
end else result:=true;
end;



end;


function TContenerEnemy.AI(x,y:integer):integer;
var i,ii:integer; TE:TEnemy;  Rad:single;
begin
result:=0;
ii:=0;
if List.Size<>0 then
 for i:=0 to (List.Size div sizeof(TEnemy))-1 do begin
  List.Position:=sizeof(TEnemy)*i;
  List.ReadBuffer(te,sizeof(TEnemy));
  if te._use then  begin
  // ii:=GetAngle(x,y,trunc(te.XPos),trunc(te.yPos));

    // Rad := 30/(exp(0.3 * ln(2)));
   //  cos(Line[i + 1])*Rad*2, sin(Line[i + 1])*Rad*2
  if GetTargetPoint(te,x,y) then
   case te._tip of
     teMeloch : ii:=ii+2;
     teBugay  : ii:=ii+5;
     teharder : ii:=ii+9;
   end;
  
    // te.angle:=ii;
    // te.XPos:=te.XPos+(te._speed)*CosineArray^[ii];
    // te.yPos:=te.yPos+(te._speed)*SineArray^[ii];
    //
    // te.XPos:=te.XPos+(te._speed)*cos(ii)*Rad;
    // te.yPos:=te.yPos+(te._speed)*sin(ii)*Rad;

     
   List.Position:=sizeof(TEnemy)*i;
   List.Write(te,sizeof(TEnemy));
  end;
 end;
 result:=ii;
end;

end.

