unit UnitPociski;

interface

uses OmegaImageList, OmegaScreen, OmegaSprite,OmegaInput,UnitWarstwy, classes,praduszek;

const
 cKaty:array[0..7,0..3]of single=
     (
        (270.00000 ,4.71238898 ,-1.000, 0.000),//N
        (323.13010 ,5.639684157,-0.600, 0.800),//NE
        (0         ,0          ,0     , 1),    //E
        (36.86990  ,0.64350115 ,0.600 , 0.800),//SE
        (90.00000  ,1.570796327,1.000 , 0.000),//S
        (143.13010 ,2.498091504,0.600 ,-0.800),//SW
        (180.00000 ,3.141592654,0.000 ,-1.000),//W
        (216.86990 ,3.785093803,-0.600,-0.800) //NW
      );

 cKlatkiPocisku:array[0..0,0..7,0..8]of byte=(
   (
    (8,8,8,8,8,8,8,8,8),         //N
    (5,4,3,2,1,31,30,29,28),     //NE
    (4,3,2,1,0,31,30,29,28),     //E
    (2,1,31,30,29,28,27,26,25),  //SE
    (24,24,24,24,24,24,24,24,24),//S
    (15,14,17,18,19,20,21,22,23),//SW
    (12,13,14,15,16,17,18,19,20),//W
    (11,12,13,14,15,18,19,20,21) //NW
    )//dla pocisku klasy tDzida- Ord(tDzida) da indeks 0
  );
type

 tTypPocisku=(tDzida);
 tPocisk=class(TSprite)
    fSmiercZUplywuCzasu,
    fStopAnimacja:boolean;
    fCountSmiercZUplywuCzasu,
    dxAnimacji,
    dVx,dVy,
    cosAlfa,
    sinAlfa,
    fAlfa:single;
    fTyp:tTypPocisku;
    fKierunek:tKierunek;
    fKlatkaAnimacji:integer;
    constructor Create(const AParent: TOmegaSprite;
                       const AOmegaImageList: TOmegaImageList;
                       const ATyp:tTypPocisku;
                       const AKierunek:tKierunek;
                       const AX,AY:single
                       );virtual;
   private
    fidKafla,
    fKolumna,
    fWiersz:longWord;
    procedure Pozycja(const aX,aY:single;const ADW,ADH:integer);
    property typ:tTypPocisku read fTyp write fTyp;
    property Kierunek:tKierunek read fKierunek write fKierunek;
    procedure SmiercZUplywuCzasu(const MoveCount: Single);
    procedure Move(const MoveCount: Single); override;
    procedure Dead; override;
    procedure onCollision(const Sprite:Tsprite;const colX,colY:integer);override;
 end;
procedure RobPocisk(const AParent: TOmegaSprite;
                    const AOmegaImageList: TOmegaImageList;
                    const ATyp:tTypPocisku;
                    const AKierunek:tKierunek;
                    const AX,AY:single
                    );

implementation
procedure TPocisk.Dead;
begin
 inherited Dead;
end;

procedure TPocisk.SmiercZUplywuCzasu(const MoveCount: Single);
begin
 if fCountSmiercZUplywuCzasu<10 then fCountSmiercZUplywuCzasu:=fCountSmiercZUplywuCzasu+MoveCount
 else Dead;
end;

procedure TPocisk.onCollision(const Sprite:Tsprite;const colX,colY:integer);
begin
  if (Sprite is TKostkaMapy)then
  begin
     //akcje w mapie świata gry
     PMapa(Lista.Items[TKostkaMapy(Sprite).idWskMApy])^[TKostkaMapy(Sprite).fIDKafla].idKlatka:=-1;
     PMapa(Lista.Items[TKostkaMapy(Sprite).idWskMApy])^[TKostkaMapy(Sprite).fIDKafla+DaneMapy.XCount].RGBA.zakazWstepu:=0;
     PMapa(Lista.Items[TKostkaMapy(Sprite).idWskMApy])^[TKostkaMapy(Sprite).fIDKafla].Animacja.fKolizja:=false;
     TKostkaMapy(Sprite).ZmianaKlatki;
     //akcje pocisku
     fSmiercZUplywuCzasu:=true;
     fStopAnimacja:=true;
     dVx:=0;
     dVy:=0;
     DoCollision:=false;
  end;
