DEADSOFTWARE

Game: Fix magic value check of gSpectMode
[d2df-sdl.git] / src / game / g_game.pas
index bc645b0a57fd12de70a6888d4e8c4c32ec9c52fd..2fd8408553a14a0c8efa24b8a4653d9972d44c34 100644 (file)
@@ -84,6 +84,7 @@ procedure g_Game_Free (freeTextures: Boolean=true);
 procedure g_Game_LoadData();
 procedure g_Game_FreeData();
 procedure g_Game_Update();
+procedure g_Game_PreUpdate();
 procedure g_Game_Draw();
 procedure g_Game_Quit();
 procedure g_Game_SetupScreenSize();
@@ -240,6 +241,7 @@ var
   gPlayer2: TPlayer = nil;
   gPlayerDrawn: TPlayer = nil;
   gTime: LongWord;
+  gLerpFactor: Single = 1.0;
   gSwitchGameMode: Byte = GM_DM;
   gHearPoint1, gHearPoint2: THearPoint;
   gSoundEffectsDF: Boolean = False;
@@ -265,6 +267,7 @@ var
   gShowFPS: Boolean = False;
   gShowGoals: Boolean = True;
   gShowStat: Boolean = True;
+  gShowPIDs: Boolean = False;
   gShowKillMsg: Boolean = True;
   gShowLives: Boolean = True;
   gShowPing: Boolean = False;
@@ -385,7 +388,7 @@ uses
   e_input, e_log, g_console, g_items, g_map, g_panel,
   g_playermodel, g_gfx, g_options, Math,
   g_triggers, g_monsters, e_sound, CONFIG,
-  g_language, g_net, g_main,
+  g_language, g_net, g_main, g_phys,
   ENet, e_msg, g_netmsg, g_netmaster,
   sfs, wadreader, g_system;
 
@@ -1160,6 +1163,7 @@ var
   stat: TPlayerStatArray;
   wad, map: string;
   mapstr: string;
+  namestr: string;
 begin
   s1 := '';
   s2 := '';
@@ -1301,8 +1305,12 @@ begin
               gg := g;
               bb := b;
             end;
+            if gShowPIDs then
+              namestr := Format('[%5d] %s', [UID, Name])
+            else
+              namestr := Name;
             // Èìÿ
-            e_TextureFontPrintEx(x+16, _y, Name, gStdFont, rr, gg, bb, 1);
+            e_TextureFontPrintEx(x+16, _y, namestr, gStdFont, rr, gg, bb, 1);
             // Ïèíã/ïîòåðè
             e_TextureFontPrintEx(x+w1+16, _y, Format(_lc[I_GAME_PING_MS], [Ping, Loss]), gStdFont, rr, gg, bb, 1);
             // Ôðàãè
@@ -1337,11 +1345,15 @@ begin
           r := 255;
           g := 127;
         end;
+        if gShowPIDs then
+          namestr := Format('[%5d] %s', [UID, Name])
+        else
+          namestr := Name;
         // Öâåò èãðîêà
         e_DrawFillQuad(x+16, _y+4, x+32-1, _y+16+4-1, Color.R, Color.G, Color.B, 0);
         e_DrawQuad(x+16, _y+4, x+32-1, _y+16+4-1, 192, 192, 192);
         // Èìÿ
-        e_TextureFontPrintEx(x+16+16+8, _y+4, Name, gStdFont, r, g, 0, 1);
+        e_TextureFontPrintEx(x+16+16+8, _y+4, namestr, gStdFont, r, g, 0, 1);
         // Ïèíã/ïîòåðè
         e_TextureFontPrintEx(x+w1+16, _y+4, Format(_lc[I_GAME_PING_MS], [Ping, Loss]), gStdFont, r, g, 0, 1);
         // Ôðàãè
@@ -1715,6 +1727,17 @@ begin
   MC_SEND_CheatRequest(NET_CHEAT_READY);
 end;
 
+procedure g_Game_PreUpdate();
+begin
+  // these are in separate PreUpdate functions because they can interact during Update()
+  // and are synced over the net
+  // we don't care that much about corpses and gibs
+  g_Player_PreUpdate();
+  g_Monsters_PreUpdate();
+  g_Items_PreUpdate();
+  g_Weapon_PreUpdate();
+end;
+
 procedure g_Game_Update();
 var
   Msg: g_gui.TMessage;
