DEADSOFTWARE

Allow not to specify a name in the bot preset to choose it from the general list
[d2df-sdl.git] / src / game / g_player.pas
index 38bb86a299228cfdd06c61bf01973c1aad915da4..0990c0e5ce43a17ff51a0ff1ff2c6cfe96bdb366 100644 (file)
@@ -573,7 +573,7 @@ type
 
   TTeamStat = Array [TEAM_RED..TEAM_BLUE] of
     record
-      Goals: SmallInt;
+      Score: SmallInt;
     end;
 
 var
@@ -600,6 +600,10 @@ procedure g_Gibs_SetMax(Count: Word);
 function  g_Gibs_GetMax(): Word;
 procedure g_Corpses_SetMax(Count: Word);
 function  g_Corpses_GetMax(): Word;
+procedure g_Force_Model_Set(Mode: Word);
+function g_Force_Model_Get(): Word;
+procedure g_Forced_Model_SetName(Model: String);
+function  g_Forced_Model_GetName(): String;
 procedure g_Shells_SetMax(Count: Word);
 function  g_Shells_GetMax(): Word;
 
@@ -619,7 +623,7 @@ procedure g_Player_ResetAll(Force, Silent: Boolean);
 function  g_Player_Get(UID: Word): TPlayer;
 function  g_Player_GetCount(): Byte;
 function  g_Player_GetStats(): TPlayerStatArray;
-function  g_Player_ValidName(Name: String): Boolean;
+function  g_Player_ExistingName(Name: String): Boolean;
 function  g_Player_CreateCorpse(Player: TPlayer): Integer;
 procedure g_Player_CreateGibs(fX, fY: Integer; ModelName: String; fColor: TRGB);
 procedure g_Player_CreateShell(fX, fY, dX, dY: Integer; T: Byte);
@@ -729,6 +733,8 @@ var
   MaxGibs: Word = 150;
   MaxCorpses: Word = 20;
   MaxShells: Word = 300;
+  ForceModel: Word = 0;
+  ForcedModelName: String = STD_PLAYER_MODEL;
   CurrentGib: Integer = 0;
   CurrentShell: Integer = 0;
   BotNames: Array of String;
@@ -796,6 +802,26 @@ begin
   Result := MaxCorpses;
 end;
 
+procedure g_Force_Model_Set(Mode: Word);
+begin
+  ForceModel := Mode;
+end;
+
+function g_Force_Model_Get(): Word;
+begin
+  Result := ForceModel;
+end;
+
+procedure g_Forced_Model_SetName(Model: String);
+begin
+  ForcedModelName := Model;
+end;
+
+function g_Forced_Model_GetName(): String;
+begin
+  Result := ForcedModelName;
+end;
+
 function g_Player_Create(ModelName: String; Color: TRGB; Team: Byte; Bot: Boolean): Word;
 var
   a: Integer;
@@ -831,6 +857,8 @@ begin
 
   gPlayers[a].FActualModelName := ModelName;
   gPlayers[a].SetModel(ModelName);
+  if Bot and (g_Force_Model_Get() <> 0) then
+    gPlayers[a].SetModel(g_Forced_Model_GetName());
 
 // Íåò ìîäåëè - ñîçäàíèå íå âîçìîæíî:
   if gPlayers[a].FModel = nil then
@@ -899,7 +927,11 @@ begin
 
   // create entity and load state
   if Bot then
-    gPlayers[a] := TBot.Create()
+  begin
+    gPlayers[a] := TBot.Create();
+    if (g_Force_Model_Get() <> 0) then
+      gPlayers[a].SetModel(g_Forced_Model_GetName());
+  end
   else
     gPlayers[a] := TPlayer.Create();
   gPlayers[a].FPhysics := True; // ???
@@ -992,7 +1024,7 @@ begin
   _name := '';
   if BotNames <> nil then
     for a := 0 to High(BotNames) do
-      if g_Player_ValidName(BotNames[a]) then
+      if g_Player_ExistingName(BotNames[a]) then
       begin
         _name := BotNames[a];
         Break;
@@ -1064,26 +1096,33 @@ begin
         Team := BotList[num].team; // CTF / TDM
 
 // Âûáèðàåì íàñòðîéêè áîòà èç ñïèñêà ïî íîìåðó èëè èìåíè:
