unit uHero;

interface
uses
  LexUtils, zglHeader, uConst, uMaterials;

type
  TElement = record
    O, F, W, N, D : Integer;
  end;

  TBullet = record
    Enabled : Boolean;
    bpX, bpY, bmX, bmY : Single;
    Element : TElement;
    T : Integer;
  end;

  THero = class
    pX, pY, mX, mY, dX, dY : Single;
    W, H : Integer;
    Magic,
    Angle : Single;
    Health, Power : Integer;

    Bullet : array[1..7] of TBullet;
    ElArmor, ElAtack : TElement;
    PowerTime, TimerAtack : Integer;
    
    constructor Create;
    procedure DrawTex(dpX, dpY : Integer; Alpha : Byte; FX : Integer);
    procedure Draw;
    procedure Update;
    function  Collis(X, Y : SIngle) : Boolean;
    procedure Fire(inT : Integer; inElement : TElement);
    procedure Init;
  end;

implementation


function THero.Collis(X, Y: Single): Boolean;
begin
  Result := (X > pX - 15)
  and (X < pX + 30)
  and (Y > pY - 57)
  and (Y < pY + 45);
end;

constructor THero.Create;
begin
  Health := 5;
  Power := 6;
  Magic := 255;
end;

procedure THero.Draw;
var
  I : Integer;
begin
  fx2d_SetScale(2, 2);
  fx_SetBlendMode(FX_BLEND_NORMAL);
  DrawTex(trunc(pX - 64), trunc(pY - 64), 255, FX_BLEND);

  for I := 1 to 6 do
  if Bullet[I].Enabled then
  with Bullet[I] do
    asprite2d_Draw(mMagic, bpX - 16, bpY - 16, 32, 32, 0, T, 150);
end;

procedure THero.DrawTex(dpX, dpY : Integer; Alpha: Byte; FX: Integer);
begin
  asprite2d_Draw(mBroom, dpX, dpY, 128, 128, Angle, 1, Alpha, FX);
  asprite2d_Draw(mBody,  dpX, dpY, 128, 128, Angle, 1, Alpha, FX);
  asprite2d_Draw(mEyes,  dpX, dpY, 128, 128, Angle, 1, Alpha, FX);
  asprite2d_Draw(mMouse, dpX, dpY, 128, 128, Angle, 1, Alpha, FX);
  asprite2d_Draw(mStock, dpX, dpY, 128, 128, Angle, 1, Alpha, FX);
  asprite2d_Draw(mShoes, dpX, dpY, 128, 128, Angle, 1, Alpha, FX);
  asprite2d_Draw(mPants, dpX, dpY, 128, 128, Angle, 1, Alpha, FX);
  asprite2d_Draw(mShirt, dpX, dpY, 128, 128, Angle, 1, Alpha, FX);
  asprite2d_Draw(mHand,  dpX, dpY, 128, 128, Angle, 1, Alpha, FX);
  asprite2d_Draw(mHair,  dpX, dpY, 128, 128, Angle, 1, Alpha, FX);
  asprite2d_Draw(mCap,   dpX, dpY, 128, 128, Angle, 1, Alpha, FX);
end;

procedure THero.Fire(inT: Integer; inElement: TElement);
var
  I : Integer;
begin
  for I := 1 to 6 do
  if not Bullet[I].Enabled then
    Break;

  with Bullet[I] do
  begin
    Enabled := True;
    Element := inElement;
    T := inT;
    bpX := pX + 55 - dX;
    bpY := pY - 20 - dY;
    bmX := +14 + random(4);
    bmY := (random(5) - 2) / 1.7;
    TimerAtack := 8;
    Power := Power - 1;
    PowerTime := 0;
    pengine2d_AddEmitter( @em_broom_magic, nil, bpX, bpY );
  end;
end;

procedure THero.Init;
begin
  pX := 270;
  pY := WinH div 2;
  Health := 5;
  Power := 6;
  Magic := 255;
end;

procedure THero.Update;
var
  I : Integer;
begin
  dX := 0;

  if key_Down(K_A) or key_Down(K_LEFT) then
    dX := dX - 2*cSpeedX;
  if key_Down(K_D) or key_Down(K_RIGHT) then
    dX := dX + cSpeedX;

  pX := pX + dX;

  if (TimerAtack > 0) then
    TimerAtack := TimerAtack - 1
  else
  if (Power > 1) then
  begin
    pengine2d_AddEmitter( @em_bullet_magic[1], nil, pX + 55, pY - 20);
    if key_Down(K_SPACE) or key_Down(K_CTRL_L) then
      Fire(1, ElAtack);
  end;

  if Power <= 6 then
  begin
    if PowerTime < 252 then
      PowerTime := PowerTime + 7
    else
    begin
      PowerTime := 0;
      Power := Power + 1;
    end;
  end;

  if pX > maxX1 then pX := maxX1
  else
  if pX < maxX0 then pX := maxX0;

  if Magic > 0 then
  begin
    Magic :=  Magic - 0.075;

    pengine2d_AddEmitter( @em_broom_magic, nil, pX - 55, pY );
    dY := 0;
    if key_Down(K_W) or key_Down(K_UP) then
      dY := dY - cSpeedY;
    if key_Down(K_S) or key_Down(K_DOWN) then
      dY := dY + cSpeedY;
    pY := pY + dY;

    if pY > maxY1 then pY := maxY1
    else
    if pY < maxY0 then pY := maxY0;
  end
  else
  begin
    dY := dY + 0.1;
    pY := pY + dY;
  end;

  for I := 1 to 6 do
  if Bullet[I].Enabled then
  with Bullet[I] do
  begin
    bpX := bpX + bmX;
    bpY := bpY + bmY;
    pengine2d_AddEmitter( @em_bullet_magic[T], nil, bpX, bpY );
    if bpX > WinWx15 then
      Enabled := False;
  end;
end;

end.
