DEADSOFTWARE

generalize warmup stuff
[d2df-sdl.git] / src / game / g_player.pas
index cc6afb07be47661fa320584d0d6ecb2f80f5df1e..30a71f18306d98e7b0b79486399b0323284ee28d 100644 (file)
@@ -267,6 +267,7 @@ type
     FReady:     Boolean;
     FDummy:     Boolean;
     FFireTime:  Integer;
+    FSpawnInvul: Integer;
     FHandicap:  Integer;
     FWaitForFirstSpawn: Boolean; // set to `true` in server, used to spawn a player on first full state request
 
@@ -555,12 +556,12 @@ var
   gTeamStat: TTeamStat;
   gFly: Boolean = False;
   gAimLine: Boolean = False;
-  gChatBubble: Byte = 0;
+  gChatBubble: Integer = 0;
   gPlayerIndicator: Integer = 1;
   gPlayerIndicatorStyle: Integer = 0;
   gNumBots: Word = 0;
-  gLMSPID1: Word = 0;
-  gLMSPID2: Word = 0;
+  gSpectLatchPID1: Word = 0;
+  gSpectLatchPID2: Word = 0;
   MAX_RUNVEL: Integer = 8;
   VEL_JUMP: Integer = 10;
   SHELL_TIMEOUT: Cardinal = 60000;
@@ -613,7 +614,7 @@ uses
   g_holmes,
 {$ENDIF}
   e_log, g_map, g_items, g_console, g_gfx, Math,
-  g_options, g_triggers, g_menu, g_game, g_grid,
+  g_options, g_triggers, g_menu, g_game, g_grid, e_res,
   wadreader, g_main, g_monsters, CONFIG, g_language,
   g_net, g_netmsg, g_window,
   utils, xstreams;
@@ -1071,12 +1072,6 @@ begin
         Break;
       end;
 
-// Èìåíè íåò, çàäàåì ñëó÷àéíîå:
-  if _name = '' then
-    repeat
-      _name := Format('DFBOT%.2d', [Random(100)]);
-    until g_Player_ValidName(_name);
-
 // Âûáèðàåì ñëó÷àéíóþ ìîäåëü:
   _model := m[Random(Length(m))];
 
@@ -1087,7 +1082,11 @@ begin
                                          Min(Random(9)*32, 255)),
                                     Team, True)) as TBot do
   begin
-    Name := _name;
+  // Åñëè èìåíè íåò, äåëàåì åãî èç UID áîòà
+    if _name = '' then
+      Name := Format('DFBOT%.5d', [UID])
+    else
+      Name := _name;
 
     case Difficult of
       1: FDifficult := DIFFICULT_EASY;
@@ -1254,14 +1253,16 @@ var
   a, b: Integer;
   config: TConfig;
   sa: SSArray;
+  path: AnsiString;
 begin
   BotNames := nil;
 
-  if not FileExists(DataDir + BOTNAMES_FILENAME) then
+  path := BOTNAMES_FILENAME;
+  if e_FindResource(DataDirs, path) = false then
     Exit;
 
 // ×èòàåì âîçìîæíûå èìåíà áîòîâ èç ôàéëà:
-  AssignFile(F, DataDir + BOTNAMES_FILENAME);
+  AssignFile(F, path);
   Reset(F);
 
   while not EOF(F) do
@@ -1282,7 +1283,7 @@ begin
   g_Bot_MixNames();
 
 // ×èòàåì ôàéë ñ ïàðàìåòðàìè áîòîâ:
-  config := TConfig.CreateFile(DataDir + BOTLIST_FILENAME);
+  config := TConfig.CreateFile(path);
   BotList := nil;
   a := 0;
 
@@ -2227,6 +2228,7 @@ begin
     FMegaRulez[MR_SUIT] := 0;
     FMegaRulez[MR_INVUL] := 0;
     FMegaRulez[MR_INVIS] := 0;
+    FSpawnInvul := 0;
     FBerserk := 0;
   end;
 
@@ -2505,7 +2507,7 @@ begin
       end;
     end;
 
-    if (FMegaRulez[MR_INVUL] > gTime) and (gPlayerDrawn <> Self) then
+    if (FMegaRulez[MR_INVUL] > gTime) and ((gPlayerDrawn <> Self) or (FSpawnInvul >= gTime)) then
       if g_Texture_Get('TEXTURE_PLAYER_INVULPENTA', ID) then
       begin
         e_GetTextureSize(ID, @w, @h);
@@ -2764,7 +2766,14 @@ begin
       e_CharFont_PrintEx(gMenuSmallFont, X-16-tw, Y+32, s, _RGB(255, 0, 0));
     end;
 
-    if gShowLives and (gGameSettings.MaxLives > 0) then
+    if gLMSRespawn > LMS_RESPAWN_NONE then
+    begin
+      s := _lc[I_GAME_WARMUP];
+      e_CharFont_GetSize(gMenuFont, s, tw, th);
+      s := s + ': ' + IntToStr((gLMSRespawnTime - gTime) div 1000);
+      e_CharFont_PrintEx(gMenuFont, X-64-tw, SY-32, s, _RGB(0, 255, 0));
+    end
+    else if gShowLives and (gGameSettings.MaxLives > 0) then
     begin
       s := IntToStr(Lives);
       e_CharFont_GetSize(gMenuFont, s, tw, th);
@@ -2873,7 +2882,7 @@ var
   dr: Boolean;
 begin
   // Ïðè âçÿòèè íåóÿçâèìîñòè ðèñóåòñÿ èíâåðñèîííûé áåëûé ôîí
