<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

Reply via email to