DEADSOFTWARE

fix playerstats netmessage; zero gTime before spawning players
[d2df-sdl.git] / src / game / g_player.pas
index dee10aa191af47131130ed12d2b102299d1a2d60..2f089d711a6bd6265a1a6284c36c4f12b04c7ce1 100644 (file)
@@ -267,7 +267,9 @@ 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
 
     // debug: viewport offset
     viewPortX, viewPortY, viewPortW, viewPortH: Integer;
@@ -554,7 +556,7 @@ var
   gTeamStat: TTeamStat;
   gFly: Boolean = False;
   gAimLine: Boolean = False;
-  gChatBubble: Byte = 0;
+  gChatBubble: Integer = 0;
   gPlayerIndicator: Integer = 1;
   gPlayerIndicatorStyle: Integer = 0;
   gNumBots: Word = 0;
@@ -612,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;
@@ -1253,14 +1255,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
@@ -1281,7 +1285,7 @@ begin
   g_Bot_MixNames();
 
 // ×èòàåì ôàéë ñ ïàðàìåòðàìè áîòîâ:
-  config := TConfig.CreateFile(DataDir + BOTLIST_FILENAME);
+  config := TConfig.CreateFile(path);
   BotList := nil;
   a := 0;
 
@@ -2178,6 +2182,8 @@ begin
   FJustTeleported := False;
   FNetTime := 0;
 
+  FWaitForFirstSpawn := false;
+
   resetWeaponQueue();
 end;
 
@@ -2224,6 +2230,7 @@ begin
     FMegaRulez[MR_SUIT] := 0;
     FMegaRulez[MR_INVUL] := 0;
     FMegaRulez[MR_INVIS] := 0;
+    FSpawnInvul := 0;
     FBerserk := 0;
   end;
 
@@ -2332,6 +2339,8 @@ procedure TPlayer.DrawIndicator(Color: TRGB);
 var
   indX, indY: Integer;
   indW, indH: Word;
+  indA: Single;
+  a: TDFPoint;
   nW, nH: Byte;
   ID: DWORD;
   c: TRGB;
@@ -2343,12 +2352,43 @@ begin
           if g_Texture_Get('TEXTURE_PLAYER_INDICATOR', ID) then
           begin
             e_GetTextureSize(ID, @indW, @indH);
-            indX := FObj.X + FObj.Rect.X + (FObj.Rect.Width - indW) div 2;
-            indY := FObj.Y - indH;
+            a.X := indW div 2;
+            a.Y := indH div 2;
+
+            if (FObj.X + FObj.Rect.X) < 0 then
+            begin
+              indA := 90;
+              indX := FObj.X + FObj.Rect.X + FObj.Rect.Width;
+              indY := FObj.Y + FObj.Rect.Y + (FObj.Rect.Height - indW) div 2;
+            end
+
+            else if (FObj.X + FObj.Rect.X + FObj.Rect.Width) > Max(gMapInfo.Width, gPlayerScreenSize.X) then
+            begin
+              indA := 270;
+              indX := FObj.X + FObj.Rect.X - indH;
+              indY := FObj.Y + FObj.Rect.Y + (FObj.Rect.Height - indW) div 2;
+            end
+
+            else if (fObj.Y - indH) < 0 then
+            begin
+              indA := 180;
+              indX := FObj.X + FObj.Rect.X + (FObj.Rect.Width - indW) div 2;
+              indY := FObj.Y + FObj.Rect.Y + FObj.Rect.Height;
+            end
+
+            else
+            begin
+              indA := 0;
+              indX := FObj.X + FObj.Rect.X + (FObj.Rect.Width - indW) div 2;
+              indY := FObj.Y - indH;
+            end;
+
+            indX := EnsureRange(indX, 0, Max(gMapInfo.Width, gPlayerScreenSize.X) - indW);
+            indY := EnsureRange(indY, 0, Max(gMapInfo.Height, gPlayerScreenSize.Y) - indH);
 
             c := e_Colors;
             e_Colors := Color;
-            e_Draw(ID, indX, indY, 0, True, False);
+            e_DrawAdv(ID, indX, indY, 0, True, False, indA, @a);
             e_Colors := c;
           end;
         end;
@@ -2469,7 +2509,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);
@@ -2837,7 +2877,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)
@@ -3501,7 +3541,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);
@@ -3688,8 +3729,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);
@@ -4241,6 +4282,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);
@@ -4326,6 +4368,7 @@ begin
   FMonsterKills := 0;
   FDeath := 0;
   FSecrets := 0;
+  FSpawnInvul := 0;
   FReady := False;
   if FNoRespawn then
   begin
@@ -4518,6 +4561,7 @@ begin
   FShellTimer := -1;
   FPain := 0;
   FLastHit := 0;
+  FSpawnInvul := 0;
 
   if not g_Game_IsServer then
     Exit;
@@ -4596,7 +4640,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 := [];
@@ -4632,6 +4677,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;
@@ -6253,6 +6305,7 @@ begin
       if FMegaRulez[MR_INVUL] < gTime+PLAYER_INVUL_TIME then
       begin
         FMegaRulez[MR_INVUL] := gTime+PLAYER_INVUL_TIME;
+        FSpawnInvul := 0;
       end;
 
     ITEM_INVIS: