DEADSOFTWARE

net: sync moving items and flags
authorfgsfds <pvt.fgsfds@gmail.com>
Fri, 21 Jan 2022 19:08:56 +0000 (22:08 +0300)
committerfgsfds <pvt.fgsfds@gmail.com>
Fri, 21 Jan 2022 19:08:56 +0000 (22:08 +0300)
src/game/g_game.pas
src/game/g_items.pas
src/game/g_map.pas
src/game/g_net.pas
src/game/g_nethandler.pas
src/game/g_netmsg.pas

index add8be44def44354fd817f129e847a4e9c914944..653ba539cf7f1fd4138d26dec714ef679f6ecf38 100644 (file)
@@ -1781,6 +1781,16 @@ var
     if mon.gncNeedSend then MH_SEND_MonsterPos(mon.UID);
   end;
 
+  function sendItemPos (it: PItem): Boolean;
+  begin
+    result := false; // don't stop
+    if it.needSend then
+    begin
+      MH_SEND_ItemPos(it.myId);
+      it.needSend := False;
+    end;
+  end;
+
 var
   reliableUpdate: Boolean;
 begin
@@ -2239,6 +2249,18 @@ begin
 
         g_Mons_ForEach(sendMonsPos);
 
+        // update flags that aren't stationary
+        if gGameSettings.GameMode = GM_CTF then
+          for I := FLAG_RED to FLAG_BLUE do
+            if gFlags[I].NeedSend then
+            begin
+              gFlags[I].NeedSend := False;
+              MH_SEND_FlagPos(I);
+            end;
+
+        // update items that aren't stationary
+        g_Items_ForEachAlive(sendItemPos);
+
         if reliableUpdate then
         begin
           NetTimeToReliable := 0;
index 7331242b7672c3675c54be4b14d630736dfbbd95..0aa9d560ab9b00cd002fbca4ac994b9f80a76ede 100644 (file)
@@ -41,6 +41,7 @@ Type
     Obj: TObj;
     Animation: TAnimation;
     dropped: Boolean; // dropped from the monster? drops should be rendered after corpses, so zombie corpse will not obscure ammo container, for example
+    NeedSend: Boolean;
 
     procedure positionChanged (); //WARNING! call this after monster position was changed, or coldet will not work right!
 
@@ -133,6 +134,7 @@ end;
 // ////////////////////////////////////////////////////////////////////////// //
 procedure TItem.positionChanged ();
 begin
+  NeedSend := NeedSend or (Obj.X <> Obj.oldX) or (Obj.Y <> Obj.oldY);
 end;
 
 
@@ -348,6 +350,7 @@ begin
   it.alive := False;
   it.SpawnTrigger := -1;
   it.ItemType := ITEM_NONE;
+  it.NeedSend := false;
   freeIds.release(LongWord(idx));
 end;
 
@@ -371,6 +374,7 @@ begin
     it.alive := false;
     it.SpawnTrigger := -1;
     it.Respawnable := false;
+    it.NeedSend := false;
     //if not freeIds.hasFree[LongWord(i)] then raise Exception.Create('internal error in item idx manager');
   end;
 end;
@@ -461,6 +465,7 @@ begin
   it.alive := True;
   it.QuietRespawn := False;
   it.dropped := false;
+  it.NeedSend := false;
 
   g_Obj_Init(@it.Obj);
   it.Obj.X := X;
index 20bfa3bf1bee93ff29bc5471cb86a60cf214941a..39a6692f2b228df76f4274e25abc139397a58b8a 100644 (file)
@@ -54,6 +54,7 @@ type
     CaptureTime: LongWord;
     Animation:   TAnimation;
     Direction:   TDirection;
+    NeedSend:    Boolean;
   end;
 
 function  g_Map_Load(Res: String): Boolean;
@@ -2567,8 +2568,13 @@ begin
         begin
           if gFlags[a].Animation <> nil then gFlags[a].Animation.Update();
 
+          Obj.oldX := Obj.X;
+          Obj.oldY := Obj.Y;
+
           m := g_Obj_Move(@Obj, True, True);
 
+          NeedSend := NeedSend or (Obj.X <> Obj.oldX) or (Obj.Y <> Obj.oldY);
+
           if gTime mod (GAME_TICK*2) <> 0 then Continue;
 
           // Ñîïðîòèâëåíèå âîçäóõà
@@ -3153,6 +3159,9 @@ begin
       Direction := FlagPoints[Flag]^.Direction;
       State := FLAG_STATE_NORMAL;
     end;
+    Obj.oldX := Obj.X;
+    Obj.oldY := Obj.Y;
+    NeedSend := False; // the event will take care of this
     Count := -1;
   end;
 end;