-  lName := AnsiLowerCase(lName);
-  if (num < 0) or (num > Length(BotList)-1) then
-    num := -1;
-  if (num = -1) and (lName <> '') and (BotList <> nil) then
-    for a := 0 to High(BotList) do
-      if AnsiLowerCase(BotList[a].name) = lName then
-      begin
-        num := a;
-        Break;
-      end;
-  if num = -1 then
-    Exit;
+  if lName = '' then 
+    num := Random(Length(BotList))
+  else
+  begin
+    if (num < 0) or (num > Length(BotList)-1) then
+      num := -1;
+    if (num = -1) and (BotList <> nil) then
+      lName := AnsiLowerCase(lName);
+      for a := 0 to High(BotList) do
+        if AnsiLowerCase(BotList[a].name) = lName then
+        begin
+          num := a;
+          Break;
+        end;
+    if num = -1 then
+      Exit;
+  end;
 
 // Èìÿ áîòà:
   _name := BotList[num].name;
-// Çàíÿòî - âûáèðàåì ñëó÷àéíîå:
-  if not g_Player_ValidName(_name) then
-  repeat
-    _name := Format('DFBOT%.2d', [Random(100)]);
-  until g_Player_ValidName(_name);
+  if (_name = '') and (BotNames <> nil) then
+    for a := 0 to High(BotNames) do
+      if g_Player_ExistingName(BotNames[a]) then
+      begin
+        _name := BotNames[a];
+        Break;
+      end;
 
 // Ìîäåëü:
   _model := BotList[num].model;
@@ -1094,7 +1133,10 @@ begin
 // Ñîçäàåì áîòà:
   with g_Player_Get(g_Player_Create(_model, BotList[num].color, Team, True)) as TBot do
   begin
-    Name := _name;
+  // Åñëè èìåíè íåò, äåëàåì åãî èç UID áîòà
+    if _name = ''
+      then Name := Format('DFBOT%.5d', [UID])
+      else Name := _name;
 
     FDifficult.DiagFire := BotList[num].diag_fire;
     FDifficult.InvisFire := BotList[num].invis_fire;
@@ -1185,90 +1227,91 @@ var
   path: AnsiString;
 begin
   BotNames := nil;
+  BotList := nil;
 
   path := BOTNAMES_FILENAME;
-  if e_FindResource(DataDirs, path) = false then
-    Exit;
-
-// ×èòàåì âîçìîæíûå èìåíà áîòîâ èç ôàéëà:
-  AssignFile(F, path);
-  Reset(F);
-
-  while not EOF(F) do
+  if e_FindResource(DataDirs, path) then
   begin
-    ReadLn(F, s);
+    // ×èòàåì âîçìîæíûå èìåíà áîòîâ èç ôàéëà:
+    AssignFile(F, path);
+    Reset(F);
 
-    s := Trim(s);
-    if s = '' then
-      Continue;
+    while not EOF(F) do
+    begin
+      ReadLn(F, s);
 
-    SetLength(BotNames, Length(BotNames)+1);
-    BotNames[High(BotNames)] := s;
-  end;
+      s := Trim(s);
+      if s = '' then
+        Continue;
 
-  CloseFile(F);
+      SetLength(BotNames, Length(BotNames)+1);
+      BotNames[High(BotNames)] := s;
+    end;
 
-// Ïåðåìåøèâàåì èõ:
-  g_Bot_MixNames();
+    CloseFile(F);
 
-// ×èòàåì ôàéë ñ ïàðàìåòðàìè áîòîâ:
-  config := TConfig.CreateFile(path);
-  BotList := nil;
-  a := 0;
+    // Ïåðåìåøèâàåì èõ:
+    g_Bot_MixNames();
+  end;
 
-  while config.SectionExists(IntToStr(a)) do
+  path := BOTLIST_FILENAME;
+  if e_FindResource(DataDirs, path) then
   begin
-    SetLength(BotList, Length(BotList)+1);
+    // ×èòàåì ôàéë ñ ïàðàìåòðàìè áîòîâ:
+    config := TConfig.CreateFile(path);
+    a := 0;
 
-    with BotList[High(BotList)] do
+    while config.SectionExists(IntToStr(a)) do
     begin
