<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40444 >

> [EMAIL PROTECTED] - Sat Aug 16 23:48:11 2008]:
> 
> It makes sense that simultaneous phases be provided with an option to
> have team members simulate their turns at the same time.  At
> present, this is not an option, even when simultaneousphases is set
> to 0, this option is not allowed.
> When I tried this with 2 players v. 2 players, the simultaneousphases
> = 0 option permitted only one player to move at a time, while it
> enabled all other players to set movements without moving; the
> simultaneousphases = 1 option did what it is expected to do, to
> allow all players to move at the same time.
> My proposal is to allow a third option (simultaneousphases = 2 ?) to
> allow team players to move at the same time.

Attached patch extends the simultaneousphases setting to
allow team-alternating movement phases.


----------------------------------------------------------------------
多い人と一緒にやった方が楽しいね。
 client/packhand.c  |    6 +++++-
 client/text.c      |    9 ++++++++-
 common/game.c      |   19 ++++++++++++++++++-
 common/game.h      |   14 ++++++++++++--
 common/packets.def |    2 +-
 server/savegame.c  |   16 ++++++++--------
 server/settings.c  |   39 ++++++++++++++++++++++++++++++++-------
 server/srv_main.c  |   15 ++++++++++++---
 8 files changed, 96 insertions(+), 24 deletions(-)

