DEADSOFTWARE

key binds and vars are stored in dfconfig.cfg
[d2df-sdl.git] / src / game / g_netmsg.pas
index 98ef65484d75106458c50cf94f86679e52d992ca..e84d82965bcc48850e4d971a28234fb4adbf7a18 100644 (file)
@@ -1,4 +1,4 @@
-(* Copyright (C)  DooM 2D:Forever Developers
+(* Copyright (C)  Doom 2D: Forever Developers
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -109,6 +109,7 @@ const
   NET_EV_LMS_DRAW     = 16;
   NET_EV_KILLCOMBO    = 17;
   NET_EV_PLAYER_TOUCH = 18;
+  NET_EV_SECRET       = 19;
 
   NET_VE_STARTED      = 1;
   NET_VE_PASSED       = 2;
@@ -384,7 +385,7 @@ begin
 
   g_Console_Add(Format(_lc[I_PLAYER_JOIN], [PName]), True);
   e_WriteLog('NET: Client ' + PName + ' [' + IntToStr(C^.ID) +
-             '] connected. Assigned player #' + IntToStr(PID) + '.', MSG_NOTIFY);
+             '] connected. Assigned player #' + IntToStr(PID) + '.', TMsgType.Notify);
 
   MH_SEND_Info(C^.ID);
 
@@ -644,7 +645,7 @@ procedure MH_SEND_Everything(CreatePlayers: Boolean = False; ID: Integer = NET_E
   begin
     result := false; // don't stop
     MH_SEND_PanelState(pan.guid, ID); // anyway, to sync mplats
-    if (pan.GetTextureCount > 1) then MH_SEND_PanelTexture(pan.guid, pan.LastAnimLoop, ID);
+    if (pan.CanChangeTexture) then MH_SEND_PanelTexture(pan.guid, pan.LastAnimLoop, ID);
   end;
 
 var
@@ -777,8 +778,8 @@ begin
     if Mode = NET_CHAT_PLAYER then
     begin
       g_Console_Add(Txt, True);
-      e_WriteLog('[Chat] ' + b_Text_Unformat(Txt), MSG_NOTIFY);
-      g_Sound_PlayEx('SOUND_GAME_RADIO');
+      e_WriteLog('[Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+      g_Game_ChatSound(b_Text_Unformat(Txt));
     end
     else
     if Mode = NET_CHAT_TEAM then
@@ -787,14 +788,14 @@ begin
         if (gPlayer1.Team = TEAM_RED) and (Team = TEAM_RED) then
         begin
           g_Console_Add(#18'[Team] '#2 + Txt, True);
-          e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), MSG_NOTIFY);
-          g_Sound_PlayEx('SOUND_GAME_RADIO');
+          e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+          g_Game_ChatSound(b_Text_Unformat(Txt));
         end
         else if (gPlayer1.Team = TEAM_BLUE) and (Team = TEAM_BLUE) then
         begin
           g_Console_Add(#20'[Team] '#2 + Txt, True);
-          e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), MSG_NOTIFY);
-          g_Sound_PlayEx('SOUND_GAME_RADIO');
+          e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+          g_Game_ChatSound(b_Text_Unformat(Txt));
         end;
       end;
   end
@@ -802,8 +803,8 @@ begin
   begin
     Name := g_Net_ClientName_ByID(ID);
     g_Console_Add('-> ' + Name + ': ' + Txt, True);
-    e_WriteLog('[Tell ' + Name + '] ' + b_Text_Unformat(Txt), MSG_NOTIFY);
-    g_Sound_PlayEx('SOUND_GAME_RADIO');
+    e_WriteLog('[Tell ' + Name + '] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+    g_Game_ChatSound(b_Text_Unformat(Txt), False);
   end;
 end;
 
@@ -1007,7 +1008,7 @@ begin
     end;
 
     NetOut.Write(kByte);
-    if Direction = D_LEFT then NetOut.Write(Byte(0)) else NetOut.Write(Byte(1));
+    if Direction = TDirection.D_LEFT then NetOut.Write(Byte(0)) else NetOut.Write(Byte(1));
     NetOut.Write(GameX);
     NetOut.Write(GameY);
     NetOut.Write(GameVelX);
@@ -1070,6 +1071,7 @@ begin
     NetOut.Write(Byte(FNoRespawn));
     NetOut.Write(Byte(FJetpack));
     NetOut.Write(FFireTime);
+    NetOut.Write(Byte(FFlaming));
   end;
 
   g_Net_Host_Send(ID, True, NET_CHAN_PLAYER);
@@ -1409,8 +1411,8 @@ begin
     if Mode = NET_CHAT_PLAYER then
     begin
       g_Console_Add(Txt, True);
-      e_WriteLog('[Chat] ' + b_Text_Unformat(Txt), MSG_NOTIFY);
-      g_Sound_PlayEx('SOUND_GAME_RADIO');
+      e_WriteLog('[Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+      g_Game_ChatSound(b_Text_Unformat(Txt));
     end else
     if (Mode = NET_CHAT_TEAM) and (gPlayer1 <> nil) then
     begin
@@ -1418,8 +1420,8 @@ begin
         g_Console_Add(b_Text_Format('\r[Team] ') + Txt, True);
       if gPlayer1.Team = TEAM_BLUE then
         g_Console_Add(b_Text_Format('\b[Team] ') + Txt, True);
-      e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), MSG_NOTIFY);
-      g_Sound_PlayEx('SOUND_GAME_RADIO');
+      e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+      g_Game_ChatSound(b_Text_Unformat(Txt));
     end;
   end else
     g_Console_Add(Txt, True);
@@ -1830,6 +1832,16 @@ begin
         pl.Touch();
     end;
 
+    NET_EV_SECRET:
+    begin
+      pl := g_Player_Get(EvNum);
+      if pl <> nil then
+      begin
+        g_Console_Add(Format(_lc[I_PLAYER_SECRET], [pl.Name]), True);
+        g_Sound_PlayEx('SOUND_GAME_SECRET');
+      end;
+    end;
+
   end;
 end;
 
@@ -1838,7 +1850,7 @@ var
   PID: Word;
   Pl: TPlayer;
   EvType: Byte;
-  Fl: Byte;
+  Fl, a: Byte;
   Quiet: Boolean;
   s, ts: string;
 begin
@@ -1875,6 +1887,16 @@ begin
         s := _lc[I_PLAYER_FLAG_BLUE];
 
       g_Game_Message(Format(_lc[I_MESSAGE_FLAG_RETURN], [AnsiUpperCase(s)]), 144);
+
+      if ((Pl = gPlayer1) or (Pl = gPlayer2)
+      or ((gPlayer1 <> nil) and (gPlayer1.Team = Pl.Team))
+      or ((gPlayer2 <> nil) and (gPlayer2.Team = Pl.Team))) then
+        a := 0
+      else
+        a := 1;
+
+      if not sound_ret_flag[a].IsPlaying() then
+        sound_ret_flag[a].Play();
     end;
 
     FLAG_STATE_CAPTURED:
@@ -1890,6 +1912,16 @@ begin
 
       g_Console_Add(Format(_lc[I_PLAYER_FLAG_GET], [Pl.Name, s]), True);
       g_Game_Message(Format(_lc[I_MESSAGE_FLAG_GET], [AnsiUpperCase(s)]), 144);
+
+      if ((Pl = gPlayer1) or (Pl = gPlayer2)
+      or ((gPlayer1 <> nil) and (gPlayer1.Team = Pl.Team))
+      or ((gPlayer2 <> nil) and (gPlayer2.Team = Pl.Team))) then
+        a := 0
+      else
+        a := 1;
+
+      if not sound_get_flag[a].IsPlaying() then
+        sound_get_flag[a].Play();
     end;
 
     FLAG_STATE_DROPPED:
@@ -1905,6 +1937,16 @@ begin
 
       g_Console_Add(Format(_lc[I_PLAYER_FLAG_DROP], [Pl.Name, s]), True);
       g_Game_Message(Format(_lc[I_MESSAGE_FLAG_DROP], [AnsiUpperCase(s)]), 144);
+
+      if ((Pl = gPlayer1) or (Pl = gPlayer2)
+      or ((gPlayer1 <> nil) and (gPlayer1.Team = Pl.Team))
+      or ((gPlayer2 <> nil) and (gPlayer2.Team = Pl.Team))) then
+        a := 0
+      else
+        a := 1;
+
+      if not sound_lost_flag[a].IsPlaying() then
+        sound_lost_flag[a].Play();
     end;
 
     FLAG_STATE_SCORED:
@@ -1923,6 +1965,16 @@ begin
       Insert('.', ts, Length(ts) + 1 - 3);
       g_Console_Add(Format(_lc[I_PLAYER_FLAG_CAPTURE], [Pl.Name, s, ts]), True);
       g_Game_Message(Format(_lc[I_MESSAGE_FLAG_CAPTURE], [AnsiUpperCase(s)]), 144);
+
+      if ((Pl = gPlayer1) or (Pl = gPlayer2)
+      or ((gPlayer1 <> nil) and (gPlayer1.Team = Pl.Team))
+      or ((gPlayer2 <> nil) and (gPlayer2.Team = Pl.Team))) then
+        a := 0
+      else
+        a := 1;
+
+      if not sound_cap_flag[a].IsPlaying() then
+        sound_cap_flag[a].Play();
     end;
 
     FLAG_STATE_RETURNED:
@@ -1936,6 +1988,16 @@ begin
         s := _lc[I_PLAYER_FLAG_BLUE];
 
       g_Game_Message(Format(_lc[I_MESSAGE_FLAG_RETURN], [AnsiUpperCase(s)]), 144);
+
+      if ((Pl = gPlayer1) or (Pl = gPlayer2)
+      or ((gPlayer1 <> nil) and (gPlayer1.Team = Pl.Team))
+      or ((gPlayer2 <> nil) and (gPlayer2.Team = Pl.Team))) then
+        a := 0
+      else
+        a := 1;
+
+      if not sound_ret_flag[a].IsPlaying() then
+        sound_ret_flag[a].Play();
     end;
   end;
 end;
@@ -1996,7 +2058,7 @@ begin
   end;
 
   g_Console_Add(Format(_lc[I_PLAYER_JOIN], [PName]), True);
-  e_WriteLog('NET: Player ' + PName + ' [' + IntToStr(PID) + '] added.', MSG_NOTIFY);
+  e_WriteLog('NET: Player ' + PName + ' [' + IntToStr(PID) + '] added.', TMsgType.Notify);
   Result := PID;
 end;
 
@@ -2065,8 +2127,8 @@ function MC_RECV_PlayerStats(var M: TMsg): Word;
 var
   PID: Word;
   Pl: TPlayer;
-  I: Integer;
-  OldJet: Boolean;
+  I, OldFire: Integer;
+  OldJet, Flam: Boolean;
   NewTeam: Byte;
 begin
   PID := M.ReadWord();
@@ -2141,11 +2203,17 @@ begin
     FNoRespawn := M.ReadByte() <> 0;
     OldJet := FJetpack;
     FJetpack := M.ReadByte() <> 0;
+    OldFire := FFireTime;
     FFireTime := M.ReadLongInt();
+    if (OldFire <= 0) and (FFireTime > 0) then
+      g_Sound_PlayExAt('SOUND_IGNITE', Obj.X, Obj.Y);
+    Flam := M.ReadByte() <> 0;
     if OldJet and not FJetpack then
       JetpackOff
     else if not OldJet and FJetpack then
       JetpackOn;
+    if FFlaming and not Flam then
+      FlamerOff;
     if Team <> NewTeam then
       Pl.ChangeTeam(NewTeam);
   end;
@@ -2214,7 +2282,7 @@ begin
   if Pl = nil then Exit;
 
   g_Console_Add(Format(_lc[I_PLAYER_LEAVE], [Pl.Name]), True);
-  e_WriteLog('NET: Player ' + Pl.Name + ' [' + IntToStr(PID) + '] removed.', MSG_NOTIFY);
+  e_WriteLog('NET: Player ' + Pl.Name + ' [' + IntToStr(PID) + '] removed.', TMsgType.Notify);
 
   g_Player_Remove(PID);
 
@@ -2364,17 +2432,9 @@ begin
   TP := g_Map_PanelByGUID(PGUID);
   if (TP <> nil) then
   begin
-    if Loop = 0 then
-    begin
-      // switch texture
-      TP.SetTexture(Tex, Loop);
-      TP.SetFrame(Fr, Cnt);
-    end
-    else
-    begin
-      // looped or non-looped animation
-      TP.NextTexture(Loop);
-    end;
+    // switch texture
+    TP.SetTexture(Tex, Loop);
+    TP.SetFrame(Fr, Cnt);
   end;
 end;
 
@@ -2464,16 +2524,19 @@ begin
       if gTriggers[I].ClientID = SID then
         with gTriggers[I] do
         begin
-          if SPlaying then
+          if Sound <> nil then
           begin
-            if tgcLocal then
-              Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), tgcVolume/255.0)
+            if SPlaying then
+            begin
+              if tgcLocal then
+                Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), tgcVolume/255.0)
+              else
+                Sound.PlayPanVolume((tgcPan-127.0)/128.0, tgcVolume/255.0);
+              Sound.SetPosition(SPos);
+            end
             else