-    // Èìÿ áîòà:
-      name := config.ReadStr(IntToStr(a), 'name', '');
-    // Ìîäåëü:
-      model := config.ReadStr(IntToStr(a), 'model', '');
-    // Êîìàíäà:
-      if config.ReadStr(IntToStr(a), 'team', 'red') = 'red' then
-        team := TEAM_RED
-      else
-        team := TEAM_BLUE;
-    // Öâåò ìîäåëè:
-      sa := parse(config.ReadStr(IntToStr(a), 'color', ''));
-      color.R := StrToIntDef(sa[0], 0);
-      color.G := StrToIntDef(sa[1], 0);
-      color.B := StrToIntDef(sa[2], 0);
-    // Âåðîÿòíîñòü ñòðåëüáû ïîä óãëîì:
-      diag_fire := config.ReadInt(IntToStr(a), 'diag_fire', 0);
-    // Âåðîÿòíîñòü îòâåòíîãî îãíÿ ïî íåâèäèìîìó ñîïåðíèêó:
-      invis_fire := config.ReadInt(IntToStr(a), 'invis_fire', 0);
-    // Òî÷íîñòü ñòðåëüáû ïîä óãëîì:
-      diag_precision := config.ReadInt(IntToStr(a), 'diag_precision', 0);
-    // Òî÷íîñòü ñòðåëüáû â ïîëåòå:
-      fly_precision := config.ReadInt(IntToStr(a), 'fly_precision', 0);
-    // Òî÷íîñòü óêëîíåíèÿ îò ñíàðÿäîâ:
-      cover := config.ReadInt(IntToStr(a), 'cover', 0);
-    // Âåðîÿòíîñòü ïðûæêà ïðè ïðèáëèæåíèè ñîïåðíèêà:
-      close_jump := config.ReadInt(IntToStr(a), 'close_jump', 0);
-    // Ïðèîðèòåòû îðóæèÿ äëÿ äàëüíåãî áîÿ:
-      sa := parse(config.ReadStr(IntToStr(a), 'w_prior1', ''));
-      if Length(sa) = 10 then
-        for b := 0 to 9 do
-          w_prior1[b] := EnsureRange(StrToInt(sa[b]), 0, 9);
-    // Ïðèîðèòåòû îðóæèÿ äëÿ áëèæíåãî áîÿ:
-      sa := parse(config.ReadStr(IntToStr(a), 'w_prior2', ''));
-      if Length(sa) = 10 then
-        for b := 0 to 9 do
-          w_prior2[b] := EnsureRange(StrToInt(sa[b]), 0, 9);
-
-      {sa := parse(config.ReadStr(IntToStr(a), 'w_prior3', ''));
-      if Length(sa) = 10 then
-        for b := 0 to 9 do
-          w_prior3[b] := EnsureRange(StrToInt(sa[b]), 0, 9);}
+      SetLength(BotList, Length(BotList)+1);
+
+      with BotList[High(BotList)] do
+      begin
+        name := config.ReadStr(IntToStr(a), 'name', '');  // Èìÿ áîòà
+        model := config.ReadStr(IntToStr(a), 'model', '');  // Ìîäåëü
+
+        // Êîìàíäà
+        if config.ReadStr(IntToStr(a), 'team', 'red') = 'red'
+          then team := TEAM_RED
+          else team := TEAM_BLUE;
+
+        // Öâåò ìîäåëè
+        sa := parse(config.ReadStr(IntToStr(a), 'color', ''));
+        color.R := StrToIntDef(sa[0], 0);
+        color.G := StrToIntDef(sa[1], 0);
+        color.B := StrToIntDef(sa[2], 0);
+
+        diag_fire := config.ReadInt(IntToStr(a), 'diag_fire', 0);  // Âåðîÿòíîñòü ñòðåëüáû ïîä óãëîì
+        invis_fire := config.ReadInt(IntToStr(a), 'invis_fire', 0);  // Âåðîÿòíîñòü îòâåòíîãî îãíÿ ïî íåâèäèìîìó ñîïåðíèêó
+        diag_precision := config.ReadInt(IntToStr(a), 'diag_precision', 0);  // Òî÷íîñòü ñòðåëüáû ïîä óãëîì
+        fly_precision := config.ReadInt(IntToStr(a), 'fly_precision', 0);  // Òî÷íîñòü ñòðåëüáû â ïîëåòå
+        cover := config.ReadInt(IntToStr(a), 'cover', 0);  // Òî÷íîñòü óêëîíåíèÿ îò ñíàðÿäîâ
+        close_jump := config.ReadInt(IntToStr(a), 'close_jump', 0);  // Âåðîÿòíîñòü ïðûæêà ïðè ïðèáëèæåíèè ñîïåðíèêà
+
+        // Ïðèîðèòåòû îðóæèÿ äëÿ äàëüíåãî áîÿ
+        sa := parse(config.ReadStr(IntToStr(a), 'w_prior1', ''));
+        if Length(sa) = 10 then
+          for b := 0 to 9 do
+            w_prior1[b] := EnsureRange(StrToInt(sa[b]), 0, 9);
+
+        // Ïðèîðèòåòû îðóæèÿ äëÿ áëèæíåãî áîÿ
+        sa := parse(config.ReadStr(IntToStr(a), 'w_prior2', ''));
+        if Length(sa) = 10 then
+          for b := 0 to 9 do
+            w_prior2[b] := EnsureRange(StrToInt(sa[b]), 0, 9);
+
+        {sa := parse(config.ReadStr(IntToStr(a), 'w_prior3', ''));
+        if Length(sa) = 10 then
+          for b := 0 to 9 do
+            w_prior3[b] := EnsureRange(StrToInt(sa[b]), 0, 9);}
+      end;
+
+      a += 1;
     end;
 