diff --git a/client/packhand.c b/client/packhand.c
index 41940b3..f7650a4 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.simultaneous_phases == SPT_PLAYERS_ALTERNATE
+          && phase >= player_count())
+      || (game.info.simultaneous_phases == SPT_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 c2e243d..9308aa2 100644
--- a/client/text.c
+++ b/client/text.c
@@ -618,13 +618,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.simultaneous_phases == SPT_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.simultaneous_phases == SPT_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..54df17d 100644
--- a/common/game.c
+++ b/common/game.c
@@ -615,10 +615,27 @@ void game_renumber_players(int plrno)
 
 /**************************************************************************
   Return TRUE if it is this player's phase.
+  NB: Meaning of 'phase' argument must match its use in begin_turn().
 **************************************************************************/
 bool is_player_phase(const struct player *pplayer, int phase)
 {
-  return game.info.simultaneous_phases || player_number(pplayer) == phase;
+  switch (game.info.simultaneous_phases) {
+  case SPT_CONCURRENT:
+    return TRUE;
+    break;
+  case SPT_PLAYERS_ALTERNATE:
+    return player_number(pplayer) == phase;
+    break;
+  case SPT_TEAMS_ALTERNATE:
+    assert(pplayer->team != NULL);
+    return team_number(pplayer->team) == phase;
+    break;
+  default:
+    break;
+  }
+
+  assert(FALSE);
+  return TRUE;
 }
 
 /****************************************************************************
diff --git a/common/game.h b/common/game.h
index c397fa0..caba5b4 100644
--- a/common/game.h
+++ b/common/game.h
@@ -32,6 +32,14 @@ enum debug_globals {
   DEBUG_LAST
 };
 
+/* NB: Must match simultaneousphases setting
+ * help text in server/settings.c */
+enum simultaneous_phase_types {
+  SPT_PLAYERS_ALTERNATE = 0,
+  SPT_CONCURRENT = 1,
+  SPT_TEAMS_ALTERNATE = 2
+};
+
 #define CONTAMINATION_POLLUTION 1
 #define CONTAMINATION_FALLOUT   2
 
@@ -58,7 +66,7 @@ struct civ_game {
   /* The .info.simultaneous_phases 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 simultaneous_phases_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_SIMULTANEOUS_PHASES 1
+#define GAME_MIN_SIMULTANEOUS_PHASES 0
+#define GAME_MAX_SIMULTANEOUS_PHASES 2
 
 #define GAME_DEFAULT_TCPTIMEOUT      10
 #define GAME_MIN_TCPTIMEOUT          0
diff --git a/common/packets.def b/common/packets.def
index 84a8965..408f1ea 100644
--- a/common/packets.def
+++ b/common/packets.def
@@ -375,7 +375,7 @@ PACKET_GAME_INFO=15; sc
   PHASE phase;
   YEAR year, end_year;
 
-  BOOL simultaneous_phases;
+  UINT8 simultaneous_phases;
   UINT32 num_phases;
 
   PLAYER min_players;
diff --git a/server/savegame.c b/server/savegame.c
index 94d499a..a96d6ad 100644
--- a/server/savegame.c
+++ b/server/savegame.c
@@ -3930,11 +3930,11 @@ static void game_load_internal(struct section_file *file)
       game.info.turn = -2;
     }
     game.info.simultaneous_phases
-      = secfile_lookup_bool_default(file, TRUE,
-				    "game.simultaneous_phases_now");
+      = secfile_lookup_int_default(file, GAME_DEFAULT_SIMULTANEOUS_PHASES,
+                                   "game.simultaneous_phases_now");
     game.simultaneous_phases_stored
-      = secfile_lookup_bool_default(file, TRUE,
-				    "game.simultaneous_phases_stored");
+      = secfile_lookup_int_default(file, GAME_DEFAULT_SIMULTANEOUS_PHASES,
+                                   "game.simultaneous_phases_stored");
 
     game.info.min_players   = secfile_lookup_int(file, "game.min_players");
     game.info.max_players   = secfile_lookup_int(file, "game.max_players");
@@ -4614,10 +4614,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.simultaneous_phases,
+                     "game.simultaneous_phases_now");
+  secfile_insert_int(file, game.simultaneous_phases_stored,
+                     "game.simultaneous_phases_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..d40ee2d 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.
+*************************************************************************/
+static bool simultaneousphases_callback(int value,
+                                        const char **error_string)
+{
+  if (value == SPT_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,19 @@ 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)
+  /* NB: The values must match enum simultaneous_phase_types in
+   * common/game.h */
+  GEN_INT("simultaneousphases", game.simultaneous_phases_stored,
+	  SSET_META, SSET_INTERNAL, SSET_SITUATIONAL, SSET_TO_CLIENT,
+	  N_("Whether to have simultaneous player/team phases."),
+	  N_("This setting controls whether players may make "
+             "moves at the same time during a turn.\n\n"
+             "0 - All players alternate movement.\n"
+             "1 - All players move concurrently.\n"
+             "2 - Only players on the same team move concurrently, "
+             "teams as a whole alternate movement."),
+          simultaneousphases_callback, GAME_MIN_SIMULTANEOUS_PHASES,
+          GAME_MAX_SIMULTANEOUS_PHASES, GAME_DEFAULT_SIMULTANEOUS_PHASES)
 
   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 4ea8dc3..eeea194 100644
--- a/server/srv_main.c
+++ b/server/srv_main.c
@@ -605,10 +605,19 @@ static void begin_turn(bool is_new_turn)
   if (is_new_turn) {
     game.info.simultaneous_phases = game.simultaneous_phases_stored;
   }
-  if (game.info.simultaneous_phases) {
+  switch (game.info.simultaneous_phases) {
+  case SPT_CONCURRENT:
     game.info.num_phases = 1;
-  } else {
+    break;
+  case SPT_PLAYERS_ALTERNATE:
     game.info.num_phases = game.info.nplayers;
+    break;
+  case SPT_TEAMS_ALTERNATE:
+    game.info.num_phases = team_count();
+    break;
+  default:
+    assert(FALSE);
+    break;
   }
   send_game_info(NULL);
 
@@ -648,7 +657,7 @@ static void begin_turn(bool is_new_turn)
     }
   }
 
-  if (is_new_turn && game.info.simultaneous_phases) {
+  if (is_new_turn && game.info.simultaneous_phases == SPT_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