index 45f507a53dcccadfe604224d5fccaa1f90f7666d..200fd5bedeb52fad78925fe358ae789572a99b0e 100644 (file)
@@ -21,7 +21,7 @@ uses
   e_log, e_msg, utils, ENet, Classes, md5, MAPDEF{$IFDEF USE_MINIUPNPC}, miniupnpc;{$ELSE};{$ENDIF}
 
 const
-  NET_PROTOCOL_VER = 186;
+  NET_PROTOCOL_VER = 187;
 
   NET_MAXCLIENTS = 24;
   NET_CHANS = 12;
index ebd9d1d87552720a3f1206f6d7ad14b4aa56a2b4..b5bc14de9bf8ce0c67aef4e5dbaf11fba63b3124 100644 (file)
@@ -101,6 +101,7 @@ begin
     NET_MSG_GEVENT: MC_RECV_GameEvent(NetMsg);
     NET_MSG_FLAG:   MC_RECV_FlagEvent(NetMsg);
     NET_MSG_GSET:   MC_RECV_GameSettings(NetMsg);
+    NET_MSG_FLAGPOS:MC_RECV_FlagPos(NetMsg);
 
     NET_MSG_PLR:    MC_RECV_PlayerCreate(NetMsg);
     NET_MSG_PLRPOS: MC_RECV_PlayerPos(NetMsg);
@@ -123,6 +124,7 @@ begin
 
     NET_MSG_ISPAWN: MC_RECV_ItemSpawn(NetMsg);
     NET_MSG_IDEL:   MC_RECV_ItemDestroy(NetMsg);
+    NET_MSG_IPOS:   MC_RECV_ItemPos(NetMsg);
 
     NET_MSG_PSTATE: MC_RECV_PanelState(NetMsg);
     NET_MSG_PTEX:   MC_RECV_PanelTexture(NetMsg);
index 0a4facfdbdc7a0fe1c91cd362962b5fc7e3dadc1..36c0aa15e5e293f5a64713e87706577d27149864 100644 (file)
@@ -31,6 +31,7 @@ const
   NET_MSG_FLAG   = 107;
   NET_MSG_REQFST = 108;
   NET_MSG_GSET   = 109;
+  NET_MSG_FLAGPOS= 110;
 
   NET_MSG_PLR    = 111;
   NET_MSG_PLRPOS = 112;
@@ -44,6 +45,7 @@ const
 
   NET_MSG_ISPAWN = 121;
   NET_MSG_IDEL   = 122;
+  NET_MSG_IPOS   = 123;
 
   NET_MSG_MSPAWN = 131;
   NET_MSG_MPOS   = 132;
@@ -51,8 +53,8 @@ const
   NET_MSG_MSHOT  = 134;
   NET_MSG_MDEL   = 135;
 
-  NET_MSG_PSTATE   = 141;
-  NET_MSG_PTEX     = 142;
+  NET_MSG_PSTATE = 141;
+  NET_MSG_PTEX   = 142;
 
   NET_MSG_TSOUND = 151;
   NET_MSG_TMUSIC = 152;
