unit uGameCore;

interface

uses
  zglHeader, uGmData, uGmTypes, uGmArena, uGmUtils, uGmCreature, uGmPathfind, uGmAI, uGmGUI;

procedure Game_Init;
procedure Game_Draw;
procedure Game_Update;
procedure Game_Quit;

var
  Mouse_TX  : integer;
  Mouse_TY  : integer;

implementation

//==============================================================================
procedure Game_Init;
begin
  Data_Load;
  Arena := TArena.Create;

  GmGUI_Init;

  GameState := 'Main Menu';
end;

//==============================================================================
procedure Game_Draw;
var
  tx, ty, i, j, hp, w : integer;
  SomeAction : boolean;
begin
  GetPickedHex( Mouse_X, Mouse_Y, Mouse_TX, Mouse_TY );

  SomeAction := Arena.SomeAction;
  if SelCr <> nil then
    if SelCr.PlayerN = 2 then SomeAction := True;
  if Winner <> 0 then SomeAction := True;
  if GameState <> 'Fight' then SomeAction := True;

  EndTurnBtn.Enabled := not SomeAction;

  //---- рисуем фон ------
  Arena.Background.Draw;

  //---- рисуем клетки по которым может ходить существо ------
  if SomeAction = False then
    for j := 0 to 8 do
      for i := 0 to 10 do
      begin
        tx := i * 54 + 84;
        ty := j * 46 + 100;
        if j mod 2 = 0 then tx := tx + 27;
        if Wave[ i, j ] > 0 then ssprite2d_Draw( BlackhexTex, tx, ty, 64, 64, 0 );
      end;

  if GameState = 'Shop' then
  begin
    for j := 0 to 8 do
    begin
      tx := 84;
      ty := j * 46 + 100;
      if j mod 2 = 0 then tx := tx + 27;
      for i := 0 to Arena.CreaturesCnt - 1 do
        if ( Arena.Creatures[ i ].TX = 0 ) and ( Arena.Creatures[ i ].TY = j ) then
        begin
          tx := -1;
          Break;
        end;
      if tx <> -1 then ssprite2d_Draw( BlackhexTex, tx, ty, 64, 64, 0 );
    end;
  end;

  //---- рисуем сетку ------
  Arena.Background.DrawGrid;

  for i := 0 to Arena.CreaturesCnt - 1 do
    with Arena.Creatures[ i ] do
      if State <> CS_DIE then
        ssprite2d_Draw( ShadowTex, X - 64, Y - 56, 128, 128, 0, 80 );

  if SomeAction = False then
  begin
    if SelCr <> nil then
    begin
      tx := SelCr.TX * 54 + 84;
      ty := SelCr.TY * 46 + 100;
      if SelCr.TY mod 2 = 0 then tx := tx + 27;
      ssprite2d_Draw( SelCrHexTex, tx, ty, 64, 64, 0 );
    end;
    //---- рисуем клетку на которую наведен курсор ------
    if ( StatsWnd.Visible = False ) and ( ExitConfirm = False ) then
      if ( Mouse_TX >= 0 ) and ( Mouse_TY >= 0 ) and ( Mouse_TX <= 10 ) and ( Mouse_TY <= 8 ) then
      begin
        tx := Mouse_TX * 54 + 84;
        ty := Mouse_TY * 46 + 100;
        if Mouse_TY mod 2 = 0 then tx := tx + 27;
        ssprite2d_Draw( BlackhexTex, tx, ty, 64, 64, 0 );
      end;
  end;

  //---- рисуем арену ------
  Arena.Draw;

  //---- рисуем здоровье существа ------
  for i := 0 to Arena.CreaturesCnt - 1 do
    with Arena.Creatures[ i ] do
      if ( State <> CS_WALK ) and ( State <> CS_DIE ) then
      begin
        hp := Health;
        if hp < 0 then hp := 0;
        pr2d_Rect( X - 10, Y + 9, 20, 15, $0077EE, 255, PR2D_FILL );
        pr2d_Rect( X - 10, Y + 9, 20, 15, $FFFF88, 200 );
        w := Round( text_GetWidth( Font2, u_IntToStr( hp ) ) );
        text_Draw( Font2, X - w div 2, Y + 12, u_IntToStr( hp ) );
      end;

  //---- задаем вид курсора ------
  CurState := CUR_CURSOR;
  if ( SomeAction = False ) and ( SelCr <> nil ) then
    if ( Mouse_TX >= 0 ) and ( Mouse_TY >= 0 ) and ( Mouse_TX <= 10 ) and ( Mouse_TY <= 8 ) then
    begin
      if Wave[ Mouse_TX, Mouse_TY ] > 1 then
      begin
        CurState := CUR_WALK;
        if SelCr.Pat.CanFly then CurState := CUR_FLY;
      end;
      if Wave[ Mouse_TX, Mouse_TY ] = -2 then
        if ( SelCr.Pat.CanShoot ) and ( CrIsBlocked( SelCr ) = False ) then
        begin
          CurState := CUR_SHOOT;
        end else
        begin
          CurState := CUR_ATACK;
          CurAng   := GetCursorAtackAngle( Mouse_TX, Mouse_TY, Mouse_X, Mouse_Y );
          if CurAng = -1 then CurState := CUR_CURSOR;
        end;
    end;
  if StatsWnd.Visible then CurState := CUR_NONE;
  if ExitConfirm then CurState := CUR_CURSOR;

  GmGUI_Draw;
