<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40444 >
> [EMAIL PROTECTED] - Thu Aug 28 01:31:34 2008]: > > 2008/8/28 Madeline Book: > > Version 3 remains compatible with pre 2.2 savegames by > > checking for the presence of the old settings in the > > secfile. > > It's generally not a good idea to rely on version number for checking > savegame options. It should be possible to use values really present > in savegame in the lines of: > > old = look_bool_default(TRUE...) > if (old) > new_default = 1 > else > new_default = 1 > final = look_int_default(new_default...) > > Failing that, you should use savegame options. > > In any case your check against 020200 means that current S2_2 > development version 2.1.99 is not reading new values. Version 4 fixes this inaccuracy and improves comments. ---------------------------------------------------------------------- それはどうも
client/packhand.c | 6 +++++- client/text.c | 9 ++++++++- common/game.c | 26 ++++++++++++++++++++++++-- common/game.h | 16 +++++++++++++--- common/packets.def | 2 +- server/savegame.c | 43 +++++++++++++++++++++++++++++++++---------- server/settings.c | 38 +++++++++++++++++++++++++++++++------- server/srv_main.c | 21 +++++++++++++++++---- 8 files changed, 132 insertions(+), 29 deletions(-) diff --git a/client/packhand.c b/client/packhand.c index 60c980b..cfc1339 100644 --- a/client/packhand.c +++ b/client/packhand.c @@ -1011,7 +1011,11 @@ void handle_end_phase(void) void handle_start_phase(int phase) { - if (phase < 0 || phase >= player_count()) { + if (phase < 0 + || (game.info.phase_mode == PMT_PLAYERS_ALTERNATE + && phase >= player_count()) + || (game.info.phase_mode == PMT_TEAMS_ALTERNATE + && phase >= team_count())) { freelog(LOG_ERROR, "handle_start_phase() illegal phase %d.", phase); diff --git a/client/text.c b/client/text.c index 1137b75..23daf69 100644 --- a/client/text.c +++ b/client/text.c @@ -616,13 +616,20 @@ const char *get_info_label_text(void) client.conn.playing->economic.luxury, client.conn.playing->economic.science); } - if (!game.info.simultaneous_phases) { + if (game.info.phase_mode == PMT_PLAYERS_ALTERNATE) { if (game.info.phase < 0 || game.info.phase >= game.info.nplayers) { astr_add_line(&str, _("Moving: Nobody")); } else { astr_add_line(&str, _("Moving: %s"), player_name(player_by_number(game.info.phase))); } + } else if (game.info.phase_mode == PMT_TEAMS_ALTERNATE) { + if (game.info.phase < 0 || game.info.phase >= team_count()) { + astr_add_line(&str, _("Moving: Nobody")); + } else { + astr_add_line(&str, _("Moving: %s"), + team_name_translation(team_by_number(game.info.phase))); + } } astr_add_line(&str, _("(Click for more info)")); return str.str; diff --git a/common/game.c b/common/game.c index fcd4868..bf0508f 100644 --- a/common/game.c +++ b/common/game.c @@ -319,7 +319,7 @@ void game_init(void) sz_strlcpy(game.info.start_units, GAME_DEFAULT_START_UNITS); game.fogofwar_old = game.info.fogofwar; - game.simultaneous_phases_stored = GAME_DEFAULT_SIMULTANEOUS_PHASES; + game.phase_mode_stored = GAME_DEFAULT_PHASE_MODE; game.timeoutint = GAME_DEFAULT_TIMEOUTINT; game.timeoutintinc = GAME_DEFAULT_TIMEOUTINTINC; game.timeoutinc = GAME_DEFAULT_TIMEOUTINC; @@ -615,10 +615,32 @@ void game_renumber_players(int plrno) /************************************************************************** Return TRUE if it is this player's phase. + NB: The meaning of the 'phase' argument must match its use in the + function begin_turn() in server/srv_main.c. + NB: The phase mode PMT_TEAMS_ALTERNATE assumes that every player is + on a team, i.e. that pplayer->team is never NULL. **************************************************************************/ bool is_player_phase(const struct player *pplayer, int phase) { - return game.info.simultaneous_phases || player_number(pplayer) == phase; + switch (game.info.phase_mode) { + case PMT_CONCURRENT: + return TRUE; + break; + case PMT_PLAYERS_ALTERNATE: + return player_number(pplayer) == phase; + break; + case PMT_TEAMS_ALTERNATE: + assert(pplayer->team != NULL); + return team_number(pplayer->team) == phase; + break; + default: + break; + } + + freelog(LOG_FATAL, "Unrecognized phase mode %d in is_player_phase().", + phase); + assert(FALSE); + return TRUE; } /**************************************************************************** diff --git a/common/game.h b/common/game.h index c397fa0..ba18102 100644 --- a/common/game.h +++ b/common/game.h @@ -32,6 +32,14 @@ enum debug_globals { DEBUG_LAST }; +/* NB: Must match phasemode setting + * help text in server/settings.c */ +enum phase_mode_types { + PMT_CONCURRENT = 0, + PMT_PLAYERS_ALTERNATE = 1, + PMT_TEAMS_ALTERNATE = 2 +}; + #define CONTAMINATION_POLLUTION 1 #define CONTAMINATION_FALLOUT 2 @@ -55,10 +63,10 @@ struct civ_game { time_t last_ping; struct timer *phase_timer; /* Time since seconds_to_phase_done was set. */ - /* The .info.simultaneous_phases value indicates the phase mode currently in + /* The .info.phase_mode value indicates the phase mode currently in * use. The "stored" value is a value the player can change; it won't * take effect until the next turn. */ - bool simultaneous_phases_stored; + int phase_mode_stored; char *startmessage; struct player players[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS]; struct conn_list *all_connections; /* including not yet established */ @@ -275,7 +283,9 @@ bool setting_class_is_changeable(enum sset_class class); #define GAME_MIN_TIMEOUT -1 #define GAME_MAX_TIMEOUT 8639999 -#define GAME_DEFAULT_SIMULTANEOUS_PHASES TRUE +#define GAME_DEFAULT_PHASE_MODE 0 +#define GAME_MIN_PHASE_MODE 0 +#define GAME_MAX_PHASE_MODE 2 #define GAME_DEFAULT_TCPTIMEOUT 10 #define GAME_MIN_TCPTIMEOUT 0 diff --git a/common/packets.def b/common/packets.def index accc06e..b47d8ab 100644 --- a/common/packets.def +++ b/common/packets.def @@ -377,7 +377,7 @@ PACKET_GAME_INFO=15; sc PHASE phase; YEAR year, end_year; - BOOL simultaneous_phases; + UINT8 phase_mode; UINT32 num_phases; PLAYER min_players; diff --git a/server/savegame.c b/server/savegame.c index a478a03..2e65b3b 100644 --- a/server/savegame.c +++ b/server/savegame.c @@ -4100,12 +4100,35 @@ static void game_load_internal(struct section_file *file) } else { game.info.turn = -2; } - game.info.simultaneous_phases - = secfile_lookup_bool_default(file, TRUE, - "game.simultaneous_phases_now"); - game.simultaneous_phases_stored - = secfile_lookup_bool_default(file, TRUE, - "game.simultaneous_phases_stored"); + + if (section_file_lookup(file, "game.simultaneous_phases_now")) { + bool sp_now; + + sp_now = secfile_lookup_bool(file, "game.simultaneous_phases_now"); + game.info.phase_mode = (sp_now ? PMT_CONCURRENT + : PMT_PLAYERS_ALTERNATE); + + } else { + game.info.phase_mode = GAME_DEFAULT_PHASE_MODE; + } + + if (section_file_lookup(file, "game.simultaneous_phases_stored")) { + bool sp_stored; + + sp_stored + = secfile_lookup_bool(file, "game.simultaneous_phases_stored"); + game.phase_mode_stored = (sp_stored ? PMT_CONCURRENT + : PMT_PLAYERS_ALTERNATE); + } else { + game.phase_mode_stored = game.info.phase_mode; + } + + game.info.phase_mode + = secfile_lookup_int_default(file, game.info.phase_mode, + "game.phase_mode"); + game.phase_mode_stored + = secfile_lookup_int_default(file, game.phase_mode_stored, + "game.phase_mode_stored"); game.info.min_players = secfile_lookup_int(file, "game.min_players"); game.info.max_players = secfile_lookup_int(file, "game.max_players"); @@ -4813,10 +4836,10 @@ void game_save(struct section_file *file, const char *save_reason) secfile_insert_int(file, game.info.end_year, "game.end_year"); secfile_insert_int(file, game.info.year, "game.year"); secfile_insert_int(file, game.info.turn, "game.turn"); - secfile_insert_bool(file, game.info.simultaneous_phases, - "game.simultaneous_phases_now"); - secfile_insert_bool(file, game.simultaneous_phases_stored, - "game.simultaneous_phases_stored"); + secfile_insert_int(file, game.info.phase_mode, + "game.phase_mode"); + secfile_insert_int(file, game.phase_mode_stored, + "game.phase_mode_stored"); secfile_insert_int(file, game.info.min_players, "game.min_players"); secfile_insert_int(file, game.info.max_players, "game.max_players"); secfile_insert_int(file, game.info.nplayers, "game.nplayers"); diff --git a/server/settings.c b/server/settings.c index f06ccf1..8855003 100644 --- a/server/settings.c +++ b/server/settings.c @@ -197,6 +197,25 @@ static bool aifill_callback(int value, const char **error_string) return TRUE; } +/************************************************************************* + Check that everyone is on a team for team-alternating simultaneous + phases. NB: Assumes that it is not possible to first set team + alternating phase mode then make teamless players. +*************************************************************************/ +static bool phasemode_callback(int value, const char **error_string) +{ + if (value == PMT_TEAMS_ALTERNATE) { + players_iterate(pplayer) { + if (!pplayer->team) { + *error_string = _("All players must have a team if this option " + "value is used."); + return FALSE; + } + } players_iterate_end; + } + *error_string = NULL; + return TRUE; +} /************************************************************************/ #if defined(HAVE_LIBBZ2) @@ -908,13 +927,18 @@ struct settings_s settings[] = { /* This setting points to the "stored" value; changing it won't have * an effect until the next synchronization point (i.e., the start of * the next turn). */ - GEN_BOOL("simultaneousphases", game.simultaneous_phases_stored, - SSET_META, SSET_INTERNAL, SSET_SITUATIONAL, SSET_TO_CLIENT, - N_("Whether to have simultaneous player phases."), - N_("If true, all players' movement phases will occur " - "simultaneously; if false, then players will " - "alternate movement."), NULL, - GAME_DEFAULT_SIMULTANEOUS_PHASES) + GEN_INT("phasemode", game.phase_mode_stored, + SSET_META, SSET_INTERNAL, SSET_SITUATIONAL, SSET_TO_CLIENT, + N_("Whether to have simultaneous player/team phases."), + /* NB: The values must match enum phase_mode_types + * defined in common/game.h */ + N_("This setting controls whether players may make " + "moves at the same time during a turn.\n" + " 0 = All players move concurrently.\n" + " 1 = All players alternate movement.\n" + " 2 = Only players on the same team move concurrently."), + phasemode_callback, GAME_MIN_PHASE_MODE, + GAME_MAX_PHASE_MODE, GAME_DEFAULT_PHASE_MODE) GEN_INT("nettimeout", game.info.tcptimeout, SSET_META, SSET_NETWORK, SSET_RARE, SSET_TO_CLIENT, diff --git a/server/srv_main.c b/server/srv_main.c index 1fd4435..7e9f047 100644 --- a/server/srv_main.c +++ b/server/srv_main.c @@ -603,12 +603,25 @@ static void begin_turn(bool is_new_turn) /* Reset this each turn. */ if (is_new_turn) { - game.info.simultaneous_phases = game.simultaneous_phases_stored; + game.info.phase_mode = game.phase_mode_stored; } - if (game.info.simultaneous_phases) { + + /* NB: Phase logic must match is_player_phase(). */ + switch (game.info.phase_mode) { + case PMT_CONCURRENT: game.info.num_phases = 1; - } else { + break; + case PMT_PLAYERS_ALTERNATE: game.info.num_phases = game.info.nplayers; + break; + case PMT_TEAMS_ALTERNATE: + game.info.num_phases = team_count(); + break; + default: + freelog(LOG_FATAL, "Unrecognized phase mode %d in begin_turn().", + game.info.phase_mode); + assert(FALSE); + break; } send_game_info(NULL); @@ -648,7 +661,7 @@ static void begin_turn(bool is_new_turn) } } - if (is_new_turn && game.info.simultaneous_phases) { + if (is_new_turn && game.info.phase_mode == PMT_CONCURRENT) { freelog(LOG_DEBUG, "Shuffleplayers"); shuffle_players(); }
_______________________________________________ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev