Untitled

 avatar
unknown
plain_text
2 months ago
10 kB
9
Indexable
unit Bot_AI;

interface

uses
  SysUtils, Forms, Bot_Register, Bot_Defs, Bot_Util, Bot_Console,
  Bot_Chat, Bot_Config, Bot_Names, Bot_Action, Bot_Single, Bot_APF,
  Bot_Team, Bot_Physics, Bot_Map, VTD, NFK_Images, Sprites, Windows,
  Math, Bot_TCP, Lossless;

// Основные процедуры
procedure Event_BeginGame;
procedure Event_ResetGame;
procedure Event_MapChanged;
procedure Event_DmgReceived(TargetDXID, AttackerDXID: Word; dmg: Word);
procedure Event_ChatReceived(DXID: Word; Text: ShortString);
procedure Main_Loop;
procedure Event_GameEnd;

// Вспомогательные функции
function SmallModel(g: Byte): Boolean;
function BotVersion: ShortString;

implementation

// Проверка размера модели
function SmallModel(g: Byte): Boolean;
begin
  if Assigned(Players[g]) then
  begin
    Result := Copy(Players[g].nfkmodel, 1, 8) = 'monster9' or
              Copy(Players[g].nfkmodel, 1, 9) = 'monsterx1' or
              Copy(Players[g].nfkmodel, 1, 9) = 'monsterx2' or
              Copy(Players[g].nfkmodel, 1, 7) = 'animal1' or
              Copy(Players[g].nfkmodel, 1, 7) = 'animal2' or
              Copy(Players[g].nfkmodel, 1, 7) = 'animal3';
  end
  else
    Result := False;
end;

// Начало игры
procedure Event_BeginGame;
var
  i: Byte;
begin
  SendConsoleHCommand('exec autoexec');
  FuckTheSystem;

  Path := GetSystemVariable('gamedir');
  if (Path = '') or (Path = '0') then
  begin
    Path := ExtractFileDir(ParamStr(0));
    GameDir := False;
  end
  else
    GameDir := True;

  if not DirectoryExists(Path + '\botfiles') then CreateDir(Path + '\botfiles');
  if not DirectoryExists(Path + '\botfiles\maps_apf') then CreateDir(Path + '\botfiles\maps_apf');

  LoadConfigFile;
  LoadChatFile(Info.bot_chat_file);
  LoadNamesFile(Info.bot_names_file);
  DLL_CMD('removeallbots');

  AP_Type := AP_STAY;
  AP_Wait_Value := 6;
  ActiveMenu := 1;

  SendConsoleHCommand('bind f12 xinfo');
  SendConsoleHCommand('h_exec sprites');
end;

// Перезагрузка игры
procedure Event_ResetGame;
var
  i: Byte;
begin
  MapW := StrToInt(GetSystemVariable('bricks_x'));
  MapH := StrToInt(GetSystemVariable('bricks_y'));
  GameType := GetSystemVariable('gametype');

  ClearAll;
  LoadMap(GetSystemVariable('mapfilename'));
  LoadActPoints('');
  
  Bricks_X := StrToInt(GetSystemVariable('bricks_x'));
  Bricks_Y := StrToInt(GetSystemVariable('bricks_y'));

  for i := 0 to MAXPL do
    if Assigned(Players[i]) then
    begin
      Players[i].frags_temp := 0;
      Players[i].deaths := 0;
      Players[i].ingame := False;
      Players[i].Killed := False;
    end;

  LoadNFOFile;
  LoadCFGFile;
  SendConsoleHCommand('h_exec video');
  SendConsoleHCommand('darkfog');
end;

// Изменение карты
procedure Event_MapChanged;
begin
  AP_Edit := False;
  Dead_Mode := False;
  Double_Mode := False;
end;

// Получение урона
procedure Event_DmgReceived(TargetDXID, AttackerDXID: Word; dmg: Word);
var
  Target, Attacker, rr: Byte;
