DEADSOFTWARE

Player: Always display punch animation
[d2df-sdl.git] / src / game / g_game.pas
index 2a72d3cbff95cf869e534fc704403ef0c18cf8a1..c38572befa771c29a3d575d8ddcf940aaf6dadf6 100644 (file)
@@ -137,7 +137,7 @@ procedure GameCheats(P: SSArray);
 procedure DebugCommands(P: SSArray);
 procedure g_Game_Process_Params;
 procedure g_Game_SetLoadingText(Text: String; Max: Integer; reWrite: Boolean);
-procedure g_Game_StepLoading();
+procedure g_Game_StepLoading(Value: Integer = -1);
 procedure g_Game_ClearLoading();
 procedure g_Game_SetDebugMode();
 procedure DrawLoadingStat();
@@ -263,6 +263,10 @@ var
   gSpectViewTwo: Boolean = False;
   gSpectPID1: Integer = -1;
   gSpectPID2: Integer = -1;
+  gSpectAuto: Boolean = False;
+  gSpectAutoNext: LongWord;
+  gSpectAutoStepX: Integer;
+  gSpectAutoStepY: Integer;
   gMusic: TMusic = nil;
   gLoadGameMode: Boolean;
   gCheats: Boolean = False;
@@ -354,10 +358,9 @@ function gPause (): Boolean; inline;
 implementation
 
 uses
-{$IFDEF USE_NANOGL}
-  nanoGL,
-{$ELSE}
-  GL, GLExt,
+{$INCLUDE ../nogl/noGLuses.inc}
+{$IFDEF ENABLE_HOLMES}
+  g_holmes,
 {$ENDIF}
   e_texture, g_textures, g_main, g_window, g_menu,
   e_input, e_log, g_console, g_items, g_map, g_panel,
@@ -365,7 +368,7 @@ uses
   g_triggers, g_monsters, e_sound, CONFIG,
   g_language, g_net,
   ENet, e_msg, g_netmsg, g_netmaster,
-  sfs, wadreader, g_holmes;
+  sfs, wadreader;
 
 
 var
@@ -932,6 +935,7 @@ begin
               end
               else
                 slWaitStr := _lc[I_NET_SLIST_ERROR];
+              g_Serverlist_GenerateTable(slCurrent, slTable);
             end;
 
             g_Game_ExecuteEvent('ongameend');
@@ -1015,6 +1019,7 @@ begin
             gMusic.SetByName('MUSIC_INTERMUS');
             gMusic.Play();
             gState := STATE_INTERSINGLE;
+            e_UnpressAllKeys();
 
             g_Game_ExecuteEvent('oninter');
           end
@@ -1435,6 +1440,59 @@ begin
     Result := ids[(Length(ids) - 1 + idx) mod Length(ids)];
 end;
 
+function GetActivePlayerID_Random(Skip: Integer = -1): Integer;
+var
+  a, idx: Integer;
+  ids: Array of Word;
+begin
+  Result := -1;
+  if gPlayers = nil then
+    Exit;
+  SetLength(ids, 0);
+  idx := -1;
+  for a := Low(gPlayers) to High(gPlayers) do
+    if IsActivePlayer(gPlayers[a]) then
+    begin
+      SetLength(ids, Length(ids) + 1);
+      ids[High(ids)] := gPlayers[a].UID;
+      if gPlayers[a].UID = Skip then
+        idx := High(ids);
+    end;
+  if Length(ids) = 0 then
+    Exit;
+  if Length(ids) = 1 then
+  begin
+    Result := ids[0];
+    Exit;
+  end;
+  Result := ids[Random(Length(ids))];
+  a := 10;
+  while (idx <> -1) and (Result = Skip) and (a > 0) do
+  begin
+    Result := ids[Random(Length(ids))];
+    Dec(a);
+  end;
+end;
+
+function GetRandomSpectMode(Current: Byte): Byte;
+label
+  retry;
+begin
+  Result := Current;
+retry:
+  case Random(7) of
+    0: Result := SPECT_STATS;
+    1: Result := SPECT_MAPVIEW;
+    2: Result := SPECT_MAPVIEW;
+    3: Result := SPECT_PLAYERS;
+    4: Result := SPECT_PLAYERS;
+    5: Result := SPECT_PLAYERS;
+    6: Result := SPECT_PLAYERS;
+  end;
+  if (Current in [SPECT_STATS, SPECT_MAPVIEW]) and (Current = Result) then
+    goto retry;
+end;
+
 function isKeyPressed (key1: Word; key2: Word): Boolean;
 begin
   if (key1 <> 0) and e_KeyPressed(key1) then begin result := true; exit; end;