-              Sound.PlayPanVolume((tgcPan-127.0)/128.0, tgcVolume/255.0);
-            Sound.SetPosition(SPos);
-          end
-          else
-            if Sound.IsPlaying then Sound.Stop;
+              if Sound.IsPlaying then Sound.Stop;
+          end;
 
           SoundPlayCount := SCount;
         end;
@@ -2583,7 +2646,7 @@ end;
 
 procedure MC_RECV_MonsterState(var M: TMsg);
 var
-  ID: Integer;
+  ID, OldFire: Integer;
   MState, MFAnm: Byte;
   Mon: TMonster;
   AnimRevert: Boolean;
@@ -2604,7 +2667,10 @@ begin
     MonsterAmmo := M.ReadLongInt();
     MonsterPain := M.ReadLongInt();
     AnimRevert := M.ReadByte() <> 0;
+    OldFire := FFireTime;
     FFireTime := M.ReadLongInt();
+    if (OldFire <= 0) and (FFireTime > 0) then
+      g_Sound_PlayExAt('SOUND_IGNITE', Obj.X, Obj.Y);
     RevertAnim(AnimRevert);
 
     if MonsterState <> MState then
@@ -2715,20 +2781,12 @@ begin
   g_Net_Client_Send(True, NET_CHAN_CHAT);
 end;
 
