unit BotMutant;

interface

uses
  QuadEngine, Vec2f, QuadEngine.Color, Units.Custom, GlobalTypes;

type
  TBotMutant = class(TCustomUnit)
  private
    FBotModel: TBotModel;
    FVector: TVec2f;
    FHero: TCustomUnit;
    FAtack: Boolean;
    FDamage: Integer;
  public
    constructor Create(const APosition: TVec2f); override;
    procedure Process(const Delta: Double); override;
    function FindHero: TCustomUnit;
    procedure SetParams(AScale: Single; AHP, ADamage: Integer);
    procedure Draw; override;

  published
    procedure Damage(AGamage: Single); override;
  end;

implementation

uses
  Resources, Math;

constructor TBotMutant.Create(const APosition: TVec2f);
begin
  inherited;
  FDefaultAnimation := baRun;
  FAnimation := baRun;
  FSpeed[baStep] := 30;
  FSpeed[baRun] := 100;
  FSpeed[baAtack] := 0;
  FSpeed[baDeath] := 0;
  FSpeed[baDead] := 0;

  FFrameSpeed[baStep] := 25;
  FFrameSpeed[baRun] := 30;
  FFrameSpeed[baAtack] := 40;
  FFrameSpeed[baDeath] := 40;
  FFrameSpeed[baDead] := 0;

  FRadius := 20;
end;

procedure TBotMutant.SetParams(AScale: Single; AHP, ADamage: Integer);
begin
  FScale := AScale;
  FHP := AHP;
  FMaxHP := AHP;
  FDamage := ADamage;
end;

procedure TBotMutant.Damage(AGamage: Single);
begin
  if FAnimation = baDeath then
    Exit;

  FHP := FHP - AGamage;
  if FHP <= 0 then
  begin
    Death;
    SetAnimation(baDeath);
  end
  else
    Hit;
end;

function TBotMutant.FindHero: TCustomUnit;
var
  i: Integer;
  Dis, D: Single;
begin
  Result := nil;
  Dis := 1000;
  for i := 0 to TGlobals.LevelHeroes.Count - 1 do
    if not TGlobals.LevelHeroes[i].IsNeedToKill then
    begin
      D := TGlobals.LevelHeroes[i].Position.Distance(Position);
      if (D < Dis) and (D < 200) then
      begin
        Dis := D;
        Result := TGlobals.LevelHeroes[i];
      end;
    end;
end;

procedure TBotMutant.Process(const Delta: Double);
begin
  if IsNeedToKill or (FAnimation = baDead) then
    Exit;

  FHero := FindHero;

  if Assigned(FHero) then
  begin
    FVector := (FHero.Position - Position).Normalize();
    FAngle := FVector.Angle + PI;

    if (FAnimation = baStep) or (FAnimation = baRun) then
      Position := Position + FVector * FSpeed[FAnimation] * Delta * FScale;

    if (FDefaultAnimation = FAnimation) and (Position.Distance(FHero.Position) < 40) then
    begin
      SetAnimation(baAtack);
      FAtack := false;
    end;

    if (FAnimation = baAtack) and not FAtack then
    begin
      FAtack := true;
      if Position.Distance(FHero.Position) < 40 then
        FHero.Damage(FDamage);
    end;
  end;

  FFrame := FFrame + Delta * FFrameSpeed[FAnimation];

  if FFrame > TTextures.Bots[FBotModel].Frames[FAnimation] then
    case FAnimation of
      baStep: FFrame := FFrame - TTextures.Bots[FBotModel].Frames[FAnimation];
      baRun: FFrame := FFrame - TTextures.Bots[FBotModel].Frames[FAnimation];
      baAtack: SetAnimation(FDefaultAnimation);
      baDeath:
        begin
          SetAnimation(baDead);
          Kill;
        end;
    end;
end;

procedure TBotMutant.Draw;
begin
  if not IsNeedToKill then
    TTextures.Bots[FBotModel].Textures[FAnimation].DrawRotFrame(Position, FAngle + 90, FScale, Floor(FFrame));

end;

end.