-    a := a + 1;
+    config.Free();
   end;
 
-  config.Free();
   SetLength(SavedStates, 0);
 end;
 
@@ -1488,8 +1531,8 @@ procedure g_Player_ResetAll(Force, Silent: Boolean);
 var
   i: Integer;
 begin
-  gTeamStat[TEAM_RED].Goals := 0;
-  gTeamStat[TEAM_BLUE].Goals := 0;
+  gTeamStat[TEAM_RED].Score := 0;
+  gTeamStat[TEAM_BLUE].Score := 0;
 
   if gPlayers <> nil then
     for i := 0 to High(gPlayers) do
@@ -2299,8 +2342,13 @@ begin
         end;
 
       if t = HIT_WATER then
+      begin
         g_GFX_Bubbles(FObj.X+PLAYER_RECT.X+(PLAYER_RECT.Width div 2),
                       FObj.Y+PLAYER_RECT.Y-4, value div 2, 8, 4);
+        if Random(2) = 0
+          then g_Sound_PlayExAt('SOUND_GAME_BUBBLE1', FObj.X, FObj.Y)
+          else g_Sound_PlayExAt('SOUND_GAME_BUBBLE2', FObj.X, FObj.Y);
+      end;
     end;
 
   // Áóôåð óðîíà:
@@ -2738,7 +2786,7 @@ begin
   SY := gPlayerScreenSize.Y;
   Y := 0;
 
-  if gShowGoals and (gGameSettings.GameMode in [GM_TDM, GM_CTF]) then
+  if gShowScore and (gGameSettings.GameMode in [GM_TDM, GM_CTF]) then
   begin
     if gGameSettings.GameMode = GM_CTF then
       a := 32 + 8
@@ -2755,7 +2803,7 @@ begin
         e_Draw(ID, X-16-32, 240-72-4, 0, True, False);
     end;
 
-    s := IntToStr(gTeamStat[TEAM_RED].Goals);
+    s := IntToStr(gTeamStat[TEAM_RED].Score);
     e_CharFont_GetSize(gMenuFont, s, tw, th);
     e_CharFont_PrintEx(gMenuFont, X-16-a-tw, 240-72-4, s, TEAMCOLOR[TEAM_RED]);
 
@@ -2770,7 +2818,7 @@ begin
         e_Draw(ID,  X-16-32, 240-32-4, 0, True, False);
     end;
 
-    s := IntToStr(gTeamStat[TEAM_BLUE].Goals);
+    s := IntToStr(gTeamStat[TEAM_BLUE].Score);
     e_CharFont_GetSize(gMenuFont, s, tw, th);
     e_CharFont_PrintEx(gMenuFont, X-16-a-tw, 240-32-4, s, TEAMCOLOR[TEAM_BLUE]);
   end;