-function isKeyPressed (key1: Word; key2: Word): Boolean;
-begin
-  if (key1 <> 0) and e_KeyPressed(key1) then begin result := true; exit; end;
-  if (key2 <> 0) and e_KeyPressed(key2) then begin result := true; exit; end;
-  result := false;
-end;
-
 procedure MC_SEND_PlayerPos();
 var
   kByte: Word;
   Predict: Boolean;
   strafeDir: Byte;
   WeaponSelect: Word = 0;
-  I: Integer;
 begin
   if not gGameOn then Exit;
   if gPlayers = nil then Exit;
@@ -2741,62 +2799,70 @@ begin
   begin
     strafeDir := P1MoveButton shr 4;
     P1MoveButton := P1MoveButton and $0F;
-    with gGameControls.P1Control do
+
+    if gPlayerAction[0, ACTION_MOVELEFT] and (not gPlayerAction[0, ACTION_MOVERIGHT]) then
+      P1MoveButton := 1
+    else if (not gPlayerAction[0, ACTION_MOVELEFT]) and gPlayerAction[0, ACTION_MOVERIGHT] then
+      P1MoveButton := 2
+    else if (not gPlayerAction[0, ACTION_MOVELEFT]) and (not gPlayerAction[0, ACTION_MOVERIGHT]) then
+      P1MoveButton := 0;
+
+    // strafing
+    if gPlayerAction[0, ACTION_STRAFE] then
     begin
