unit BaseBuild;

interface   

uses
  _Geometry,
  Frost.Engine,
  Frost.GL,
  _PNG;

type
TBuild = class(TComponent)
  protected
    FLife: Integer;
    FRenderer: TMeshRenderer;
    FActive: Boolean;
    FBounds: TVector3;
    FAnimateDeath: Boolean;
    FDeathTimer: Single;
    FFallAngle: TVector3;   
    FFallSpeed: Single;
    procedure CreateMesh(Mesh: TMesh; Material: TMaterial; Bounds: TVector3; Life: Integer);
    procedure CheckBoundCollision();
    procedure CheckActive();
    procedure Animate(const Delta: Double);
  public
    procedure OnStart; override;
    procedure OnUpdate(const Delta: Double); override;
    procedure OnDestroy; override;
  end;

implementation

uses
  Bullet,  
  Rocket,  
  Hero,
  SolidParticle,
  BlowEffect;

{$REGION 'Factory'}
procedure TBuild.CreateMesh(Mesh: TMesh; Material: TMaterial; Bounds: TVector3; Life: Integer);
begin
  FRenderer := TMeshRenderer.CreateMeshRenderer(Mesh, Material);
  GameObject.AddComponent(FRenderer);
  FActive := True;
  FLife := Life;
  FBounds := Bounds;
  FAnimateDeath := False;
  FFallAngle := GetVector(Random(360), 1);
  FFallSpeed := 1 + Random(6)* 0.5;
end;

procedure TBuild.CheckActive();
begin
end;

procedure TBuild.CheckBoundCollision();   
var
  i, j: Integer;
begin
  if (GameObject.Enabled <> FActive) then
  begin
    FActive := GameObject.Enabled;
    if (FLife > 0) then
    begin
      FRenderer.Enable := FActive;
    end;
  end;
  if (GameObject.Enabled) and (FLife > 0) then
  begin
    for i := 0 to MAX_BULLETS do
    if (Bullets[i].Active) and (Bullets[i].Owner = THero.FInstance.GameObject) then
    begin
      if
        (Bullets[i].GameObject.Position.X > GameObject.LocalPosition.X - FBounds.X) and
        (Bullets[i].GameObject.Position.X < GameObject.LocalPosition.X + FBounds.X) and
        (Bullets[i].GameObject.Position.Y > GameObject.LocalPosition.Y - FBounds.Y) and
        (Bullets[i].GameObject.Position.Y < GameObject.LocalPosition.Y + FBounds.Y) and
        (Bullets[i].GameObject.Position.Z > GameObject.LocalPosition.Z - FBounds.Z) and
        (Bullets[i].GameObject.Position.Z < GameObject.LocalPosition.Z + FBounds.Z) then
        begin
          Bullets[i].Hide;
          FLife := FLife - 1;       
        end;
    end;       
    for i := 0 to MAX_ROCKETS do
    if (Rockets[i].Active) and (Rockets[i].Owner = THero.FInstance.GameObject) then
    begin
      if
        (Rockets[i].GameObject.Position.X > GameObject.LocalPosition.X - FBounds.X) and
        (Rockets[i].GameObject.Position.X < GameObject.LocalPosition.X + FBounds.X) and
        (Rockets[i].GameObject.Position.Y > GameObject.LocalPosition.Y - FBounds.Y) and
        (Rockets[i].GameObject.Position.Y < GameObject.LocalPosition.Y + FBounds.Y) and
        (Rockets[i].GameObject.Position.Z > GameObject.LocalPosition.Z - FBounds.Z) and
        (Rockets[i].GameObject.Position.Z < GameObject.LocalPosition.Z + FBounds.Z) then
        begin
          Rockets[i].Hide;
          FLife := FLife - 20;
        end;
    end;
    if (FLife <= 0) then
    begin
      FAnimateDeath := True;
      FDeathTimer := 0;
      for j := 0 to Random(3) + 2 do
        TBlowEffect.Blow(
          Vector3(GameObject.LocalPosition.X, GameObject.LocalPosition.Y,0) +
          Vector3( FBounds.X * (Random(20) - 10) * 0.04, FBounds.Y * (Random(20) - 10) * 0.04, 0),
          0.3 + Random(10) * 0.1);
    end;
  end;
end;

procedure TBuild.Animate(const Delta: Double);
var
  i: Byte;
begin
  if (FAnimateDeath) and (GameObject.Enabled) then
  begin
    for i := 0 to 1 + Random(3) do
      TParticle.Emit( Vector3(GameObject.LocalPosition.X, GameObject.LocalPosition.Y,0) +
        Vector3(
          FBounds.X * (Random(20) - 10) * 0.06,
          FBounds.Y * (Random(20) - 10) * 0.06,
          0),
        Vector3(Random(10) - 5, Random(10) - 5, Random(10) - 5) * 0.03,
        5, Random(8) * 0.1);
    FDeathTimer := FDeathTimer + Delta;
    GameObject.LocalPosition := Vector3(GameObject.LocalPosition.X, GameObject.LocalPosition.Y, (- FDeathTimer) * 0.2);
    GameObject.LocalRotation := Rotate(FDeathTimer * FFallSpeed, FFallAngle);
    if FDeathTimer > 12 then
    begin
      FAnimateDeath := False;
      FRenderer.Enable := False;
    end;
  end;
end;

procedure TBuild.OnStart;
begin

end;
         
procedure TBuild.OnUpdate(const Delta: Double);
begin
  CheckBoundCollision();
  Animate(Delta);
end;

procedure TBuild.OnDestroy;
begin

end;
{$ENDREGION}

end.