@@ -162,6 +164,7 @@ procedure MH_SEND_GameStats(ID: Integer = NET_EVERYONE);
 procedure MH_SEND_CoopStats(ID: Integer = NET_EVERYONE);
 procedure MH_SEND_GameEvent(EvType: Byte; EvNum: Integer = 0; EvStr: string = 'N'; ID: Integer = NET_EVERYONE);
 procedure MH_SEND_FlagEvent(EvType: Byte; Flag: Byte; PID: Word; Quiet: Boolean = False; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_FlagPos(Flag: Byte; ID: Integer = NET_EVERYONE);
 procedure MH_SEND_GameSettings(ID: Integer = NET_EVERYONE);
 // PLAYER
 procedure MH_SEND_PlayerCreate(PID: Word; ID: Integer = NET_EVERYONE);
@@ -175,6 +178,7 @@ procedure MH_SEND_PlayerSettings(PID: Word; Mdl: string = ''; ID: Integer = NET_
 // ITEM
 procedure MH_SEND_ItemSpawn(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
 procedure MH_SEND_ItemDestroy(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_ItemPos(IID: Word; ID: Integer = NET_EVERYONE);
 // PANEL
 procedure MH_SEND_PanelTexture(PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
 procedure MH_SEND_PanelState(PGUID: Integer; ID: Integer = NET_EVERYONE);
@@ -204,6 +208,7 @@ procedure MC_RECV_GameStats(var M: TMsg);
 procedure MC_RECV_CoopStats(var M: TMsg);
 procedure MC_RECV_GameEvent(var M: TMsg);
 procedure MC_RECV_FlagEvent(var M: TMsg);
+procedure MC_RECV_FlagPos(var M: TMsg);
 procedure MC_RECV_GameSettings(var M: TMsg);
 // PLAYER
 function  MC_RECV_PlayerCreate(var M: TMsg): Word;
@@ -217,6 +222,7 @@ procedure MC_RECV_PlayerSettings(var M: TMsg);
 // ITEM
 procedure MC_RECV_ItemSpawn(var M: TMsg);
 procedure MC_RECV_ItemDestroy(var M: TMsg);
+procedure MC_RECV_ItemPos(var M: TMsg);
 // PANEL
 procedure MC_RECV_PanelTexture(var M: TMsg);
 procedure MC_RECV_PanelState(var M: TMsg);
@@ -1054,10 +1060,23 @@ begin
   NetOut.Write(gFlags[Flag].Obj.Y);
   NetOut.Write(gFlags[Flag].Obj.Vel.X);
   NetOut.Write(gFlags[Flag].Obj.Vel.Y);
+  NetOut.Write(Byte(gFlags[Flag].Direction));
 
   g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
 end;
 
+procedure MH_SEND_FlagPos(Flag: Byte; ID: Integer = NET_EVERYONE);
+begin
+  NetOut.Write(Byte(NET_MSG_FLAGPOS));
+  NetOut.Write(Flag);
+  NetOut.Write(gFlags[Flag].Obj.X);
+  NetOut.Write(gFlags[Flag].Obj.Y);
+  NetOut.Write(gFlags[Flag].Obj.Vel.X);
+  NetOut.Write(gFlags[Flag].Obj.Vel.Y);
+
+  g_Net_Host_Send(ID, False, NET_CHAN_IMPORTANT);
+end;
+
 procedure MH_SEND_GameSettings(ID: Integer = NET_EVERYONE);
 begin
   NetOut.Write(Byte(NET_MSG_GSET));
@@ -1297,6 +1316,22 @@ begin
   g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
 end;
 
+procedure MH_SEND_ItemPos(IID: Word; ID: Integer = NET_EVERYONE);
+var
+  it: PItem;
+begin
+  it := g_Items_ByIdx(IID);
+
+  NetOut.Write(Byte(NET_MSG_IPOS));
+  NetOut.Write(IID);
+  NetOut.Write(it.Obj.X);
+  NetOut.Write(it.Obj.Y);
+  NetOut.Write(it.Obj.Vel.X);
+  NetOut.Write(it.Obj.Vel.Y);
+
+  g_Net_Host_Send(ID, False, NET_CHAN_LARGEDATA);
+end;
+
 // PANEL
 
 procedure MH_SEND_PanelTexture(PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
@@ -2026,6 +2061,18 @@ begin
   end;
 end;
 
+procedure MC_RECV_FlagPos(var M: TMsg);
+var
+  Fl: Byte;
+begin
+  Fl := M.ReadByte();
+  if Fl = FLAG_NONE then Exit;
+  gFlags[Fl].Obj.X := M.ReadLongInt();
+  gFlags[Fl].Obj.Y := M.ReadLongInt();
+  gFlags[Fl].Obj.Vel.X := M.ReadLongInt();
+  gFlags[Fl].Obj.Vel.Y := M.ReadLongInt();
+end;
+
 procedure MC_RECV_FlagEvent(var M: TMsg);
 var
   PID: Word;
@@ -2049,6 +2096,7 @@ begin
   gFlags[Fl].Obj.Y := M.ReadLongInt();
   gFlags[Fl].Obj.Vel.X := M.ReadLongInt();
   gFlags[Fl].Obj.Vel.Y := M.ReadLongInt();
+  gFlags[Fl].Direction := TDirection(M.ReadByte());
 
   Pl := g_Player_Get(PID);
   if (Pl = nil) and
@@ -2605,6 +2653,31 @@ begin
   g_Items_Remove(ID);
 end;
 
+procedure MC_RECV_ItemPos(var M: TMsg);
+var
+  ID: Word;
+  X, Y, VX, VY: Integer;
+  it: PItem;
+begin
+  if not gGameOn then Exit;
+
+  ID := M.ReadWord();
+  X := M.ReadLongInt();
+  Y := M.ReadLongInt();
+  VX := M.ReadLongInt();
+  VY := M.ReadLongInt();
+
+  if g_Items_ValidId(ID) then
+  begin
+    it := g_Items_ByIdx(ID);
+    it.Obj.X := X;
+    it.Obj.Y := Y;
+    it.Obj.Vel.X := VX;
+    it.Obj.Vel.Y := VY;
+    it.positionChanged();
+  end;
+end;
+
 // PANEL
 
 procedure MC_RECV_PanelTexture(var M: TMsg);