-           if isKeyPressed(KeyLeft, KeyLeft2) and (not isKeyPressed(KeyRight, KeyRight2)) then P1MoveButton := 1
-      else if (not isKeyPressed(KeyLeft, KeyLeft2)) and isKeyPressed(KeyRight, KeyRight2) then P1MoveButton := 2
-      else if (not isKeyPressed(KeyLeft, KeyLeft2)) and (not isKeyPressed(KeyRight, KeyRight2)) then P1MoveButton := 0;
+      // new strafe mechanics
+      if (strafeDir = 0) then strafeDir := P1MoveButton; // start strafing
+      // now set direction according to strafe (reversed)
+           if (strafeDir = 2) then gPlayer1.SetDirection(TDirection.D_LEFT)
+      else if (strafeDir = 1) then gPlayer1.SetDirection(TDirection.D_RIGHT);
+    end
+    else
+    begin
+      if (P1MoveButton = 2) and gPlayerAction[0, ACTION_MOVELEFT] then
+        gPlayer1.SetDirection(TDirection.D_LEFT)
+      else if (P1MoveButton = 1) and gPlayerAction[0, ACTION_MOVERIGHT] then
+        gPlayer1.SetDirection(TDirection.D_RIGHT)
+      else if P1MoveButton <> 0 then
+        gPlayer1.SetDirection(TDirection(P1MoveButton-1));
+    end;
 
