DEADSOFTWARE

no more public `gMonsters`
[d2df-sdl.git] / src / game / g_netmsg.pas
index e838a9b7fff87f34eaceee923c3dc387feb14fe1..a60f95fe10e2e313b1fd2512029fe5db397c2527 100644 (file)
@@ -13,7 +13,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *)
-{$MODE DELPHI}
+{$INCLUDE ../shared/a_modes.inc}
 unit g_netmsg;
 
 interface
@@ -627,11 +627,26 @@ end;
 // GAME (SEND)
 
 procedure MH_SEND_Everything(CreatePlayers: Boolean = False; ID: Integer = NET_EVERYONE);
+
+  function sendItemRespawn (it: PItem): Boolean;
+  begin
+    result := false; // don't stop
+    MH_SEND_ItemSpawn(True, it.myid, ID);
+  end;
+
+  function sendMonSpawn (monidx: Integer; mon: TMonster): Boolean;
+  begin
+    result := false; // don't stop
+    MH_SEND_MonsterSpawn(mon.UID, ID);
+  end;
+
 var
   I: Integer;
 begin
   if gPlayers <> nil then
+  begin
     for I := Low(gPlayers) to High(gPlayers) do
+    begin
       if gPlayers[I] <> nil then
       begin
         if CreatePlayers then MH_SEND_PlayerCreate(gPlayers[I].UID, ID);
@@ -641,18 +656,11 @@ begin
         if (gPlayers[I].Flag <> FLAG_NONE) and (gGameSettings.GameMode = GM_CTF) then
           MH_SEND_FlagEvent(FLAG_STATE_CAPTURED, gPlayers[I].Flag, gPlayers[I].UID, True, ID);
       end;
-
-  if gItems <> nil then
-  begin
-    for I := High(gItems) downto Low(gItems) do
-      if gItems[I].Live then
-        MH_SEND_ItemSpawn(True, I, ID);
+    end;
   end;
 
-  if gMonsters <> nil then
-    for I := 0 to High(gMonsters) do
-      if gMonsters[I] <> nil then
-        MH_SEND_MonsterSpawn(gMonsters[I].UID, ID);
+  g_Items_ForEachAlive(sendItemRespawn, true); // backwards
+  g_Mons_ForEach(sendMonSpawn);
 
   if gWalls <> nil then
     for I := Low(gWalls) to High(gWalls) do
@@ -1077,10 +1085,10 @@ begin
     for I := WP_FIRST to WP_LAST do
       e_Buffer_Write(@NetOut, Byte(FWeapon[I]));
 
-    for I := A_BULLETS to A_CELLS do
+    for I := A_BULLETS to A_HIGH do
       e_Buffer_Write(@NetOut, FAmmo[I]);
 
-    for I := A_BULLETS to A_CELLS do
+    for I := A_BULLETS to A_HIGH do
       e_Buffer_Write(@NetOut, FMaxAmmo[I]);
 
     for I := MR_SUIT to MR_MAX do
@@ -1102,6 +1110,7 @@ begin
     e_Buffer_Write(@NetOut, Byte(FPhysics));
     e_Buffer_Write(@NetOut, Byte(FNoRespawn));
     e_Buffer_Write(@NetOut, Byte(FJetpack));
+    e_Buffer_Write(@NetOut, FFireTime);
   end;
 
   g_Net_Host_Send(ID, True, NET_CHAN_PLAYER);