@@ -1665,12 +1723,14 @@ begin
 
                 gMusic.Play();
                 gState := STATE_INTERCUSTOM;
+                e_UnpressAllKeys();
               end
             else // Çàêîí÷èëàñü ïîñëåäíÿÿ êàðòà â Îäèíî÷íîé èãðå
               begin
                 gMusic.SetByName('MUSIC_INTERMUS');
                 gMusic.Play();
                 gState := STATE_INTERSINGLE;
+                e_UnpressAllKeys();
               end;
             g_Game_ExecuteEvent('oninter');
           end
@@ -1688,7 +1748,7 @@ begin
       end;
 
     STATE_SLIST:
-        g_Serverlist_Control(slCurrent);
+        g_Serverlist_Control(slCurrent, slTable);
   end;
 
   if g_Game_IsNet then
@@ -1806,7 +1866,8 @@ begin
     begin
       if not gSpectKeyPress then
       begin
-        if isKeyPressed(gGameControls.P1Control.KeyJump, gGameControls.P1Control.KeyJump2) then
+        if isKeyPressed(gGameControls.P1Control.KeyJump, gGameControls.P1Control.KeyJump2)
+           and (not gSpectAuto) then
         begin
           // switch spect mode
           case gSpectMode of
@@ -1817,7 +1878,8 @@ begin
           end;
           gSpectKeyPress := True;
         end;
-        if gSpectMode = SPECT_MAPVIEW then
+        if (gSpectMode = SPECT_MAPVIEW)
+           and (not gSpectAuto) then
         begin
           if isKeyPressed(gGameControls.P1Control.KeyLeft, gGameControls.P1Control.KeyLeft2) then
             gSpectX := Max(gSpectX - gSpectStep, 0);
@@ -1840,7 +1902,8 @@ begin
             gSpectKeyPress := True;
           end;
         end;
-        if gSpectMode = SPECT_PLAYERS then
+        if (gSpectMode = SPECT_PLAYERS)
+           and (not gSpectAuto) then
         begin
           if isKeyPressed(gGameControls.P1Control.KeyUp, gGameControls.P1Control.KeyUp2) then
           begin
@@ -1879,9 +1942,27 @@ begin
             gSpectKeyPress := True;
           end;
         end;
+        if isKeyPressed(gGameControls.P1Control.KeyFire, gGameControls.P1Control.KeyFire2) then
+        begin
+          if (gSpectMode = SPECT_STATS) and (not gSpectAuto) then
+          begin
+            gSpectAuto := True;
+            gSpectAutoNext := 0;
+            gSpectViewTwo := False;
+            gSpectKeyPress := True;
+          end
+          else
+            if gSpectAuto then
+            begin
+              gSpectMode := SPECT_STATS;
+              gSpectAuto := False;
+              gSpectKeyPress := True;
+            end;
+        end;
       end
       else
         if (not isKeyPressed(gGameControls.P1Control.KeyJump, gGameControls.P1Control.KeyJump2)) and
+           (not isKeyPressed(gGameControls.P1Control.KeyFire, gGameControls.P1Control.KeyFire2)) and
            (not isKeyPressed(gGameControls.P1Control.KeyLeft, gGameControls.P1Control.KeyLeft2)) and
            (not isKeyPressed(gGameControls.P1Control.KeyRight, gGameControls.P1Control.KeyRight2)) and
            (not isKeyPressed(gGameControls.P1Control.KeyUp, gGameControls.P1Control.KeyUp2)) and
@@ -1889,6 +1970,54 @@ begin
            (not isKeyPressed(gGameControls.P1Control.KeyPrevWeapon, gGameControls.P1Control.KeyPrevWeapon2)) and
            (not isKeyPressed(gGameControls.P1Control.KeyNextWeapon, gGameControls.P1Control.KeyNextWeapon2)) then
           gSpectKeyPress := False;