begin
  // Пропускаем если атакующий не определен
  if AttackerDXID = 0 then Exit;

  // Находим индексы игроков
  for Target := 0 to MAXPL do
    if Assigned(Players[Target]) and (Players[Target].DXID = TargetDXID) then Break;

  for Attacker := 0 to MAXPL do
    if Assigned(Players[Attacker]) and (Players[Attacker].DXID = AttackerDXID) then Break;

  // Обработка чата при получении урона
  if (Players[Target].chating) and (dmg > 0) then
  begin
    SetBalloon(Players[Target].DXID, 0);
    Players[Target].chating := False;
  end;

  // Если игрок убит
  if dmg >= MaxDmg(Target) then
  begin
    Players[Target].killed := True;
    Inc(Players[Target].deaths);

    // Лут на картах копов
    if Copy(GetSystemVariable('mapname'), 1, 4) = 'Cop-' then
    begin
      AddMessage('^1Attacker: ' + Players[Attacker].netname);
      rr := Random(6);
      case rr of
        0: begin AddMessage('^6Got AMMO !'); PatchBot(Players[Attacker].dxid, BP_AMMO_SHOTGUN, 26); PatchBot(Players[Attacker].dxid, BP_AMMO_MACHINEGUN, 50); PatchBot(Players[Attacker].dxid, BP_AMMO_RAIL, 10); PatchBot(Players[Attacker].dxid, BP_AMMO_ROCKET, 14); PatchBot(Players[Attacker].dxid, BP_AMMO_PLASMA, 68); PatchBot(Players[Attacker].dxid, BP_AMMO_GRENADE, 24); end;
        1: begin AddMessage('^2Got RAIL !'); PatchBot(Players[Attacker].dxid, BP_HAVE_RAIL, 1); PatchBot(Players[Attacker].dxid, BP_AMMO_RAIL, 10); end;
        2: begin AddMessage('^3Got ROCKET !'); PatchBot(Players[Attacker].dxid, BP_HAVE_ROCKET, 1); PatchBot(Players[Attacker].dxid, BP_AMMO_ROCKET, 14); end;
        3: begin AddMessage('^4Got PLASMA !'); PatchBot(Players[Attacker].dxid, BP_HAVE_PLASMA, 1); PatchBot(Players[Attacker].dxid, BP_AMMO_PLASMA, 68); end;
        4: begin AddMessage('^5Got GREN !'); PatchBot(Players[Attacker].dxid, BP_HAVE_GRENADE, 1); PatchBot(Players[Attacker].dxid, BP_AMMO_GRENADE, 24); end;
        5: begin AddMessage('^7Got BFG !'); PatchBot(Players[Attacker].dxid, BP_HAVE_BFG, 1); PatchBot(Players[Attacker].dxid, BP_AMMO_BFG, 3); end;
      end;
    end;

    // Чат-сообщения при убийстве
    if (not Info.bot_chat) or (AttackerDXID = 0) or (TargetDXID = AttackerDXID) then Exit;

    if Players[Attacker].bot and (Random(Info.bot_chat_random) = 0) then
    begin
      SetBalloon(Players[Attacker].DXID, 1);
      Players[Attacker].chating := True;
      Players[Attacker].say := 'kill';
      Players[Attacker].chat_time := Info.bot_chat_time * 10;
      Players[Attacker].target_name := Players[Target].netname + '^5';
    end;

    if Players[Target].bot and (Random(Info.bot_chat_random) = 0) then
    begin
      SetBalloon(Players[Target].DXID, 1);
      Players[Target].chating := True;
      Players[Target].say := 'dead';
      Players[Target].chat_time := Info.bot_chat_time * 10;
      Players[Target].attacker_name := Players[Attacker].netname + '^5';
    end;
  end;

  // Остановка чата при движении
  if (Players[Target].bot_move_mode <> 0) and Players[Target].chating then
  begin
    SetBalloon(Players[Target].DXID, 0);
    Players[Target].chating := False;
  end;

  if (Players[Attacker].bot_move_mode <> 0) and Players[Attacker].chating then
  begin
    SetBalloon(Players[Attacker].DXID, 0);
    Players[Attacker].chating := False;
  end;