end;

procedure TPocisk.Move(const MoveCount: Single);
begin
 if (fidKafla<0) or (fidKafla>DaneMapy.xCount*DaneMapy.yCount-1) then dead;
 SmiercZUplywuCzasu(MoveCount);
 inherited Move(MoveCount);
 if not fStopAnimacja then
  begin
    X:= X+dVx*MoveCount*CosAlfa+SkokX;
    Y:= Y+dVy*MoveCount*SinAlfa+SkokY;
    Pozycja(x,y,DaneMApy.W1Kosc,DAneMapy.H1Kosc);
    dXAnimacji:=dXAnimacji+MoveCount;
    if dXAnimacji>MoveCount*15 then begin
                        inc(fKlatkaAnimacji);
                        if fKlatkaAnimacji>high(cKlatkiPocisku[Ord(typ),Ord(kierunek)])-1then
                           begin fStopAnimacja:=true;
                                 fSmiercZUplywuCzasu:=true;
                           end;
                        ImageIndex:=cKlatkiPocisku[Ord(typ),Ord(kierunek),fKlatkaAnimacji];
                        dXAnimacji:=0;
                        end;
  end
 else
  begin
    X:= X+SkokX;
    Y:= Y+SkokY;
    Pozycja(x,y,DaneMApy.W1Kosc,DAneMapy.H1Kosc);
    z:=z-7;//połóż na trawie;
  end;

end;

constructor tPocisk.Create(const AParent: TOmegaSprite;
                           const AOmegaImageList: TOmegaImageList;
                           const ATyp:tTypPocisku;
                           const AKierunek:tKierunek;
                           const AX,AY:single
                           );
begin
 inherited Create(AParent);
 fSmiercZUplywuCzasu:=false;
 fCountSmiercZUplywuCzasu:=0;
 fStopAnimacja:=false;
 fKlatkaAnimacji:=0;
 dxAnimacji:=0;
 x:=AX;
 y:=AY;
 typ:=ATyp;
 case typ of
  tDzida:begin Image:=AOmegaImageList.ImageList.Find('dzida1');
               dVx:=350;
               dVy:=dVx*DaneMApy.H1Kosc/DaneMApy.W1Kosc;
         end;
 end;

 width        :=Image.TileWidth;
 height       :=Image.TileHeight;

 DoCollision  :=true;
 DoPixelCheck :=true;

 Kierunek:=AKierunek;

 fAlfa  :=ckaty[ord(Kierunek),1];
 sinAlfa:=ckaty[ord(Kierunek),2];
 cosAlfa:=ckaty[ord(Kierunek),3];

 ImageIndex:=cKlatkiPocisku[Ord(typ),Ord(kierunek),0];
end;


procedure tPocisk.Pozycja(const aX,aY:single;const ADW,ADH:integer);
 var

   k,w:integer;
 begin
   fkolumna:=Round(ax-RogSwiata.x+Image.TileWidth div 2)div ADW;
   fWiersz :=Round(ay-RogSwiata.y+Image.TileHeight div 2)div ADH;
   fidKafla:=fKolumna+fWiersz*DaneMApy.XCount;
   k:=Round(ax+Image.TileWidth div 2)div ADW;
   w:=Round(ay+Image.TileHeight div 2)div ADH;
   if (k<=0)or(k>=DaneMapy.XSwiataEkranu-1-1)or
      (w<=0)or(w>=DaneMapy.YSwiataEkranu-1-1)then
      exit
      else Z:=SwiatProstokatnyWarstwy[1,k,w].z+8;

 end;

procedure RobPocisk(const AParent: TOmegaSprite;
                    const AOmegaImageList: TOmegaImageList;
                    const ATyp:tTypPocisku;
                    const AKierunek:tKierunek;
                    const AX,AY:single
                    );
begin
 TPocisk.Create(AParent,AOmegaImageList,ATyp,AKierunek,AX,AY);
end;
end.