+
+      if gSpectAuto then
+      begin
+        if gSpectMode = SPECT_MAPVIEW then
+        begin
+          i := Min(Max(gSpectX + gSpectAutoStepX, 0), gMapInfo.Width - gScreenWidth);
+          if i = gSpectX then
+            gSpectAutoNext := gTime
+          else
+            gSpectX := i;
+          i := Min(Max(gSpectY + gSpectAutoStepY, 0), gMapInfo.Height - gScreenHeight);
+          if i = gSpectY then
+            gSpectAutoNext := gTime
+          else
+            gSpectY := i;
+        end;
+        if gSpectAutoNext <= gTime then
+        begin
+          if gSpectAutoNext > 0 then
+          begin
+            gSpectMode := GetRandomSpectMode(gSpectMode);
+            case gSpectMode of
+              SPECT_MAPVIEW:
+              begin
+                gSpectX := Random(gMapInfo.Width - gScreenWidth);
+                gSpectY := Random(gMapInfo.Height - gScreenHeight);
+                gSpectAutoStepX := Random(9) - 4;
+                gSpectAutoStepY := Random(9) - 4;
+                if ((gSpectX < 800) and (gSpectAutoStepX < 0)) or
+                   ((gSpectX > gMapInfo.Width - gScreenWidth - 800) and (gSpectAutoStepX > 0)) then
+                  gSpectAutoStepX := gSpectAutoStepX * -1;
+                if ((gSpectY < 800) and (gSpectAutoStepY < 0)) or
+                   ((gSpectY > gMapInfo.Height - gScreenHeight - 800) and (gSpectAutoStepY > 0)) then
+                  gSpectAutoStepY := gSpectAutoStepY * -1;
+              end;
+              SPECT_PLAYERS:
+              begin
+                gSpectPID1 := GetActivePlayerID_Random(gSpectPID1);
+              end;
+            end;
+          end;
+          case gSpectMode of
+            SPECT_STATS:   gSpectAutoNext := gTime + (Random(3) + 5) * 1000;
+            SPECT_MAPVIEW: gSpectAutoNext := gTime + (Random(4) + 7) * 1000;
+            SPECT_PLAYERS: gSpectAutoNext := gTime + (Random(7) + 8) * 1000;
+          end;
+        end;
+      end;
     end;
 
   // Îáíîâëÿåì âñå îñòàëüíîå:
@@ -2181,7 +2310,12 @@ begin
   end;
 
   g_Frames_CreateWAD(nil, 'FRAMES_TELEPORT', GameWAD+':TEXTURES\TELEPORT', 64, 64, 10, False);
-  g_Frames_CreateWAD(nil, 'FRAMES_PUNCH', GameWAD+':TEXTURES\PUNCH', 64, 64, 4, False);
+  g_Frames_CreateWAD(nil, 'FRAMES_PUNCH', GameWAD+':WEAPONS\PUNCH', 64, 64, 4, False);
+  g_Frames_CreateWAD(nil, 'FRAMES_PUNCH_UP', GameWAD+':WEAPONS\PUNCH_UP', 64, 64, 4, False);
+  g_Frames_CreateWAD(nil, 'FRAMES_PUNCH_DN', GameWAD+':WEAPONS\PUNCH_DN', 64, 64, 4, False);
+  g_Frames_CreateWAD(nil, 'FRAMES_PUNCH_BERSERK', GameWAD+':WEAPONS\PUNCHB', 64, 64, 4, False);
+  g_Frames_CreateWAD(nil, 'FRAMES_PUNCH_BERSERK_UP', GameWAD+':WEAPONS\PUNCHB_UP', 64, 64, 4, False);
+  g_Frames_CreateWAD(nil, 'FRAMES_PUNCH_BERSERK_DN', GameWAD+':WEAPONS\PUNCHB_DN', 64, 64, 4, False);
   g_Sound_CreateWADEx('SOUND_GAME_TELEPORT', GameWAD+':SOUNDS\TELEPORT');
   g_Sound_CreateWADEx('SOUND_GAME_NOTELEPORT', GameWAD+':SOUNDS\NOTELEPORT');
   g_Sound_CreateWADEx('SOUND_GAME_DOOROPEN', GameWAD+':SOUNDS\DOOROPEN');
@@ -2259,6 +2393,11 @@ begin
   g_Texture_Delete('TEXTURE_PLAYER_INVULPENTA');
   g_Frames_DeleteByName('FRAMES_TELEPORT');
   g_Frames_DeleteByName('FRAMES_PUNCH');