-      // strafing
-      if isKeyPressed(KeyStrafe, KeyStrafe2) then
-      begin
-        // new strafe mechanics
-        if (strafeDir = 0) then strafeDir := P1MoveButton; // start strafing
-        // now set direction according to strafe (reversed)
-             if (strafeDir = 2) then gPlayer1.SetDirection(D_LEFT)
-        else if (strafeDir = 1) then gPlayer1.SetDirection(D_RIGHT);
-      end
-      else
-      begin
-             if (P1MoveButton = 2) and isKeyPressed(KeyLeft, KeyLeft2) then gPlayer1.SetDirection(D_LEFT)
-        else if (P1MoveButton = 1) and isKeyPressed(KeyRight, KeyRight2) then gPlayer1.SetDirection(D_RIGHT)
-        else if P1MoveButton <> 0 then gPlayer1.SetDirection(TDirection(P1MoveButton-1));
-      end;
+    gPlayer1.ReleaseKeys;
+    if P1MoveButton = 1 then
+    begin
+      kByte := kByte or NET_KEY_LEFT;
+      if Predict then gPlayer1.PressKey(KEY_LEFT, 10000);
+    end;
+    if P1MoveButton = 2 then
+    begin
+      kByte := kByte or NET_KEY_RIGHT;
+      if Predict then gPlayer1.PressKey(KEY_RIGHT, 10000);
+    end;
+    if gPlayerAction[0, ACTION_LOOKUP] then
+    begin
+      kByte := kByte or NET_KEY_UP;
+      gPlayer1.PressKey(KEY_UP, 10000);
+    end;
+    if gPlayerAction[0, ACTION_LOOKDOWN] then
+    begin
+      kByte := kByte or NET_KEY_DOWN;
+      gPlayer1.PressKey(KEY_DOWN, 10000);
+    end;
+    if gPlayerAction[0, ACTION_JUMP] then
+    begin
+      kByte := kByte or NET_KEY_JUMP;
+      // gPlayer1.PressKey(KEY_JUMP, 10000); // TODO: Make a prediction option
+    end;
+    if gPlayerAction[0, ACTION_ATTACK] then kByte := kByte or NET_KEY_FIRE;
+    if gPlayerAction[0, ACTION_ACTIVATE] then kByte := kByte or NET_KEY_OPEN;
+    if gPlayerAction[0, ACTION_WEAPNEXT] then kByte := kByte or NET_KEY_NW;
+    if gPlayerAction[0, ACTION_WEAPPREV] then kByte := kByte or NET_KEY_PW;
 
