DEADSOFTWARE

new tree-based weapon hitscan tracer (sometimes it is faster than the old one, someti...
[d2df-sdl.git] / src / game / g_game.pas
index 497567b23ccf7e36e3e8e5f011c411211d65502c..fb5d978bc793a5152d9648cde712bb3a75de5d7a 100644 (file)
@@ -327,7 +327,7 @@ uses
   g_playermodel, g_gfx, g_options, g_weapons, Math,
   g_triggers, MAPDEF, g_monsters, e_sound, CONFIG,
   BinEditor, g_language, g_net, SDL,
-  ENet, e_fixedbuffer, g_netmsg, g_netmaster, GL, GLExt,
+  ENet, e_msg, g_netmsg, g_netmaster, GL, GLExt,
   utils, sfs;
 
 
@@ -1439,6 +1439,24 @@ var
   a: Byte;
   w: Word;
   i, b: Integer;
+
+  function sendMonsPos (mon: TMonster): Boolean;
+  begin
+    result := false; // don't stop
+    if (mon.MonsterType = MONSTER_BARREL) then
+    begin
+      if (mon.GameVelX <> 0) or (mon.GameVelY <> 0) then MH_SEND_MonsterPos(mon.UID);
+    end
+    else
+      if (mon.MonsterState <> MONSTATE_SLEEP) then
+      begin
+        if (mon.MonsterState <> MONSTATE_DEAD) or (mon.GameVelX <> 0) or (mon.GameVelY <> 0) then
+        begin
+          MH_SEND_MonsterPos(mon.UID);
+        end;
+      end;
+  end;
+
 begin
   g_ResetDynlights();
 // Ïîðà âûêëþ÷àòü èãðó:
@@ -1808,22 +1826,7 @@ begin
           if gPlayers[I] <> nil then
             MH_SEND_PlayerPos(True, gPlayers[I].UID);
 
-        if gMonsters <> nil then
-          for I := 0 to High(gMonsters) do
-            if gMonsters[I] <> nil then
-            begin
-              if (gMonsters[I].MonsterType = MONSTER_BARREL) then
-              begin
-                if (gMonsters[I].GameVelX <> 0) or (gMonsters[I].GameVelY <> 0) then
-                  MH_SEND_MonsterPos(gMonsters[I].UID);
-              end
-              else
-                if (gMonsters[I].MonsterState <> MONSTATE_SLEEP) then
-                  if (gMonsters[I].MonsterState <> MONSTATE_DEAD) or
-                     (gMonsters[I].GameVelX <> 0) or
-                     (gMonsters[I].GameVelY <> 0) then
-                  MH_SEND_MonsterPos(gMonsters[I].UID);
-            end;
+        g_Mons_ForEach(sendMonsPos);
 
         NetTimeToReliable := 0;
         NetTimeToUpdate := NetUpdateRate;
@@ -1835,22 +1838,7 @@ begin
             if gPlayers[I] <> nil then
               MH_SEND_PlayerPos(False, gPlayers[I].UID);
 
-        if gMonsters <> nil then
-          for I := 0 to High(gMonsters) do
-            if gMonsters[I] <> nil then
-            begin
-              if (gMonsters[I].MonsterType = MONSTER_BARREL) then
-              begin
-                if (gMonsters[I].GameVelX <> 0) or (gMonsters[I].GameVelY <> 0) then
-                  MH_SEND_MonsterPos(gMonsters[I].UID);
-              end
-              else
-                if (gMonsters[I].MonsterState <> MONSTATE_SLEEP) then
-                  if (gMonsters[I].MonsterState <> MONSTATE_DEAD) or
-                     (gMonsters[I].GameVelX <> 0) or
-                     (gMonsters[I].GameVelY <> 0) then
-                  MH_SEND_MonsterPos(gMonsters[I].UID);
-            end;
+        g_Mons_ForEach(sendMonsPos);
 
         NetTimeToUpdate := 0;
       end;
@@ -2453,6 +2441,28 @@ end;
 procedure DrawMinimap(p: TPlayer; RenderRect: e_graphics.TRect);
 var
   a, aX, aY, aX2, aY2, Scale, ScaleSz: Integer;
+
+  function monDraw (mon: TMonster): Boolean;
+  begin
+    result := false; // don't stop
+    with mon do
+    begin
+      if Live then
+      begin
+        // Ëåâûé âåðõíèé óãîë
+        aX := Obj.X div ScaleSz + 1;
+        aY := Obj.Y div ScaleSz + 1;
+        // Ðàçìåðû
+        aX2 := max(Obj.Rect.Width div ScaleSz, 1);
+        aY2 := max(Obj.Rect.Height div ScaleSz, 1);
+        // Ïðàâûé íèæíèé óãîë
+        aX2 := aX + aX2 - 1;
+        aY2 := aY + aY2 - 1;
+        e_DrawFillQuad(aX, aY, aX2, aY2, 255, 255, 0, 0);
+      end;
+    end;
+  end;
+
 begin
   if (gMapInfo.Width > RenderRect.Right - RenderRect.Left) or
      (gMapInfo.Height > RenderRect.Bottom - RenderRect.Top) then
@@ -2621,25 +2631,8 @@ begin
               end;
           end;
     end;
-    if gMonsters <> nil then
-    begin
-    // Ðèñóåì ìîíñòðîâ:
-      for a := 0 to High(gMonsters) do
-        if gMonsters[a] <> nil then with gMonsters[a] do
-          if Live then begin
-          // Ëåâûé âåðõíèé óãîë:
-            aX := Obj.X div ScaleSz + 1;
-            aY := Obj.Y div ScaleSz + 1;
-          // Ðàçìåðû:
-            aX2 := max(Obj.Rect.Width div ScaleSz, 1);
-            aY2 := max(Obj.Rect.Height div ScaleSz, 1);
-          // Ïðàâûé íèæíèé óãîë:
-            aX2 := aX + aX2 - 1;
-            aY2 := aY + aY2 - 1;
-
-            e_DrawFillQuad(aX, aY, aX2, aY2, 255, 255, 0, 0);
-          end;
-    end;
+    // Ðèñóåì ìîíñòðîâ
+    g_Mons_ForEach(monDraw);
   end;
 end;
 
@@ -3747,6 +3740,7 @@ var
   State: Byte;
   OuterLoop: Boolean;
   newResPath: string;
+  InMsg: TMsg;
 begin
   g_Game_Free();
 
@@ -3794,27 +3788,28 @@ begin
       if (NetEvent.kind = ENET_EVENT_TYPE_RECEIVE) then
       begin
         Ptr := NetEvent.packet^.data;
-        e_Raw_Seek(0);
+        if not InMsg.Init(Ptr, NetEvent.packet^.dataLength, True) then
+          continue;
 
-        MID := e_Raw_Read_Byte(Ptr);
+        MID := InMsg.ReadByte();
 
         if (MID = NET_MSG_INFO) and (State = 0) then
         begin
-          NetMyID := e_Raw_Read_Byte(Ptr);
-          NetPlrUID1 := e_Raw_Read_Word(Ptr);
+          NetMyID := InMsg.ReadByte();
+          NetPlrUID1 := InMsg.ReadWord();
 
-          WadName := e_Raw_Read_String(Ptr);
-          Map := e_Raw_Read_String(Ptr);
+          WadName := InMsg.ReadString();
+          Map := InMsg.ReadString();
 
-          gWADHash := e_Raw_Read_MD5(Ptr);
+          gWADHash := InMsg.ReadMD5();
 
-          gGameSettings.GameMode := e_Raw_Read_Byte(Ptr);
+          gGameSettings.GameMode := InMsg.ReadByte();
           gSwitchGameMode := gGameSettings.GameMode;
-          gGameSettings.GoalLimit := e_Raw_Read_Word(Ptr);
-          gGameSettings.TimeLimit := e_Raw_Read_Word(Ptr);
-          gGameSettings.MaxLives := e_Raw_Read_Byte(Ptr);
-          gGameSettings.Options := e_Raw_Read_LongWord(Ptr);
-          T := e_Raw_Read_LongWord(Ptr);
+          gGameSettings.GoalLimit := InMsg.ReadWord();
+          gGameSettings.TimeLimit := InMsg.ReadWord();
+          gGameSettings.MaxLives := InMsg.ReadByte();
+          gGameSettings.Options := InMsg.ReadLongWord();
+          T := InMsg.ReadLongWord();
 
           newResPath := g_Res_SearchSameWAD(MapsDir, WadName, gWADHash);
           if newResPath = '' then
@@ -4175,6 +4170,13 @@ end;
 procedure g_Game_RestartRound(NoMapRestart: Boolean = False);
 var
   i, n, nb, nr: Integer;
+
+  function monRespawn (mon: TMonster): Boolean;
+  begin
+    result := false; // don't stop
+    if not mon.FNoRespawn then mon.Respawn();
+  end;
+
 begin
   if not g_Game_IsServer then Exit;
   if gLMSRespawn = LMS_RESPAWN_NONE then Exit;
@@ -4243,11 +4245,8 @@ begin
 
   g_Items_RestartRound();
 
-  for i := Low(gMonsters) to High(gMonsters) do
-  begin
-    if (gMonsters[i] <> nil) and not gMonsters[i].FNoRespawn then
-      gMonsters[i].Respawn;
-  end;
+
+  g_Mons_ForEach(monRespawn);
 
   gLMSSoftSpawn := False;
 end;
@@ -4996,6 +4995,28 @@ begin
     if gdbg_map_dump_coldet_tree_queries then g_Console_Add('grid coldet tree queries: tan') else g_Console_Add('grid coldet tree queries: ona');
     exit;
   end;
+
+  if (cmd = 'mon_sq_enabled') then
+  begin
+    case getBool(1) of
+      -1: begin end;
+       0: gmon_debug_use_sqaccel := false;
+       1: gmon_debug_use_sqaccel := true;
+    end;
+    if gmon_debug_use_sqaccel then g_Console_Add('accelerated monster coldet: tan') else g_Console_Add('accelerated monster coldet: ona');
+    exit;
+  end;
+
+  if (cmd = 'wtrace_sq_enabled') then
+  begin
+    case getBool(1) of
+      -1: begin end;
+       0: gwep_debug_fast_trace := false;
+       1: gwep_debug_fast_trace := true;
+    end;
+    if gwep_debug_fast_trace then g_Console_Add('accelerated weapon hitscan: tan') else g_Console_Add('accelerated weapon hitscan: ona');
+    exit;
+  end;
 end;
 
 procedure DebugCommands(P: SArray);
@@ -5003,6 +5024,7 @@ var
   a, b: Integer;
   cmd: string;
   //pt: TPoint;
+  mon: TMonster;
 begin
 // Êîìàíäû îòëàäî÷íîãî ðåæèìà:
   if gDebugMode then
@@ -5080,12 +5102,14 @@ begin
           else
             begin
               with gPlayer1.Obj do
-                b := g_Monsters_Create(a,
+              begin
+                mon := g_Monsters_Create(a,
                      X + Rect.X + (Rect.Width div 2),
                      Y + Rect.Y + Rect.Height,
                      gPlayer1.Direction, True);
-              if (Length(P) > 2) and (b >= 0) then
-                gMonsters[b].MonsterBehaviour := Min(Max(StrToIntDef(P[2], BH_NORMAL), BH_NORMAL), BH_GOOD);
+              end;
+              if (Length(P) > 2) and (mon <> nil) then
+                mon.MonsterBehaviour := Min(Max(StrToIntDef(P[2], BH_NORMAL), BH_NORMAL), BH_GOOD);
             end;
         end;
     end