+  g_Frames_DeleteByName('FRAMES_PUNCH_UP');
+  g_Frames_DeleteByName('FRAMES_PUNCH_DN');
+  g_Frames_DeleteByName('FRAMES_PUNCH_BERSERK');
+  g_Frames_DeleteByName('FRAMES_PUNCH_BERSERK_UP');
+  g_Frames_DeleteByName('FRAMES_PUNCH_BERSERK_DN');
   g_Sound_Delete('SOUND_GAME_TELEPORT');
   g_Sound_Delete('SOUND_GAME_NOTELEPORT');
   g_Sound_Delete('SOUND_GAME_DOOROPEN');
@@ -3120,7 +3259,7 @@ var
     tagmask: Integer;
     pan: TPanel;
   begin
-    profileFrameDraw.sectionBegin(profname);
+    if (profileFrameDraw <> nil) then profileFrameDraw.sectionBegin(profname);
     if gdbg_map_use_accel_render then
     begin
       tagmask := panelTypeToTag(panType);
@@ -3136,31 +3275,31 @@ var
     begin
       if doDraw then g_Map_DrawPanels(panType, hasAmbient, ambColor);
     end;
-    profileFrameDraw.sectionEnd();
+    if (profileFrameDraw <> nil) then profileFrameDraw.sectionEnd();
   end;
 
   procedure drawOther (profname: AnsiString; cb: TDrawCB);
   begin
-    profileFrameDraw.sectionBegin(profname);
+    if (profileFrameDraw <> nil) then profileFrameDraw.sectionBegin(profname);
     if assigned(cb) then cb();
-    profileFrameDraw.sectionEnd();
+    if (profileFrameDraw <> nil) then profileFrameDraw.sectionEnd();
   end;
 
 begin
-  profileFrameDraw.sectionBegin('total');
+  if (profileFrameDraw <> nil) then profileFrameDraw.sectionBegin('total');
 
   // our accelerated renderer will collect all panels to gDrawPanelList
   // we can use panel tag to render level parts (see GridTagXXX in g_map.pas)
-  profileFrameDraw.sectionBegin('collect');
+  if (profileFrameDraw <> nil) then profileFrameDraw.sectionBegin('collect');
   if gdbg_map_use_accel_render then
   begin
     g_Map_CollectDrawPanels(sX, sY, sWidth, sHeight);
   end;
-  profileFrameDraw.sectionEnd();
+  if (profileFrameDraw <> nil) then profileFrameDraw.sectionEnd();
 
-  profileFrameDraw.sectionBegin('skyback');
+  if (profileFrameDraw <> nil) then profileFrameDraw.sectionBegin('skyback');
   g_Map_DrawBack(backXOfs, backYOfs);
-  profileFrameDraw.sectionEnd();
+  if (profileFrameDraw <> nil) then profileFrameDraw.sectionEnd();
 
   if setTransMatrix then
   begin
@@ -3217,7 +3356,7 @@ begin
     g_Player_DrawHealth();
   end;
 
-  profileFrameDraw.mainEnd(); // map rendering
+  if (profileFrameDraw <> nil) then profileFrameDraw.mainEnd(); // map rendering
 end;
 
 
@@ -3257,7 +3396,7 @@ begin
   end;
 
   if (profileFrameDraw = nil) then profileFrameDraw := TProfiler.Create('RENDER', g_profile_history_size);
-  profileFrameDraw.mainBegin(g_profile_frame_draw);
+  if (profileFrameDraw <> nil) then profileFrameDraw.mainBegin(g_profile_frame_draw);
 
   gPlayerDrawn := p;
 
@@ -3390,11 +3529,13 @@ begin
   p.viewPortW := sWidth;
   p.viewPortH := sHeight;
 
+{$IFDEF ENABLE_HOLMES}
   if (p = gPlayer1) then
   begin
     g_Holmes_plrViewPos(sX, sY);
     g_Holmes_plrViewSize(sWidth, sHeight);
   end;
+{$ENDIF}
 
   renderMapInternal(-c, -d, true);
 
@@ -3436,9 +3577,9 @@ var
   px: Integer = -1;
   py: Integer = -1;
 begin
-  if g_profile_frame_draw then px := px-drawProfiles(px, py, profileFrameDraw);
-  if g_profile_collision then begin px := px-drawProfiles(px, py, profMapCollision); py -= calcProfilesHeight(profMonsLOS); end;
-  if g_profile_los then begin px := px-drawProfiles(px, py, profMonsLOS); py -= calcProfilesHeight(profMonsLOS); end;
+  if g_profile_frame_draw and (profileFrameDraw <> nil) then px := px-drawProfiles(px, py, profileFrameDraw);
+  if g_profile_collision and (profMapCollision <> nil) then begin px := px-drawProfiles(px, py, profMapCollision); py -= calcProfilesHeight(profMonsLOS); end;
+  if g_profile_los and (profMonsLOS <> nil) then begin px := px-drawProfiles(px, py, profMonsLOS); py -= calcProfilesHeight(profMonsLOS); end;
 end;
 
 procedure g_Game_Draw();