-      gPlayer1.ReleaseKeys;
-      if P1MoveButton = 1 then
-      begin
-        kByte := kByte or NET_KEY_LEFT;
-        if Predict then gPlayer1.PressKey(KEY_LEFT, 10000);
-      end;
-      if P1MoveButton = 2 then
-      begin
-        kByte := kByte or NET_KEY_RIGHT;
-        if Predict then gPlayer1.PressKey(KEY_RIGHT, 10000);
-      end;
-      if isKeyPressed(KeyUp, KeyUp2) then
-      begin
-        kByte := kByte or NET_KEY_UP;
-        gPlayer1.PressKey(KEY_UP, 10000);
-      end;
-      if isKeyPressed(KeyDown, KeyDown2) then
-      begin
-        kByte := kByte or NET_KEY_DOWN;
-        gPlayer1.PressKey(KEY_DOWN, 10000);
-      end;
-      if isKeyPressed(KeyJump, KeyJump2) then
-      begin
-        kByte := kByte or NET_KEY_JUMP;
-        // gPlayer1.PressKey(KEY_JUMP, 10000); // TODO: Make a prediction option
-      end;
-      if isKeyPressed(KeyFire, KeyFire2) then kByte := kByte or NET_KEY_FIRE;
-      if isKeyPressed(KeyOpen, KeyOpen2) then kByte := kByte or NET_KEY_OPEN;
-      if isKeyPressed(KeyNextWeapon, KeyNextWeapon2) then kByte := kByte or NET_KEY_NW;
-      if isKeyPressed(KeyPrevWeapon, KeyPrevWeapon2) then kByte := kByte or NET_KEY_PW;
-      for I := 0 to High(KeyWeapon) do
-        if isKeyPressed(KeyWeapon[I], KeyWeapon2[I]) then
-          WeaponSelect := WeaponSelect or Word(1 shl I);
+    if gSelectWeapon[0] >= 0 then
+    begin
+      WeaponSelect := gSelectWeapon[0];
+      //gSelectWeapon[0] := -1
     end;
+
     // fix movebutton state
     P1MoveButton := P1MoveButton or (strafeDir shl 4);
   end
@@ -2872,15 +2938,15 @@ var
   FileStream : TStream;
   fname: string;
 begin
-  e_WriteLog(Format('NETWORK: looking for file "%s"', [FileName]), MSG_NOTIFY);
+  e_WriteLog(Format('NETWORK: looking for file "%s"', [FileName]), TMsgType.Notify);
   fname := findDiskWad(FileName);
   if length(fname) = 0 then
   begin
-    e_WriteLog(Format('NETWORK: file "%s" not found!', [FileName]), MSG_FATALERROR);
+    e_WriteLog(Format('NETWORK: file "%s" not found!', [FileName]), TMsgType.Fatal);
     SetLength(Result, 0);
     exit;
   end;
-  e_WriteLog(Format('NETWORK: found file "%s"', [fname]), MSG_NOTIFY);
+  e_WriteLog(Format('NETWORK: found file "%s"', [fname]), TMsgType.Notify);
   Result := nil;
   FileStream := openDiskFileRO(fname);
   try
@@ -3019,10 +3085,10 @@ var
   mapDataMsg: TMapDataMsg;
 begin
   e_WriteLog('NET: Received map request from ' +
-             DecodeIPV4(C.Peer.address.host), MSG_NOTIFY);
+             DecodeIPV4(C^.Peer.address.host), TMsgType.Notify);
 
   mapDataMsg := CreateMapDataMsg(MapsDir + gGameSettings.WAD, gExternalResources);
-  peer := NetClients[C.ID].Peer;
+  peer := NetClients[C^.ID].Peer;
 
   MapDataMsgToBytes(payload, mapDataMsg);
   g_Net_SendData(payload, peer, True, NET_CHAN_DOWNLOAD);
@@ -3041,15 +3107,15 @@ var
 begin
   FileName := ExtractFileName(M.ReadString());
   e_WriteLog('NET: Received res request: ' + FileName +
-             ' from ' + DecodeIPV4(C.Peer.address.host), MSG_NOTIFY);
+             ' from ' + DecodeIPV4(C^.Peer.address.host), TMsgType.Notify);
 
   if not IsValidFilePath(FileName) then
   begin
-    e_WriteLog('Invalid filename: ' + FileName, MSG_WARNING);
+    e_WriteLog('Invalid filename: ' + FileName, TMsgType.Warning);
     exit;
   end;
 
-  peer := NetClients[C.ID].Peer;
+  peer := NetClients[C^.ID].Peer;
 
   if gExternalResources.IndexOf(FileName) > -1 then
   begin