end;

//==============================================================================
procedure Game_Update;
var
  ang, x2, y2, i, sn : integer;
  p1HasCr, p2HasCr, AllPohod : boolean;
  btn : PGmButton;
begin
  GmGUI_Update;

  if key_Press( K_ESCAPE ) then
  begin
    if GameState = 'Main Menu' then zgl_Exit;
    ExitConfirm := not( ExitConfirm );
    if ExitConfirm then
    begin
      GmButton_Get( 'Exit Yes' ).Visible := True;
      GmButton_Get( 'Exit No' ).Visible := True;
    end else
    begin
      GmButton_Get( 'Exit Yes' ).Visible := False;
      GmButton_Get( 'Exit No' ).Visible := False;
    end;
  end;
  if key_Down( K_ALT ) and key_Press( K_ENTER ) then
  begin
    FullScr := not( FullScr );
    scr_SetOptions( 800, 600, REFRESH_MAXIMUM, FullScr, False );
    btn := GmButton_Get( 'FScreen' );
    if FullScr then btn.Tex := FScrBtnTex2 else btn.Tex := FScrBtnTex;
  end;

  if ( Winner = 0 ) and ( GameState = 'Fight' ) and ( StatsWnd.Visible = False ) and ( ExitConfirm = False ) then
  begin
    if ( Arena.SomeAction = False ) and ( SelCr <> nil ) then
    begin
      if SelCr.PlayerN = 2 then AI_Kumekaet;

      if SelCr.PlayerN = 1 then
      begin
        GetPickedHex( Mouse_X, Mouse_Y, Mouse_TX, Mouse_TY );

        if mouse_Click( M_BLEFT ) then
          if ( Mouse_TX >= 0 ) and ( Mouse_TY >= 0 ) and ( Mouse_TX <= 10 ) and ( Mouse_TY <= 8 ) then
          begin
            if Wave[ Mouse_TX, Mouse_TY ] = -2 then
            begin
              if ( SelCr.Pat.CanShoot ) and ( CrIsBlocked( SelCr ) = False ) then
              begin
                SelCr.Shoot := True;
                SelCr.State := CS_ATACK;
                for i := 0 to Arena.CreaturesCnt - 1 do
                  if Arena.Creatures[ i ].State <> CS_DIE then
                    if ( Arena.Creatures[ i ].TX = Mouse_TX ) and ( Arena.Creatures[ i ].TY = Mouse_TY ) then
                      SelCr.AtackCr := Arena.Creatures[ i ];
              end else
              begin
                ang := GetCursorAtackAngle( Mouse_TX, Mouse_TY, Mouse_X, Mouse_Y );
                if ang <> -1 then
                begin
                  x2 := Mouse_TX;
                  y2 := Mouse_TY;
                  if ang = 0 then x2 := x2 - 1;
                  if ang = 180 then x2 := x2 + 1;
                  if ( ang = 45 ) or ( ang = 135 ) then
                  begin
                    if ( ang = 45 ) and ( y2 mod 2 <> 0 ) then x2 := x2 - 1;
                    if ( ang = 135 ) and ( y2 mod 2 = 0 ) then x2 := x2 + 1;
                    y2 := y2 - 1;
                  end;
                  if ( ang = 225 ) or ( ang = 315 ) then
                  begin
                    if ( ang = 225 ) and ( y2 mod 2 = 0 ) then x2 := x2 + 1;
                    if ( ang = 315 ) and ( y2 mod 2 <> 0 ) then x2 := x2 - 1;
                    y2 := y2 + 1;
                  end;

                  CreatePath( SelCr, x2, y2 );
                  if SelCr.PathLen > 0 then SelCr.State := CS_WALK;
                  if Wave[ x2, y2 ] = 1 then SelCr.State := CS_ATACK;
                  SelCr.Shoot := SelCr.Pat.CanShoot;

                  for i := 0 to Arena.CreaturesCnt - 1 do
                    if Arena.Creatures[ i ].State <> CS_DIE then
                      if ( Arena.Creatures[ i ].TX = Mouse_TX ) and ( Arena.Creatures[ i ].TY = Mouse_TY ) then
                        SelCr.AtackCr := Arena.Creatures[ i ];
                end;
              end;
            end else
            begin
              CreatePath( SelCr, Mouse_TX, Mouse_TY );
              if SelCr.PathLen > 0 then SelCr.State := CS_WALK;
            end;
          end;
      end;
    end;

    Arena.Update;

    if Arena.SomeAction = False then
    begin
      p1HasCr  := False;
      p2HasCr  := False;
      AllPohod := True;
      for i := 0 to Arena.CreaturesCnt - 1 do
        with Arena.Creatures[ i ] do
          if State <> CS_DIE then
          begin
            if PlayerN = 1 then p1HasCr := True;
            if PlayerN = 2 then p2HasCr := True;
            if Pohodil = False then AllPohod := False;
          end;

      if p1HasCr = False then Winner := 2;
      if p2HasCr = False then Winner := 1;
      if Winner = 1 then
        if file_Exists( '.\Data\Levels\Level' + u_IntToStr( LevN + 1 ) + '.lev' ) then
          GmButton_Get( 'Next' ).Visible := True;
      if Winner = 2 then GmButton_Get( 'Restart' ).Visible := True;

      if Winner = 0 then
      begin
        //---- все существа походили - начинаем новый раунд --------------------
        if AllPohod = True then
        begin
          for i := 0 to Arena.CreaturesCnt - 1 do
            with Arena.Creatures[ i ] do
            begin
              Pohodil := False;
              SdachaCnt := Pat.SdachaCnt;
            end;
          SelCr := Arena.GetNextCr;
          CreateWave( SelCr.TX, SelCr.TY, SelCr.Pat.Speed, SelCr.Pat.CanFly );
        end;
        //----------------------------------------------------------------------
        if SelCr.Pohodil = True then
        begin
          SelCr := Arena.GetNextCr;
          if SelCr.PlayerN = 1 then CreateWave( SelCr.TX, SelCr.TY, SelCr.Pat.Speed, SelCr.Pat.CanFly );
        end;

        for i := 0 to Arena.CreaturesCnt - 1 do
          with Arena.Creatures[ i ] do
            if State <> CS_DIE then
              LookLeft := ( PlayerN = 2 );

        if SelCr.PlayerN = 2 then AI_Kumekaet;
      end;
    end;
  end;

  if GameState = 'Shop' then
  begin
    if Mouse_Click( M_BLEFT ) and not mouse_Down( M_BRIGHT ) then
    begin
      GetPickedHex( Mouse_X, Mouse_Y, Mouse_TX, Mouse_TY );
      if Mouse_TX = 0 then
      begin
        sn := -1;
        for i := 0 to Arena.CreaturesCnt - 1 do
          if ( Arena.Creatures[ i ].TX = Mouse_TX ) and ( Arena.Creatures[ i ].TY = Mouse_TY ) then
          begin
            sn := i;
            Break;
          end;
        if sn <> -1 then
        begin
          Arena.Money := Arena.Money + Arena.Creatures[ sn ].Pat.Cost;
          Arena.Creatures[ sn ].Free;
          for i := sn to Arena.CreaturesCnt - 2 do
            Arena.Creatures[ i ] := Arena.Creatures[ i + 1 ];
          DEC( Arena.CreaturesCnt );
          SetLength( Arena.Creatures, Arena.CreaturesCnt );
        end;
      end;
    end;
  end;

  mouse_ClearState;
  key_ClearState;
end;

//==============================================================================
procedure Game_Quit;
begin
  Arena.Free;
end;

end.
