unit BlowEffect;

interface       

uses
  _Geometry,   
  Frost.Forms, 
  Frost.Renderers,
  Frost.Engine,
  Frost.GL,
  Frost.Utils,
  OpenGL;

const
  MAX_BLOWS = 50;

type
TBlowEffect = class(TComponent)
  const MAX_LIFE_TIME = 0.5;
  protected 
    class var FMesh: TMesh;        
    class var FMaterial: TMaterial;
  protected
    FActive: Boolean;
    FLife: Single;         
    FScale: Single;
    FRenderer: TMeshRenderer;
  public
    class procedure Init();
    class procedure Blow(Position: TVector3; Scale: Single = 0.15);
    procedure Hide;
    procedure OnStart(); override;
    procedure OnUpdate(const Delta: Double); override;
    procedure OnDestroy(); override;
    property Active: Boolean read FActive write FActive;
  end;

var
  Blows: array [0..MAX_BLOWS] of TBlowEffect;

implementation

uses
  SolidParticle,
  WorldScene;

{$REGION 'BaseEnemy'}
class procedure TBlowEffect.Init;
var
  i: Word;
begin
  for i := 0 to MAX_BLOWS do
    Blows[i] :=  TBlowEffect.Create(TGameObject.Create(nil));
end;

class procedure TBlowEffect.Blow(Position: TVector3; Scale: Single = 0.15);
var          
  i: Word;
begin
  for i := 0 to MAX_BLOWS do
    if (not Blows[i].FActive) then
    begin
      if (Random(10) = 0) then
        TParticle.Emit(Position, Vector3(Random(10) - 5, Random(10) - 5, Random(10) - 5) * 0.01, 3, 0.2);
      Blows[i].FActive := True;   
      Blows[i].FRenderer.Enable := True;
      Blows[i].GameObject.LocalPosition := Position;
      Blows[i].FLife := MAX_LIFE_TIME;
      Blows[i].GameObject.LocalScale := VECTOR3_ONE; 
      Blows[i].FScale := Scale;   
      break;
    end;
end;

procedure TBlowEffect.Hide;
begin
  FLife := 0.01;
  FRenderer.Enable := false;
end;

procedure TBlowEffect.OnStart;
begin
  if FMesh = nil then
  begin
    FMesh := TMesh.CreateSphere(1, 3);
    FMaterial := TColorMaterial.Create(Vector3(5.0,5.0,5.0));
  end;
  FActive := false;
  GameObject.LocalPosition := Vector3(0, 0, -100);
  FRenderer := TMeshRenderer.CreateMeshRenderer(FMesh, FMaterial);
  GameObject.AddComponent(FRenderer);
end;

procedure TBlowEffect.OnUpdate(const Delta: Double);
begin
  if (FActive) then
  begin
    GameObject.LocalScale := VECTOR3_ONE * (FScale * FLife / MAX_LIFE_TIME);
    if (FLife > 0) then
      FLife := FLife - Delta * 0.5;
    if (FLife <= 0) then
    begin
      FActive := false;
      FRenderer.Enable := false;
    end;
  end;
end;

procedure TBlowEffect.OnDestroy;
begin

end;
{$ENDREGION}

end.