@@ -3621,7 +3644,8 @@ end;
 
 procedure DrawPlayer(p: TPlayer);
 var
-  px, py, a, b, c, d, i: Integer;
+  px, py, a, b, c, d, i, fX, fY: Integer;
+  camObj: TObj;
   //R: TRect;
 begin
   if (p = nil) or (p.FDummy) then
@@ -3639,8 +3663,10 @@ begin
 
   glPushMatrix();
 
-  px := p.GameX + PLAYER_RECT_CX;
-  py := p.GameY + PLAYER_RECT_CY+p.Obj.slopeUpLeft;
+  camObj := p.getCameraObj();
+  camObj.lerp(gLerpFactor, fX, fY);
+  px := fX + PLAYER_RECT_CX;
+  py := fY + PLAYER_RECT_CY+nlerp(p.SlopeOld, camObj.slopeUpLeft, gLerpFactor);
 
   if (g_dbg_scale = 1.0) and (not g_dbg_ignore_bounds) then
   begin
@@ -3697,7 +3723,7 @@ begin
       p.IncCam := nclamp(p.IncCam, min(0, -120 - i), 0);
   end;
 
-  sY := sY - p.IncCam;
+  sY := sY - nlerp(p.IncCamOld, p.IncCam, gLerpFactor);
 
   if (not g_dbg_ignore_bounds) then
   begin
@@ -3829,6 +3855,9 @@ begin
     FPSTime := Time;
   end;
 
+  e_SetRendertarget(True);
+  e_SetViewPort(0, 0, gScreenWidth, gScreenHeight);
+
   if gGameOn or (gState = STATE_FOLD) then
   begin
     if (gPlayer1 <> nil) and (gPlayer2 <> nil) then
@@ -3969,7 +3998,8 @@ begin
                   Round(gScreenHeight / 2.75)-(h div 2), MessageText);
     end;
 
-    if IsDrawStat or (gSpectMode = 1) then DrawStat();
+    if IsDrawStat or (gSpectMode = SPECT_STATS) then
+      DrawStat();
 
     if gSpectHUD and (not gChatShow) and (gSpectMode <> SPECT_NONE) and (not gSpectAuto) then
     begin
@@ -4159,10 +4189,20 @@ begin
 
   if gGameOn then drawProfilers();
 
+  // TODO: draw this after the FBO and remap mouse click coordinates
+
 {$IFDEF ENABLE_HOLMES}
   g_Holmes_DrawUI();
 {$ENDIF}
 
+  // blit framebuffer to screen
+
+  e_SetRendertarget(False);
+  e_SetViewPort(0, 0, gWinSizeX, gWinSizeY);
+  e_BlitFramebuffer(gWinSizeX, gWinSizeY);
+
+  // draw the overlay stuff on top of it
+
   g_Touch_Draw;
 end;
 
@@ -4194,6 +4234,7 @@ begin
   e_WriteLog(Format(_lc[I_FATAL_ERROR], [Text]), TMsgType.Warning);
 
   gExit := EXIT_SIMPLE;
+  if gGameOn then EndGame;
 end;
 
 procedure g_SimpleError(Text: String);
@@ -4251,6 +4292,10 @@ begin
   if ((not gGameOn) and (gState <> STATE_INTERCUSTOM))
   or (not (gGameSettings.GameType in [GT_CUSTOM, GT_SERVER, GT_CLIENT])) then
     Exit;
+
+  if (gGameSettings.MaxLives > 0) and (gLMSRespawn = LMS_RESPAWN_NONE) then
+    Exit;
+
   if gPlayer1 = nil then
   begin
     if g_Game_IsClient then
@@ -5214,12 +5259,14 @@ begin
         else if gPlayers[i].Team = TEAM_BLUE then Inc(nb)
       end;
 
-  if (n < 2) or ((gGameSettings.GameMode = GM_TDM) and ((nr = 0) or (nb = 0))) then
+  if (n < 1) or ((gGameSettings.GameMode = GM_TDM) and ((nr = 0) or (nb = 0))) then
   begin
     // wait a second until the fuckers finally decide to join
     gLMSRespawn := LMS_RESPAWN_WARMUP;
     gLMSRespawnTime := gTime + gGameSettings.WarmupTime*1000;
     gLMSSoftSpawn := NoMapRestart;
