fixed network games, part 1: separate locally and network connected players
authorHolger Schemel <info@artsoft.org>
Fri, 18 May 2018 06:55:32 +0000 (08:55 +0200)
committerHolger Schemel <info@artsoft.org>
Fri, 18 May 2018 06:55:32 +0000 (08:55 +0200)
Network games were largely broken since (at least) version 3.2.4
(although they still worked for the most common cases, but only for the
first game after starting the program). They will be fixed in several
separate steps.

This first part separates storing if a team-mode player was connected
locally or over the network (and then sets the previously used general
flag if a certain player is "connected" or not, regardless of being
connected locally or remotely).

src/game.c
src/game.h
src/init.c
src/network.c

index 6d07ec5489b05a0a8cec073449b8bd2af0e6eed3..a17dc326f05e0a3a97c9490cb0fd39024c0982bb 100644 (file)
@@ -1731,7 +1731,7 @@ static void InitPlayerField(int x, int y, int element, boolean init_game)
     if (game.use_block_last_field_bug)
       player->block_delay_adjustment = (player->block_last_field ? -1 : 1);
 
-    if (!options.network || player->connected)
+    if (!options.network || player->connected_network)
     {
       player->active = TRUE;
 
@@ -3684,22 +3684,33 @@ void InitGame()
       game.belt_dir_nr[i] = 3;         /* not moving, next moving left */
 
 #if USE_NEW_PLAYER_ASSIGNMENTS
-  /* !!! SAME AS init.c:InitPlayerInfo() -- FIX THIS !!! */
-  /* choose default local player */
-  local_player = &stored_player[0];
-
   for (i = 0; i < MAX_PLAYERS; i++)
+  {
     stored_player[i].connected = FALSE;
 
-  local_player->connected = TRUE;
-  /* !!! SAME AS init.c:InitPlayerInfo() -- FIX THIS !!! */
+    /* in network game mode, the local player might not be the first player */
+    if (stored_player[i].connected_locally)
+      local_player = &stored_player[i];
+  }
+
+  if (!options.network)
+    local_player->connected = TRUE;
 
   if (tape.playing)
   {
     for (i = 0; i < MAX_PLAYERS; i++)
       stored_player[i].connected = tape.player_participates[i];
   }
-  else if (game.team_mode && !options.network)
+  else if (options.network)
+  {
+    /* add team mode players connected over the network (needed for correct
+       assignment of player figures from level to locally playing players) */
+
+    for (i = 0; i < MAX_PLAYERS; i++)
+      if (stored_player[i].connected_network)
+       stored_player[i].connected = TRUE;
+  }
+  else if (game.team_mode)
   {
     /* try to guess locally connected team mode players (needed for correct
        assignment of player figures from level to locally playing players) */
index 93e1d0948fbd3de468f3ad1c870e48da4532106a..d65ebd9af24268b575bae380dbaa85d53777edbd 100644 (file)
@@ -225,6 +225,8 @@ struct GameInfo
 struct PlayerInfo
 {
   boolean present;             /* player present in level playfield */
+  boolean connected_locally;   /* player connected (locally) */
+  boolean connected_network;   /* player connected (network) */
   boolean connected;           /* player connected (locally or via network) */
   boolean active;              /* player present and connected */
   boolean mapped;              /* player already mapped to input device */
index 45f08cd69aac51c75b34b248260252107111dc1f..3e0f01dbaba6950025412f58e1539ed5320fb4c2 100644 (file)
@@ -5075,9 +5075,13 @@ static void InitPlayerInfo()
   local_player = &stored_player[0];
 
   for (i = 0; i < MAX_PLAYERS; i++)
-    stored_player[i].connected = FALSE;
+  {
+    stored_player[i].connected_locally = FALSE;
+    stored_player[i].connected_network = FALSE;
+  }
 
-  local_player->connected = TRUE;
+  local_player->connected_locally = TRUE;
+  local_player->connected_network = TRUE;
 }
 
 static void InitArtworkInfo()
index 56d6bc66226452bbdff72c886630fe425263f44b..afce79981a9061ab4ec0dc7ac1dba355966e9072 100644 (file)
@@ -275,11 +275,15 @@ static void Handle_OP_YOUR_NUMBER()
 
   if (old_local_player != new_local_player)
   {
-    /* copy existing player settings and change to new player */
+    /* set relevant player settings and change to new player */
 
-    *new_local_player = *old_local_player;
-    old_local_player->connected = FALSE;
     local_player = new_local_player;
+
+    old_local_player->connected_locally = FALSE;
+    new_local_player->connected_locally = TRUE;
+
+    old_local_player->connected_network = FALSE;
+    new_local_player->connected_network = TRUE;
   }
 
   if (first_player.nr > MAX_PLAYERS)
@@ -313,17 +317,22 @@ static void Handle_OP_NUMBER_WANTED()
 
     if (old_client_nr != new_client_nr)
     {
-      /* copy existing player settings and change to new player */
+      /* set relevant player settings and change to new player */
 
-      *new_player = *old_player;
-      old_player->connected = FALSE;
+      old_player->connected_network = FALSE;
+      new_player->connected_network = TRUE;
     }
 
     player = getNetworkPlayer(old_client_nr);
     player->nr = new_client_nr;
 
     if (old_player == local_player)            /* local player switched */
+    {
       local_player = new_player;
+
+      old_player->connected_locally = FALSE;
+      new_player->connected_locally = TRUE;
+    }
   }
   else if (old_client_nr == first_player.nr)   /* failed -- local player? */
   {
@@ -375,13 +384,14 @@ static void Handle_OP_PLAYER_CONNECTED()
   player->name[0] = '\0';
   player->next = NULL;
 
-  stored_player[new_index_nr].connected = TRUE;
+  stored_player[new_index_nr].connected_network = TRUE;
 }
 
 static void Handle_OP_PLAYER_DISCONNECTED()
 {
   struct NetworkClientPlayerInfo *player, *player_disconnected;
   int player_nr = (int)buffer[0];
+  int index_nr = player_nr - 1;
 
   printf("OP_PLAYER_DISCONNECTED: %d\n", player_nr);
   player_disconnected = getNetworkPlayer(player_nr);
@@ -392,6 +402,9 @@ static void Handle_OP_PLAYER_DISCONNECTED()
     if (player->next == player_disconnected)
       player->next = player_disconnected->next;
   free(player_disconnected);
+
+  stored_player[index_nr].connected_locally = FALSE;
+  stored_player[index_nr].connected_network = FALSE;
 }
 
 static void Handle_OP_START_PLAYING()