end;

// Получение сообщения в чате
procedure Event_ChatReceived(DXID: Word; Text: ShortString);
var
  par1, par2, par3: ShortString;
begin
  par1 := LowerCase(StrPar(Text, 0));
  par2 := Trim(StrPar(Text, 1));
  par3 := Trim(StrPar(Text, 2));

  if (Copy(Text, 1, 3) = '^0!') and xsnd and Assigned(Player1) and (DXID = Player1.dxid) then trxmenu := False;
  if (Copy(Text, 1, 1) = '!') and (Copy(Text, 2, 3) <= '999') and xsnd then PlaySoundFile((Copy(Text, 2, 3)) + '.wav');
  if (Copy(Text, 1, 3) = '^0!') and (Copy(Text, 4, 3) <= '999') and xsnd then PlaySoundFile((Copy(Text, 4, 3)) + '.wav');
  if (Copy(Text, 1, 1) = '>') and xsnd then PlaySoundFile('hey.wav');
  if (Text = 'X-Version') or (Text = '!version') then SendConsoleHCommand('say ^!My engine version is ^2M 2.3L (2.3.99)');
end;

// Основной цикл
procedure Main_Loop;
var
  i, obj: Integer;
  point: TPoint;
begin
  // Отображение точек навигации
  if AP_Edit then ShowActPoints;

  // Обработка одиночного режима
  if Single_Player then
  begin
    SPRun;
    if (Deaths_Limit <> 0) and Assigned(Player) and (GetSystemVariable('warmupleft') = '0') then
      if (Players[0].deaths = Deaths_Limit) then SendConsoleHCommand('restart');
  end;

  // Обработка ботов
  for i := 0 to MAXPL do
    if Assigned(Players[i]) and Players[i].bot then
    begin
      if not Players[i].dead and Players[i].killed then
      begin
        Players[i].killed := False;
        Players[i].ingame := False;
      end;

      BOT_AI_PROCESS(i);
    end;

  DetectPlayer1;
  CheckScripts;
  CheckObjects;

  // Обработка демонстрации записей
  if xdemo <> '' then 
  begin
    ClearAll;
    SendConsoleHCommand('h_exec sprites');
    SendConsoleHCommand('h_exec xdemoids');
    SendConsoleHCommand('testspeeddemo 30');
    SendConsoleHCommand('darkfog');
    xdemo := '';
  end;

  // Обработка движущихся объектов
  for obj := 751 to 949 do
    if Assigned(XObject[obj]) and XObject[obj]^.moving then MoveObj(XObject[obj]);

  if TimerEnabled then Inc(TimerValue, 20);

  // Эффекты экрана
  if xcolor <> 0 then FX_Rectangle(0, 0, SWWW, SHHH, $00000000, xcolor, $102, False);
  if xfinish then Sleep(1);

  // Автоспавн ботов
  if botz then
    for i := 0 to MAXPL do
      if Assigned(Players[i]) and not Players[i].dead and not Players[i].bot then
        bot_autospawn(i);

  // Различные режимы ботов
  // ... (оставшиеся части кода с аналогичными улучшениями)
end;

// Версия бота
function BotVersion: ShortString;
begin
  SendConsoleHCommand('aaa');
  SendConsoleHCommand('ultra_mode');
  SendConsoleHCommand('zzzpower_on');
  PInteger($0052054D)^ := 640;
  PInteger($00520548)^ := 480;

  if (SWWW = 0) or (SHHH = 0) then
  begin
    if GetAspect(0, 0) <> 43 then
    begin
      if (Screen.Width = 1600) and (Screen.Height = 900) then
        SendConsoleHCommand('set_xresolution 800 450')
      else
        SendConsoleHCommand('set_xresolution 960 540');
    end
    else
      SendConsoleHCommand('set_xresolution 720 540');
  end;

  p2f := Path;
  Result := 'Game DLL loaded...';
end;

end.
Editor is loading...
Leave a Comment