@@ -3584,8 +3725,10 @@ begin
         e_DrawLine(2, 0, gScreenHeight div 2, gScreenWidth, gScreenHeight div 2, 0, 0, 0);
     end;
 
+{$IFDEF ENABLE_HOLMES}
     // draw inspector
     if (g_holmes_enabled) then g_Holmes_Draw();
+{$ENDIF}
 
     if MessageText <> '' then
     begin
@@ -3602,7 +3745,7 @@ begin
 
     if IsDrawStat or (gSpectMode = 1) then DrawStat();
 
-    if gSpectHUD and (not gChatShow) and (gSpectMode <> SPECT_NONE) then
+    if gSpectHUD and (not gChatShow) and (gSpectMode <> SPECT_NONE) and (not gSpectAuto) then
     begin
     // Draw spectator GUI
       ww := 0;
@@ -3617,6 +3760,11 @@ begin
           e_TextureFontPrintEx(0, gScreenHeight - (hh+2)*2, 'MODE: Watch Players', gStdFont, 255, 255, 255, 1);
       end;
       e_TextureFontPrintEx(2*ww, gScreenHeight - (hh+2), '< jump >', gStdFont, 255, 255, 255, 1);
+      if gSpectMode = SPECT_STATS then
+      begin
+        e_TextureFontPrintEx(16*ww, gScreenHeight - (hh+2)*2, 'Autoview', gStdFont, 255, 255, 255, 1);
+        e_TextureFontPrintEx(16*ww, gScreenHeight - (hh+2), '< fire >', gStdFont, 255, 255, 255, 1);
+      end;
       if gSpectMode = SPECT_MAPVIEW then
       begin
         e_TextureFontPrintEx(22*ww, gScreenHeight - (hh+2)*2, '[-]', gStdFont, 255, 255, 255, 1);
@@ -3763,7 +3911,7 @@ begin
         //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180);
         e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
       end;
-      g_Serverlist_Draw(slCurrent);
+      g_Serverlist_Draw(slCurrent, slTable);
     end;
   end;
 
@@ -3797,7 +3945,9 @@ begin
 
   if gGameOn then drawProfilers();
 
+{$IFDEF ENABLE_HOLMES}
   g_Holmes_DrawUI();
+{$ENDIF}
 
   g_Touch_Draw;
 end;
@@ -4527,7 +4677,7 @@ begin
       gWADHash := MD5File(MapsDir + NewWAD);
       g_Game_LoadWAD(NewWAD);
     end else
-      // hash recieved in MC_RECV_GameEvent -> NET_EV_MAPSTART
+      // hash received in MC_RECV_GameEvent -> NET_EV_MAPSTART
       g_Game_ClientWAD(NewWAD, gWADHash);
   end else
     ResName := Map;
@@ -7312,13 +7462,18 @@ begin
   ProcessLoading(true);
 end;
 
-procedure g_Game_StepLoading();
+procedure g_Game_StepLoading(Value: Integer = -1);
 begin
   with LoadingStat do
   begin
-    Inc(CurValue);
-    Inc(ShowCount);
-    if (ShowCount > LOADING_SHOW_STEP) then
+    if Value = -1 then
+    begin
+      Inc(CurValue);
+      Inc(ShowCount);
+    end
+    else
+      CurValue := Value;
+    if (ShowCount > LOADING_SHOW_STEP) or (Value > -1) then
     begin
       ShowCount := 0;
       ProcessLoading();
@@ -7588,7 +7743,9 @@ begin
   conRegVar('los_enabled', @gmon_dbg_los_enabled, 'enable/disable monster LOS calculations', 'monster LOS', true);
   conRegVar('mon_think', @gmon_debug_think, 'enable/disable monster thinking', 'monster thinking', true);
 
+{$IFDEF ENABLE_HOLMES}
   conRegVar('dbg_holmes', @g_holmes_enabled, 'enable/disable Holmes', 'Holmes', true);
+{$ENDIF}
 
   conRegVar('dbg_ignore_level_bounds', @g_dbg_ignore_bounds, 'ignore level bounds', '',  false);