+    if g_Game_IsNet then
+      MH_SEND_GameEvent(NET_EV_LMS_WARMUP, gLMSRespawnTime - gTime);
     Exit;
   end;
 
@@ -5509,6 +5556,12 @@ begin
       if g_Game_IsServer then
       begin
         gGameSettings.WarmupTime := gsWarmupTime;
+        // extend warmup if it's already going
+        if gLMSRespawn = LMS_RESPAWN_WARMUP then
+        begin
+          gLMSRespawnTime := gTime + gsWarmupTime * 1000;
+          if g_Game_IsNet then MH_SEND_GameEvent(NET_EV_LMS_WARMUP, gLMSRespawnTime - gTime);
+        end;
         if g_Game_IsNet then MH_SEND_GameSettings;
       end;
     end;
@@ -6243,6 +6296,34 @@ begin
     end else
       g_Console_Add(_lc[I_MSG_SERVERONLY]);
   end
+  else if cmd = 'kick_pid' then
+  begin
+    if g_Game_IsServer and g_Game_IsNet then
+    begin
+      if Length(P) < 2 then
+      begin
+        g_Console_Add('kick_pid <player ID>');
+        Exit;
+      end;
+      if P[1] = '' then
+      begin
+        g_Console_Add('kick_pid <player ID>');
+        Exit;
+      end;
+
+      a := StrToIntDef(P[1], 0);
+      pl := g_Net_Client_ByPlayer(a);
+      if (pl <> nil) and pl^.Used and (pl^.Peer <> nil) then
+      begin
+        s := g_Net_ClientName_ByID(pl^.ID);
+        enet_peer_disconnect(pl^.Peer, NET_DISC_KICK);
+        g_Console_Add(Format(_lc[I_PLAYER_KICK], [s]));
+        MH_SEND_GameEvent(NET_EV_PLAYER_KICK, 0, s);
+        g_Net_Slist_ServerPlayerLeaves();
+      end;
+    end else
+      g_Console_Add(_lc[I_MSG_SERVERONLY]);
+  end
   else if cmd = 'ban' then
   begin
     if g_Game_IsServer and g_Game_IsNet then
@@ -6301,6 +6382,35 @@ begin
     end else
       g_Console_Add(_lc[I_MSG_SERVERONLY]);
   end
+  else if cmd = 'ban_pid' then
+  begin
+    if g_Game_IsServer and g_Game_IsNet then
+    begin
+      if Length(P) < 2 then
+      begin
+        g_Console_Add('ban_pid <player ID>');
+        Exit;
+      end;
+      if P[1] = '' then
+      begin
+        g_Console_Add('ban_pid <player ID>');
+        Exit;
+      end;
+
+      a := StrToIntDef(P[1], 0);
+      pl := g_Net_Client_ByPlayer(a);
+      if (pl <> nil) and pl^.Used and (pl^.Peer <> nil) then
+      begin
+        s := g_Net_ClientName_ByID(pl^.ID);
+        g_Net_BanHost(pl^.Peer^.address.host, False);
+        enet_peer_disconnect(pl^.Peer, NET_DISC_TEMPBAN);
+        g_Console_Add(Format(_lc[I_PLAYER_BAN], [s]));
+        MH_SEND_GameEvent(NET_EV_PLAYER_BAN, 0, s);
+        g_Net_Slist_ServerPlayerLeaves();
+      end;
+    end else
+      g_Console_Add(_lc[I_MSG_SERVERONLY]);
+  end
   else if cmd = 'permban' then
   begin
     if g_Game_IsServer and g_Game_IsNet then
@@ -6361,6 +6471,57 @@ begin
     end else
       g_Console_Add(_lc[I_MSG_SERVERONLY]);
   end