-  if FMegaRulez[MR_INVUL] >= gTime then
+  if (FMegaRulez[MR_INVUL] >= gTime) and (FSpawnInvul < gTime) then
   begin
     if (FMegaRulez[MR_INVUL]-gTime) <= 2100 then
       dr := not Odd((FMegaRulez[MR_INVUL]-gTime) div 300)
@@ -3537,7 +3546,8 @@ begin
       PushItem(ITEM_JETPACK);
 
 // Âûáðîñ êëþ÷åé:
-    if not (gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF]) then
+    if (not (gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF])) or
+       (not LongBool(gGameSettings.Options and GAME_OPTION_DMKEYS)) then
     begin
       if R_KEY_RED in FRulez then
         PushItem(ITEM_KEY_RED);
@@ -3657,7 +3667,7 @@ begin
     if srv and (OldLR = LMS_RESPAWN_NONE) and (gLMSRespawn > LMS_RESPAWN_NONE) then
     begin
       if NetMode = NET_SERVER then
-        MH_SEND_GameEvent(NET_EV_LMS_WARMUP, (gLMSRespawnTime - gTime) div 1000)
+        MH_SEND_GameEvent(NET_EV_LMS_WARMUP, gLMSRespawnTime - gTime)
       else
         g_Console_Add(Format(_lc[I_MSG_WARMUP_START], [(gLMSRespawnTime - gTime) div 1000]), True);
     end;
@@ -3724,8 +3734,8 @@ begin
   result := false;
   case weapon of
     WEAPON_KASTET, WEAPON_SAW: result := true;
-    WEAPON_SHOTGUN1, WEAPON_SHOTGUN2: result := (FAmmo[A_SHELLS] > 0);
-    WEAPON_PISTOL, WEAPON_CHAINGUN, WEAPON_SUPERPULEMET: result := (FAmmo[A_BULLETS] > 0);
+    WEAPON_SHOTGUN1, WEAPON_SHOTGUN2, WEAPON_SUPERPULEMET: result := (FAmmo[A_SHELLS] > 0);
+    WEAPON_PISTOL, WEAPON_CHAINGUN: result := (FAmmo[A_BULLETS] > 0);
     WEAPON_ROCKETLAUNCHER: result := (FAmmo[A_ROCKETS] > 0);
     WEAPON_PLASMA, WEAPON_BFG: result := (FAmmo[A_CELLS] > 0);
     WEAPON_FLAMETHROWER: result := (FAmmo[A_FUEL] > 0);
@@ -4277,6 +4287,7 @@ begin
       if FMegaRulez[MR_INVUL] < gTime+PLAYER_INVUL_TIME then
       begin
         FMegaRulez[MR_INVUL] := gTime+PLAYER_INVUL_TIME;
+        FSpawnInvul := 0;
         Result := True;
         remove := True;
         if gFlash = 2 then Inc(FPickup, 5);
@@ -4362,6 +4373,7 @@ begin
   FMonsterKills := 0;
   FDeath := 0;
   FSecrets := 0;
+  FSpawnInvul := 0;
   FReady := False;
   if FNoRespawn then
   begin
@@ -4554,6 +4566,7 @@ begin
   FShellTimer := -1;
   FPain := 0;
   FLastHit := 0;
+  FSpawnInvul := 0;
 
   if not g_Game_IsServer then
     Exit;
@@ -4632,7 +4645,8 @@ begin
     FMaxAmmo[A_CELLS] := AmmoLimits[0, A_CELLS];
     FMaxAmmo[A_FUEL] := AmmoLimits[0, A_FUEL];
 
-    if gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF] then
+    if (gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF]) and
+       LongBool(gGameSettings.Options and GAME_OPTION_DMKEYS) then
       FRulez := [R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE]
     else
       FRulez := [];
@@ -4668,6 +4682,13 @@ begin
   for a := Low(FMegaRulez) to High(FMegaRulez) do
     FMegaRulez[a] := 0;
 
+// Respawn invulnerability
+  if (gGameSettings.GameType <> GT_SINGLE) and (gGameSettings.SpawnInvul > 0) then
+  begin
+    FMegaRulez[MR_INVUL] := gTime + gGameSettings.SpawnInvul * 1000;
+    FSpawnInvul := FMegaRulez[MR_INVUL];
+  end;
+
   FDamageBuffer := 0;
   FJetpack := False;
   FCanJetpack := False;
@@ -4692,9 +4713,9 @@ begin
   FSpectatePlayer := -1;
   FSpawned := True;
 
-  if (gPlayer1 = nil) and (gLMSPID1 = FUID) then
+  if (gPlayer1 = nil) and (gSpectLatchPID1 = FUID) then
     gPlayer1 := self;
-  if (gPlayer2 = nil) and (gLMSPID2 = FUID) then
+  if (gPlayer2 = nil) and (gSpectLatchPID2 = FUID) then
     gPlayer2 := self;
 
   if g_Game_IsNet then
@@ -4731,12 +4752,12 @@ begin
   begin
     if Self = gPlayer1 then
     begin
-      gLMSPID1 := FUID;
+      gSpectLatchPID1 := FUID;
       gPlayer1 := nil;
-    end;
-    if Self = gPlayer2 then
+    end
+    else if Self = gPlayer2 then
     begin
-      gLMSPID2 := FUID;
+      gSpectLatchPID2 := FUID;
       gPlayer2 := nil;
     end;
   end;
@@ -6289,6 +6310,7 @@ begin
       if FMegaRulez[MR_INVUL] < gTime+PLAYER_INVUL_TIME then
       begin
         FMegaRulez[MR_INVUL] := gTime+PLAYER_INVUL_TIME;
+        FSpawnInvul := 0;
       end;
 
     ITEM_INVIS: