DEADSOFTWARE

implemented weapon queue (no network code for it yet)
[d2df-sdl.git] / src / game / g_netmsg.pas
index 869da64bf5c6556f5f7ef047c8d0380d40183a18..6e8106fc61701e20d9b29c2eede43ff50d6cec16 100644 (file)
@@ -146,7 +146,7 @@ procedure MH_SEND_Everything(CreatePlayers: Boolean = False; ID: Integer = NET_E
 procedure MH_SEND_Info(ID: Byte);
 procedure MH_SEND_Chat(Txt: string; Mode: Byte; ID: Integer = NET_EVERYONE);
 procedure MH_SEND_Effect(X, Y: Integer; Ang: SmallInt; Kind: Byte; ID: Integer = NET_EVERYONE);
-procedure MH_SEND_Sound(X, Y: Integer; Name: string; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_Sound(X, Y: Integer; Name: string; Pos: Boolean = True; ID: Integer = NET_EVERYONE);
 procedure MH_SEND_CreateShot(Proj: LongInt; ID: Integer = NET_EVERYONE);
 procedure MH_SEND_UpdateShot(Proj: LongInt; ID: Integer = NET_EVERYONE);
 procedure MH_SEND_DeleteShot(Proj: LongInt; X, Y: LongInt; Loud: Boolean = True; ID: Integer = NET_EVERYONE);
@@ -430,7 +430,7 @@ end;
 
 function  MH_RECV_PlayerPos(C: pTNetClient; P: Pointer): Word;
 var
-  Dir: Byte;
+  Dir, WeaponSelect: Byte;
   PID: Word;
   kByte: Word;
   Pl: TPlayer;
@@ -452,8 +452,10 @@ begin
     NetTime := GT;
     kByte := e_Raw_Read_Word(P);
     Dir := e_Raw_Read_Byte(P);
+    WeaponSelect := e_Raw_Read_Byte(P);
     if Direction <> TDirection(Dir) then
       JustTeleported := False;
+
     SetDirection(TDirection(Dir));
     ReleaseKeys;
 
@@ -472,6 +474,9 @@ begin
     if LongBool(kByte and NET_KEY_OPEN) then PressKey(KEY_OPEN, 10000);
     if LongBool(kByte and NET_KEY_NW) then PressKey(KEY_NEXTWEAPON, 10000);
     if LongBool(kByte and NET_KEY_PW) then PressKey(KEY_PREVWEAPON, 10000);
+
+    if WeaponSelect <> 255 then
+      QueueWeaponSwitch(WeaponSelect);
   end;
 
   // MH_SEND_PlayerPos(False, PID, C^.ID);
@@ -838,12 +843,18 @@ begin
   g_Net_Host_Send(ID, False, NET_CHAN_GAME);
 end;
 
-procedure MH_SEND_Sound(X, Y: Integer; Name: string; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_Sound(X, Y: Integer; Name: string; Pos: Boolean = True; ID: Integer = NET_EVERYONE);
 begin
   e_Buffer_Write(@NetOut, Byte(NET_MSG_SND));
   e_Buffer_Write(@NetOut, Name);
-  e_Buffer_Write(@NetOut, X);
-  e_Buffer_Write(@NetOut, Y);
+  if Pos then
+  begin
+    e_Buffer_Write(@NetOut, Byte(1));
+    e_Buffer_Write(@NetOut, X);
+    e_Buffer_Write(@NetOut, Y);
+  end
+  else
+    e_Buffer_Write(@NetOut, Byte(0));
 
   g_Net_Host_Send(ID, False, NET_CHAN_GAME);
 end;
@@ -1555,11 +1566,18 @@ procedure MC_RECV_Sound(P: Pointer);
 var
   Name: string;
   X, Y: Integer;
+  Pos: Boolean;
 begin
   Name := e_Raw_Read_String(P);
-  X := e_Raw_Read_LongInt(P);
-  Y := e_Raw_Read_LongInt(P);
-  g_Sound_PlayExAt(Name, X, Y);
+  Pos := e_Raw_Read_Byte(P) <> 0;
+  if Pos then
+  begin
+    X := e_Raw_Read_LongInt(P);
+    Y := e_Raw_Read_LongInt(P);
+    g_Sound_PlayExAt(Name, X, Y);
+  end
+  else
+    g_Sound_PlayEx(Name);
 end;
 
 procedure MC_RECV_CreateShot(P: Pointer);
@@ -2757,10 +2775,20 @@ 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: Byte = 255;
+  I: Integer;
 begin
   if not gGameOn then Exit;
   if gPlayers = nil then Exit;
@@ -2770,25 +2798,30 @@ begin
   Predict := NetPredictSelf; // and (not NetGotKeys);
 
   if (not gConsoleShow) and (not gChatShow) and (g_ActiveWindow = nil) then
+  begin
+    strafeDir := P1MoveButton shr 4;
+    P1MoveButton := P1MoveButton and $0F;
     with gGameControls.P1Control do
     begin
-      if e_KeyPressed(KeyLeft) and (not e_KeyPressed(KeyRight)) then
-        P1MoveButton := 1
-      else
-        if (not e_KeyPressed(KeyLeft)) and e_KeyPressed(KeyRight) then
-          P1MoveButton := 2
-        else
-          if (not e_KeyPressed(KeyLeft)) and (not e_KeyPressed(KeyRight)) then
-            P1MoveButton := 0;
+           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;
 
-      if (P1MoveButton = 2) and e_KeyPressed(KeyLeft) then
-        gPlayer1.SetDirection(D_LEFT)
+      // 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
-       if (P1MoveButton = 1) and e_KeyPressed(KeyRight) then
-          gPlayer1.SetDirection(D_RIGHT)
-        else
-          if P1MoveButton <> 0 then
-            gPlayer1.SetDirection(TDirection(P1MoveButton-1));
+      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
@@ -2801,26 +2834,32 @@ begin
         kByte := kByte or NET_KEY_RIGHT;
         if Predict then gPlayer1.PressKey(KEY_RIGHT, 10000);
       end;
-      if e_KeyPressed(KeyUp) then
+      if isKeyPressed(KeyUp, KeyUp2) then
       begin
         kByte := kByte or NET_KEY_UP;
         gPlayer1.PressKey(KEY_UP, 10000);
       end;
-      if e_KeyPressed(KeyDown) then
+      if isKeyPressed(KeyDown, KeyDown2) then
       begin
         kByte := kByte or NET_KEY_DOWN;
         gPlayer1.PressKey(KEY_DOWN, 10000);
       end;
-      if e_KeyPressed(KeyJump) then
+      if isKeyPressed(KeyJump, KeyJump2) then
       begin
         kByte := kByte or NET_KEY_JUMP;
         // gPlayer1.PressKey(KEY_JUMP, 10000); // TODO: Make a prediction option
       end;
-      if e_KeyPressed(KeyFire) then kByte := kByte or NET_KEY_FIRE;
-      if e_KeyPressed(KeyOpen) then kByte := kByte or NET_KEY_OPEN;
-      if e_KeyPressed(KeyNextWeapon) then kByte := kByte or NET_KEY_NW;
-      if e_KeyPressed(KeyPrevWeapon) then kByte := kByte or NET_KEY_PW;
-    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 := I;
+    end;
+    // fix movebutton state
+    P1MoveButton := P1MoveButton or (strafeDir shl 4);
+  end
   else
     kByte := NET_KEY_CHAT;
 
@@ -2828,6 +2867,7 @@ begin
   e_Buffer_Write(@NetOut, gTime);
   e_Buffer_Write(@NetOut, kByte);
   e_Buffer_Write(@NetOut, Byte(gPlayer1.Direction));
+  e_Buffer_Write(@NetOut, WeaponSelect);
   g_Net_Client_Send(True, NET_CHAN_PLAYERPOS);
 
   //kBytePrev := kByte;