diff -Nur -Xsnap/diff_ignore snap/client/civclient.c snap-take/client/civclient.c --- snap/client/civclient.c 2003-07-09 22:24:39.000000000 -0500 +++ snap-take/client/civclient.c 2003-07-13 22:34:38.000000000 -0500 @@ -203,6 +203,10 @@ /* initialization */ + conn_list_init(&game.all_connections); + conn_list_init(&game.est_connections); + conn_list_init(&game.game_connections); + ui_init(); my_init_network(); init_messages_where(); @@ -240,6 +244,7 @@ /* termination */ attribute_flush(); + client_remove_all_cli_conn(); my_shutdown_network(); client_game_free(); @@ -617,10 +622,6 @@ **************************************************************************/ void client_game_init() { - conn_list_init(&game.all_connections); - conn_list_init(&game.est_connections); - conn_list_init(&game.game_connections); - game_init(); attribute_init(); agents_init(); @@ -634,7 +635,6 @@ void client_game_free() { cm_free(); - client_remove_all_cli_conn(); free_client_goto(); free_help_texts(); attribute_free(); @@ -700,7 +700,7 @@ } update_menus(); } - if (client_state == CLIENT_PRE_GAME_STATE) { + if (!aconnection.established && client_state == CLIENT_PRE_GAME_STATE) { gui_server_connect(); if (auto_connect) { if (connect_error) { @@ -780,7 +780,7 @@ **************************************************************************/ bool client_is_observer(void) { - return aconnection.established && find_conn_by_id(game.conn_id)->observer; + return aconnection.established && aconnection.observer; } /************************************************************************** diff -Nur -Xsnap/diff_ignore snap/common/capstr.c snap-take/common/capstr.c --- snap/common/capstr.c 2003-07-11 16:36:00.000000000 -0500 +++ snap-take/common/capstr.c 2003-07-13 22:51:08.000000000 -0500 @@ -79,7 +79,7 @@ "+impr_req +waste +fastfocus +continent +small_dipl " \ "+no_nation_selected +diplomacy +no_extra_tiles " \ "+diplomacy2 +citizens_style +root_tech auth " \ - "+nat_ulimit " + "+nat_ulimit retake" /* "+1.14.0" is protocol for 1.14.0 release. * @@ -135,6 +135,8 @@ * * "nat_ulimit" means that the MAX_NUM_NATIONS limit has been removed, * allowing easy adding of arbitrarily many nations. + * + * "retake" means that a client can switch players during a running game. */ void init_our_capability(void) diff -Nur -Xsnap/diff_ignore snap/server/stdinhand.c snap-take/server/stdinhand.c --- snap/server/stdinhand.c 2003-07-13 22:00:16.000000000 -0500 +++ snap-take/server/stdinhand.c 2003-07-13 22:52:51.000000000 -0500 @@ -30,6 +30,7 @@ #endif #include "astring.h" +#include "capability.h" #include "events.h" #include "fcintl.h" #include "game.h" @@ -3121,16 +3122,6 @@ pconn = caller; } - /* If the connection controls a player and the game is running, don't - * let the user perform this command. The client isn't yet prepared - * for this kind of power ;) It'll segfault and/or do crazy things. */ - if (pconn->player && server_state == RUN_GAME_STATE) { - cmd_reply(CMD_TAKE, caller, C_FAIL, - _("You can't switch players with \"take\" " - "after the game has started.")); - goto end; - } - if (pconn->player == pplayer) { cmd_reply(CMD_TAKE, caller, C_FAIL, _("%s already controls or observes %s"), @@ -3149,6 +3140,18 @@ goto end; } conn_list_iterate_end; + /* if we want to switch players, reset the client */ + if (pconn->player && server_state == RUN_GAME_STATE) { + if (has_capability("retake", pconn->capability)) { + send_game_state(&pconn->self, CLIENT_PRE_GAME_STATE); + } else { + cmd_reply(CMD_TAKE, caller, C_FAIL, + _("You can't switch players with \"take\" " + "after the game has started.")); + goto end; + } + } + /* if the connection is already attached to a player, * unattach and cleanup old player (rename, remove, etc) */ if (pconn->player) {