+  else if cmd = 'permban_pid' then
+  begin
+    if g_Game_IsServer and g_Game_IsNet then
+    begin
+      if Length(P) < 2 then
+      begin
+        g_Console_Add('permban_pid <player ID>');
+        Exit;
+      end;
+      if P[1] = '' then
+      begin
+        g_Console_Add('permban_pid <player ID>');
+        Exit;
+      end;
+
+      a := StrToIntDef(P[1], 0);
+      pl := g_Net_Client_ByPlayer(a);
+      if (pl <> nil) and pl^.Used and (pl^.Peer <> nil) then
+      begin
+        s := g_Net_ClientName_ByID(pl^.ID);
+        g_Net_BanHost(pl^.Peer^.address.host);
+        enet_peer_disconnect(pl^.Peer, NET_DISC_BAN);
+        g_Net_SaveBanList();
+        g_Console_Add(Format(_lc[I_PLAYER_BAN], [s]));
+        MH_SEND_GameEvent(NET_EV_PLAYER_BAN, 0, s);
+        g_Net_Slist_ServerPlayerLeaves();
+      end;
+    end else
+      g_Console_Add(_lc[I_MSG_SERVERONLY]);
+  end
+  else if cmd = 'permban_ip' then
+  begin
+    if g_Game_IsServer and g_Game_IsNet then
+    begin
+      if Length(P) < 2 then
+      begin
+        g_Console_Add('permban_ip <IP address>');
+        Exit;
+      end;
+      if P[1] = '' then
+      begin
+        g_Console_Add('permban_ip <IP address>');
+        Exit;
+      end;
+
+      g_Net_BanHost(P[1]);
+      g_Net_SaveBanList();
+      g_Console_Add(Format(_lc[I_PLAYER_BAN], [P[1]]));
+    end else
+      g_Console_Add(_lc[I_MSG_SERVERONLY]);
+  end
   else if cmd = 'unban' then
   begin
     if g_Game_IsServer and g_Game_IsNet then
@@ -6569,6 +6730,7 @@ begin
         g_Game_Free();
         with gGameSettings do
         begin
+          Options := gsGameFlags;
           GameMode := g_Game_TextToMode(gsGameMode);
           if gSwitchGameMode <> GM_NONE then
             GameMode := gSwitchGameMode;
@@ -6623,6 +6785,7 @@ begin
         g_Game_Free();
         with gGameSettings do
         begin
+          Options := gsGameFlags;
           GameMode := g_Game_TextToMode(gsGameMode);
           if gSwitchGameMode <> GM_NONE then GameMode := gSwitchGameMode;
           if GameMode = GM_NONE then GameMode := GM_DM;
@@ -7213,7 +7376,6 @@ begin
       end;
     'r_reset':
       begin
-        sys_EnableVSync(gVSync);
         gRC_Width := Max(1, gRC_Width);
         gRC_Height := Max(1, gRC_Height);
         gBPP := Max(1, gBPP);
@@ -7221,6 +7383,19 @@ begin
           e_LogWriteln('resolution changed')
         else
           e_LogWriteln('resolution not changed');
+        sys_EnableVSync(gVSync);
+      end;
+    'r_maxfps':
+      begin
+        if Length(p) = 2 then
+        begin
+          gMaxFPS := StrToIntDef(p[1], gMaxFPS);
+          if gMaxFPS > 0 then
+            gFrameTime := 1000 div gMaxFPS
+          else
+            gFrameTime := 0;
+        end;
+        e_LogWritefln('r_maxfps %d', [gMaxFPS]);
       end;
     'g_language':
       begin
@@ -7609,8 +7784,7 @@ begin
   case gAnnouncer of
     ANNOUNCE_NONE:
       Exit;
-    ANNOUNCE_ME,
-    ANNOUNCE_MEPLUS:
+    ANNOUNCE_ME:
       if not g_Game_IsWatchedPlayer(SpawnerUID) then
         Exit;
   end;
@@ -7945,8 +8119,7 @@ begin
   // Options:
     s := Find_Param_Value(pars, '-opt');
     if (s = '') then
-      Opt := GAME_OPTION_ALLOWEXIT or GAME_OPTION_BOTVSPLAYER or
-        GAME_OPTION_BOTVSMONSTER or GAME_OPTION_DMKEYS
+      Opt := gsGameFlags
     else
       Opt := StrToIntDef(s, 0);
 
@@ -8077,4 +8250,5 @@ begin
   conRegVar('r_showlives', @gShowLives, 'show lives', 'show lives');
   conRegVar('r_showspect', @gSpectHUD, 'show spectator hud', 'show spectator hud');
   conRegVar('r_showstat', @gShowStat, 'show stats', 'show stats');
+  conRegVar('r_showpids', @gShowPIDs, 'show PIDs', 'show PIDs');
 end.