@@ -1178,17 +1187,21 @@ end;
 // ITEM (SEND)
 
 procedure MH_SEND_ItemSpawn(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
+var
+  it: PItem;
 begin
+  it := g_ItemByIdx(IID);
+
   e_Buffer_Write(@NetOut, Byte(NET_MSG_ISPAWN));
   e_Buffer_Write(@NetOut, IID);
   e_Buffer_Write(@NetOut, Byte(Quiet));
-  e_Buffer_Write(@NetOut, gItems[IID].ItemType);
-  e_Buffer_Write(@NetOut, Byte(gItems[IID].Fall));
-  e_Buffer_Write(@NetOut, Byte(gItems[IID].Respawnable));
-  e_Buffer_Write(@NetOut, gItems[IID].Obj.X);
-  e_Buffer_Write(@NetOut, gItems[IID].Obj.Y);
-  e_Buffer_Write(@NetOut, gItems[IID].Obj.Vel.X);
-  e_Buffer_Write(@NetOut, gItems[IID].Obj.Vel.Y);
+  e_Buffer_Write(@NetOut, it.ItemType);
+  e_Buffer_Write(@NetOut, Byte(it.Fall));
+  e_Buffer_Write(@NetOut, Byte(it.Respawnable));
+  e_Buffer_Write(@NetOut, it.Obj.X);
+  e_Buffer_Write(@NetOut, it.Obj.Y);
+  e_Buffer_Write(@NetOut, it.Obj.Vel.X);
+  e_Buffer_Write(@NetOut, it.Obj.Vel.Y);
 
   g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
 end;
@@ -1378,6 +1391,7 @@ begin
     e_Buffer_Write(@NetOut, MonsterAmmo);
     e_Buffer_Write(@NetOut, MonsterPain);
     e_Buffer_Write(@NetOut, Byte(AnimIsReverse));
+    e_Buffer_Write(@NetOut, FFireTime);
   end;
 
   g_Net_Host_Send(ID, True, NET_CHAN_MONSTER);
@@ -2130,10 +2144,10 @@ begin
     for I := WP_FIRST to WP_LAST do
       FWeapon[I] := (e_Raw_Read_Byte(P) <> 0);
 
-    for I := A_BULLETS to A_CELLS do
+    for I := A_BULLETS to A_HIGH do
       FAmmo[I] := e_Raw_Read_Word(P);
 
-    for I := A_BULLETS to A_CELLS do
+    for I := A_BULLETS to A_HIGH do
       FMaxAmmo[I] := e_Raw_Read_Word(P);
 
     for I := MR_SUIT to MR_MAX do
@@ -2182,6 +2196,7 @@ begin
     FNoRespawn := e_Raw_Read_Byte(P) <> 0;
     OldJet := FJetpack;
     FJetpack := e_Raw_Read_Byte(P) <> 0;
+    FFireTime := e_Raw_Read_LongInt(P);
     if OldJet and not FJetpack then
       JetpackOff
     else if not OldJet and FJetpack then
@@ -2336,6 +2351,7 @@ var
   T: Byte;
   Quiet, Fall{, Resp}: Boolean;
   Anim: TAnimation;
+  it: PItem;
 begin
   if not gGameOn then Exit;
   ID := e_Raw_Read_Word(P);
@@ -2349,8 +2365,10 @@ begin
   VY := e_Raw_Read_LongInt(P);
 
   g_Items_Create(X, Y, T, Fall, False, False, ID);
-  gItems[ID].Obj.Vel.X := VX;
-  gItems[ID].Obj.Vel.Y := VY;
+
+  it := g_ItemByIdx(ID);
+  it.Obj.Vel.X := VX;
+  it.Obj.Vel.Y := VY;
 
   if not Quiet then
   begin
@@ -2358,7 +2376,7 @@ begin
     if g_Frames_Get(AID, 'FRAMES_ITEM_RESPAWN') then
     begin
       Anim := TAnimation.Create(AID, False, 4);
-      g_GFX_OnceAnim(X+(gItems[ID].Obj.Rect.Width div 2)-16, Y+(gItems[ID].Obj.Rect.Height div 2)-16, Anim);
+      g_GFX_OnceAnim(X+(it.Obj.Rect.Width div 2)-16, Y+(it.Obj.Rect.Height div 2)-16, Anim);
       Anim.Free();
     end;
   end;
@@ -2372,42 +2390,10 @@ begin
   if not gGameOn then Exit;
   ID := e_Raw_Read_Word(P);
   Quiet := e_Raw_Read_Byte(P) <> 0;
-  if gItems = nil then Exit;
-  if (ID > High(gItems)) then Exit;
 
-  if not Quiet then
-    if gSoundEffectsDF then
-    begin
-      if gItems[ID].ItemType in [ITEM_SPHERE_BLUE, ITEM_SPHERE_WHITE, ITEM_INVUL,
-                                 ITEM_INVIS, ITEM_MEDKIT_BLACK, ITEM_JETPACK] then
-        g_Sound_PlayExAt('SOUND_ITEM_GETRULEZ',
-          gItems[ID].Obj.X, gItems[ID].Obj.Y)
-        else
-          if gItems[ID].ItemType in [ITEM_WEAPON_SAW, ITEM_WEAPON_PISTOL, ITEM_WEAPON_SHOTGUN1, ITEM_WEAPON_SHOTGUN2,
-                                     ITEM_WEAPON_CHAINGUN, ITEM_WEAPON_ROCKETLAUNCHER, ITEM_WEAPON_PLASMA,
-                                     ITEM_WEAPON_BFG, ITEM_WEAPON_SUPERPULEMET, ITEM_AMMO_BACKPACK] then
-            g_Sound_PlayExAt('SOUND_ITEM_GETWEAPON',
-              gItems[ID].Obj.X, gItems[ID].Obj.Y)
-            else
-              g_Sound_PlayExAt('SOUND_ITEM_GETITEM',
-                gItems[ID].Obj.X, gItems[ID].Obj.Y);
-    end
-    else
-    begin
-      if gItems[ID].ItemType in [ITEM_SPHERE_BLUE, ITEM_SPHERE_WHITE, ITEM_SUIT,
-                                 ITEM_MEDKIT_BLACK, ITEM_INVUL, ITEM_INVIS, ITEM_JETPACK] then
-        g_Sound_PlayExAt('SOUND_ITEM_GETRULEZ',
-          gItems[ID].Obj.X, gItems[ID].Obj.Y)
-      else
-        if gItems[ID].ItemType in [ITEM_WEAPON_SAW, ITEM_WEAPON_PISTOL, ITEM_WEAPON_SHOTGUN1, ITEM_WEAPON_SHOTGUN2,
-                                   ITEM_WEAPON_CHAINGUN, ITEM_WEAPON_ROCKETLAUNCHER, ITEM_WEAPON_PLASMA,
-                                   ITEM_WEAPON_BFG, ITEM_WEAPON_SUPERPULEMET] then
-          g_Sound_PlayExAt('SOUND_ITEM_GETWEAPON',
-            gItems[ID].Obj.X, gItems[ID].Obj.Y)
-        else
-          g_Sound_PlayExAt('SOUND_ITEM_GETITEM',
-            gItems[ID].Obj.X, gItems[ID].Obj.Y);
-    end;
+  if not g_ItemValidId(ID) then exit;
+
+  if not Quiet then g_Item_EmitPickupSound(ID);
 
   g_Items_Remove(ID);
 end;
@@ -2621,6 +2607,8 @@ begin
     SetHealth(MHealth);
 
     SetState(MState);
+
+    positionChanged(); // this updates spatial accelerators
   end;
 end;
 
@@ -2641,6 +2629,7 @@ begin
     GameVelX := e_Raw_Read_LongInt(P);
     GameVelY := e_Raw_Read_LongInt(P);
     GameDirection := TDirection(e_Raw_Read_Byte(P));
+    positionChanged(); // this updates spatial accelerators
   end;
 end;
 
@@ -2667,6 +2656,7 @@ begin
     MonsterAmmo := e_Raw_Read_LongInt(P);
     MonsterPain := e_Raw_Read_LongInt(P);
     AnimRevert := e_Raw_Read_Byte(P) <> 0;
+    FFireTime := e_Raw_Read_LongInt(P);
     RevertAnim(AnimRevert);
 
     if MonsterState <> MState then
@@ -2709,14 +2699,15 @@ end;
 procedure MC_RECV_MonsterDelete(P: Pointer);
 var
   ID: Integer;
-  M: TMonster;
+  M, mon: TMonster;
 begin
   ID := e_Raw_Read_Word(P);
   M := g_Monsters_Get(ID);
   if M = nil then Exit;
 
-  gMonsters[ID].SetState(5);
-  gMonsters[ID].MonsterRemoved := True;
+  mon := g_Mons_ByIdx(ID);
+  mon.SetState(5);
+  mon.MonsterRemoved := True;
 end;
 
 procedure MC_RECV_TimeSync(P: Pointer);