@@ -3479,7 +3527,7 @@ begin
       if Srv then
       begin
         if gGameSettings.GameMode = GM_TDM then
-          Dec(gTeamStat[FTeam].Goals);
+          Dec(gTeamStat[FTeam].Score);
         if DoFrags or (gGameSettings.GameMode = GM_TDM) then
         begin
           Dec(FFrags);
@@ -3506,7 +3554,7 @@ begin
             end;
 
           if (gGameSettings.GameMode = GM_TDM) and DoFrags then
-            Inc(gTeamStat[KP.Team].Goals,
+            Inc(gTeamStat[KP.Team].Score,
               IfThen(SameTeam(FUID, SpawnerUID), -1, 1));
 
           if netsrv then MH_SEND_PlayerStats(SpawnerUID);
@@ -3667,7 +3715,7 @@ begin
         g_Game_Message(Format(_lc[I_MESSAGE_TLMS_WIN], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 144);
         if Netsrv then
           MH_SEND_GameEvent(NET_EV_TLMS_WIN, TEAM_RED);
-        Inc(gTeamStat[TEAM_RED].Goals);
+        Inc(gTeamStat[TEAM_RED].Score);
         gLMSRespawn := LMS_RESPAWN_FINAL;
         gLMSRespawnTime := gTime + 5000;
       end
@@ -3677,7 +3725,7 @@ begin
         g_Game_Message(Format(_lc[I_MESSAGE_TLMS_WIN], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 144);
         if Netsrv then
           MH_SEND_GameEvent(NET_EV_TLMS_WIN, TEAM_BLUE);
-        Inc(gTeamStat[TEAM_BLUE].Goals);
+        Inc(gTeamStat[TEAM_BLUE].Score);
         gLMSRespawn := LMS_RESPAWN_FINAL;
         gLMSRespawnTime := gTime + 5000;
       end
@@ -5373,10 +5421,9 @@ begin
       else if (FAir mod 31 = 0) and not blockmon then
       begin
         g_GFX_Bubbles(FObj.X+PLAYER_RECT.X+(PLAYER_RECT.Width div 2), FObj.Y+PLAYER_RECT.Y-4, 5+Random(6), 8, 4);
-        if Random(2) = 0 then
-          g_Sound_PlayExAt('SOUND_GAME_BUBBLE1', FObj.X, FObj.Y)
-        else
-          g_Sound_PlayExAt('SOUND_GAME_BUBBLE2', FObj.X, FObj.Y);
+        if Random(2) = 0
+          then g_Sound_PlayExAt('SOUND_GAME_BUBBLE1', FObj.X, FObj.Y)
+          else g_Sound_PlayExAt('SOUND_GAME_BUBBLE2', FObj.X, FObj.Y);
       end;
     end else if FAir < AIR_DEF then
       FAir := AIR_DEF;
@@ -5517,7 +5564,7 @@ begin
             (y >= 0) and (y <= PLAYER_RECT.Height);
 end;
 
-function g_Player_ValidName(Name: string): Boolean;
+function g_Player_ExistingName(Name: string): Boolean;
 var
   a: Integer;
 begin
@@ -5798,7 +5845,7 @@ begin
     if not sound_cap_flag[a].IsPlaying() then
       sound_cap_flag[a].Play();
 
-    gTeamStat[FTeam].Goals := gTeamStat[FTeam].Goals + 1;
+    gTeamStat[FTeam].Score += 1;
 
     Result := True;
     if g_Game_IsNet then
@@ -6477,10 +6524,9 @@ begin
   begin
     g_GFX_Bubbles(Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2)+Random(3)-1,
                   Obj.Y+Obj.Rect.Height+8, 1, 8, 4);
-    if Random(2) = 0 then
-      g_Sound_PlayExAt('SOUND_GAME_BUBBLE1', FObj.X, FObj.Y)
-    else
-      g_Sound_PlayExAt('SOUND_GAME_BUBBLE2', FObj.X, FObj.Y);
+    if Random(2) = 0
+      then g_Sound_PlayExAt('SOUND_GAME_BUBBLE1', FObj.X, FObj.Y)
+      else g_Sound_PlayExAt('SOUND_GAME_BUBBLE2', FObj.X, FObj.Y);
     Exit;
   end;