From b8803f08af3cf07efed781124417be11c1a306ee Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Fri, 18 May 2018 08:55:32 +0200 Subject: [PATCH] fixed network games, part 1: separate locally and network connected players 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 | 27 +++++++++++++++++++-------- src/game.h | 2 ++ src/init.c | 8 ++++++-- src/network.c | 27 ++++++++++++++++++++------- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/game.c b/src/game.c index 6d07ec54..a17dc326 100644 --- a/src/game.c +++ b/src/game.c @@ -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) */ diff --git a/src/game.h b/src/game.h index 93e1d094..d65ebd9a 100644 --- a/src/game.h +++ b/src/game.h @@ -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 */ diff --git a/src/init.c b/src/init.c index 45f08cd6..3e0f01db 100644 --- a/src/init.c +++ b/src/init.c @@ -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() diff --git a/src/network.c b/src/network.c index 56d6bc66..afce7998 100644 --- a/src/network.c +++ b/src/network.c @@ -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() -- 2.34.1