unit CustomGun;

interface

uses
  QuadEngine, Vec2f, CustomBullet, Units.Custom;

type
  TGunFire = reference to function: Boolean;
  TGunReloading = reference to function(ACapacity: Integer): Integer;

  TCustomGun = class
  private
    FOnFire: TGunFire;
    FOnReloading: TGunReloading;
    FTime: Double;
    FClip: Integer;
    FIsReloading: Boolean;
  protected
    FBulletClass: TBulletClass;
    FCapacity: Integer;
    FReloadingTime: Single;
    FShotTime: Single;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Init; virtual;
    procedure SetProc(AOnFire: TGunFire; AOnReloading: TGunReloading);
    procedure Process(const Delta: Double);
    procedure Draw; virtual;
    function PositionShot(AViewVector: TVec2f): TVec2f; virtual;
    procedure Fire(AUnit: TCustomUnit);
    procedure Reloading;
    property Clip: Integer read FClip;
    property Capacity: Integer read FCapacity;
  end;

implementation

uses
  Subject, Resources;

constructor TCustomGun.Create;
begin
  FTime := 0;
  FClip := 0;
  FBulletClass := nil;
  FOnFire := nil;
  FOnReloading := nil;
  FCapacity := 0;
  FReloadingTime := 0;
  FShotTime := 0;
  FIsReloading := False;
end;

procedure TCustomGun.Init;
begin
  if Assigned(FOnReloading) then
    FClip := FOnReloading(FCapacity);
end;

procedure TCustomGun.SetProc(AOnFire: TGunFire; AOnReloading: TGunReloading);
begin
  FOnFire := AOnFire;
  FOnReloading := AOnReloading;
end;

function TCustomGun.PositionShot(AViewVector: TVec2f): TVec2f;
begin
  Result := TVec2f.Create(0, 0);
end;

destructor TCustomGun.Destroy;
begin
  inherited;
end;

procedure TCustomGun.Reloading;
begin
  if Assigned(FOnReloading) then
  begin
    FTime := FTime + FReloadingTime;
    FIsReloading := True;
  end;
end;

procedure TCustomGun.Process(const Delta: Double);
begin
  if FTime > 0 then
  begin
    FTime := FTime - Delta;
    if FIsReloading and (FTime <= 0) then
    begin
      FClip := FOnReloading(FCapacity);
      FIsReloading := False;
    end;
  end;
end;

procedure TCustomGun.Fire(AUnit: TCustomUnit);
begin
  if (FTime > 0) or not Assigned(FBulletClass) or (FClip = 0) or FIsReloading then
    Exit;

  if Assigned(FOnFire) and FOnFire then
  begin
    FTime := FTime + FShotTime;
    Dec(FClip);
    FBulletClass.Create(AUnit, AUnit.Position {+ PositionShot(AUnit.ViewVector)}, AUnit.ViewVector);
  end;
end;

procedure TCustomGun.Draw;
var
  Position: TVec2f;
  W, i: Integer;
begin
  Position := TVec2f.Create(1, TGlobals.GHeight - 64 - 25);
  TGlobals.QuadRender.SetBlendMode(qbmSrcAlpha);
  W := Capacity * 6;
  TTextures.Holder.DrawMap(
    Position, Position + TVec2f.Create(16, 32),
    TVec2f.Create(0, 0), TVec2f.Create(0.25, 1)
  );

  TTextures.Holder.DrawMap(
    Position + TVec2f.Create(16, 0), Position + TVec2f.Create(W, 32),
    TVec2f.Create(0.25, 0), TVec2f.Create(0.50, 1)
  );

  TTextures.Holder.DrawMap(
    Position + TVec2f.Create(W, 0), Position + TVec2f.Create(16 + W, 32),
    TVec2f.Create(0.5, 0), TVec2f.Create(0.75, 1)
  );

  Position := Position + TVec2f.Create(6, 0);

  for i := 0 to FClip - 1 do
  begin
    TTextures.Holder.DrawMap(
      Position, Position + TVec2f.Create(16, 32),
      TVec2f.Create(0.75, 0), TVec2f.Create(1, 1)
    );
    Position := Position + TVec2f.Create(6, 0);
  end;
end;

end.
