unit u_portal;

interface

uses u_map, u_const, zglHeader;

type
  TPortal = class(TObject)
    public
      fMap: TMap;
      fX, fY: single;
      fCounter, fPCounter: Single;
      fAngle: Integer;
      fClassOf: TBulletClass;
      fInited: Boolean;
      fExit: TPortal;
      fRTarget : zglPRenderTarget;

      property X: single read fX;
      property Y: single read fY;
      property ClassOf: TBulletClass read fClassOf;
      procedure Draw(DrawPortals: Boolean);
      procedure Update(dt: Double);
      constructor Create(pMap: TMap; pX, pY: Single; pAngle: Integer; pClassOf: TBulletClass);
      destructor Destroy; override;
  end;

implementation

uses u_game;

constructor TPortal.Create;
var fPX, fPY: Integer;
    oX, oY: single;
begin
  fMap := pMap;
  fX := pX; fY := pY;
  fAngle := pAngle;
  fInited := False;
  fClassOf := pClassOf;
  fPX := Trunc(fX);
  fPY := Trunc(fY);
  case fAngle of
    0, 2: fX := Round(fX);
    else fY := Round(fY);
  end;
  oX := fX - fPX;
  oY := fY - fPY;
  case fAngle of
    0, 2: begin
      if (oY > 0.5) and (Map.fData[fPY + 1][fPX].Block <> blPortable) then begin
        fY := Trunc(fY) + 0.5;
      end else
      if (oY < 0.5) and (Map.fData[fPY - 1][fPX].Block <> blPortable) then begin
        fY := Trunc(fY) + 0.5;
      end;
    end;
    else begin
      if (oX > 0.5) and (Map.fData[fPY][fPX + 1].Block <> blPortable) then begin
        fX := Trunc(fX) + 0.5;
      end else
      if (oX < 0.5) and (Map.fData[fPY][fPX - 1].Block <> blPortable) then begin
        fX := Trunc(fX) + 0.5;
      end;
    end;
  end;
  //Map.fData[fY][fX].Portal := self;
  if blEffects[blEffects[fClassOf].exit].portal <> nil then begin
    fExit := TPortal(blEffects[blEffects[fClassOf].exit].portal);
    TPortal(blEffects[blEffects[fClassOf].exit].portal).fExit := Self;

    if not fInited then begin
      portalsInit.AddEffect(
        fX * BLOCKSIZE,
        fY * BLOCKSIZE, fAngle * 90);
    end;

    if not fExit.fInited then begin
      portalsInit.AddEffect(
        fExit.fX * BLOCKSIZE,
        fExit.fY * BLOCKSIZE, fExit.fAngle * 90);
    end;
    fExit.fInited := true;
    fInited := True;
  end;
  snd_Play(portalOpen[Random(2)]);
  fRTarget := rtarget_Add(
   tex_CreateZero(PREDRAW_SIZE, PREDRAW_SIZE),
   RT_DEFAULT);
end;

destructor TPortal.Destroy;
begin
  blEffects[ClassOf].destroy.AddEffect(
      X * BLOCKSIZE, Y * BLOCKSIZE, 0);
  tex_Del(fRTarget.Surface);
  rtarget_Del(fRTarget);
  inherited;
end;

procedure TPortal.Draw;
begin

  asprite2d_Draw(txPortal,
    fX * BLOCKSIZE - BLOCKSIZE,
    fY * BLOCKSIZE - BLOCKSIZE,
    BLOCKSIZE * 2, BLOCKSIZE * 2,
    fAngle * 90, Byte(fClassOf) + 1);
  if not DrawPortals then
    Exit;
  if fExit = nil then
    Exit;

  if fCounter > 10 then begin

    rtarget_Set( fRTarget );
      pr2d_Rect(0, 0, PREDRAW_SIZE, PREDRAW_SIZE, $000000, 128, PR2D_FILL);
      fMap.Draw(
        fExit.fX * BLOCKSIZE - PREDRAW_SIZE div 2,
        fExit.fY * BLOCKSIZE - PREDRAW_SIZE div 2,
        (fAngle - fExit.fAngle + 2) * 90, 1, false);

      fx_SetBlendMode(FX_BLEND_MULT, false);
      ssprite2d_Draw(txZeroMask, 0, 0,
        PREDRAW_SIZE, PREDRAW_SIZE, 180 + fAngle * 90);
      fx_SetBlendMode(FX_BLEND_NORMAL);
      ssprite2d_Draw(txPortalEnd, 0, 0,
        PREDRAW_SIZE, PREDRAW_SIZE, 180 + fAngle * 90);
    rtarget_Set( nil );
    fCounter := 0;
  end;


end;

procedure TPortal.Update;
begin
  fCounter := fCounter + dt;
  fPCounter := fPCounter + dt;
  if fPCounter >= 100 then begin
    fPCounter := 0;
    blEffects[fClassOf].peffect.AddEffect(
      (fX + m_Cos(fAngle * 90) * 0.2 +
        m_Cos(fAngle * 90 + 90) * (Random(100)/100 - 0.5)) * BLOCKSIZE,
      (fY + m_Sin(fAngle * 90) * 0.2 +
         + m_Sin(fAngle * 90 + 90) * (Random(100)/100 - 0.5)) * BLOCKSIZE,
      fAngle * 90
    );
  end;
end;

end.
