Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2005:
[Freeciv-Dev] (PR#13184) unreadiness in pregame
Home

[Freeciv-Dev] (PR#13184) unreadiness in pregame

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#13184) unreadiness in pregame
From: "Jason Dorje Short" <jdorje@xxxxxxxxx>
Date: Sat, 28 May 2005 12:50:46 -0700
Reply-to: bugs@xxxxxxxxxxx

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

This patch greatly improves the behavior of the ready/not-ready
condition for players.

1.  Just as a cleanup, pplayer->is_started is renamed as pplayer->is_ready.

2.  If you click on the ready field in the pregame player dialog for
yourself it toggles your readiness (later it may be allowed to toggle
other players' readiness, as you can change their nations).

3.  The "Start" button in the pregame dialog renames itself as needed:

  - "Ready" if clicking it will just change you to ready.
  - "Start" if you are the only unready player and clicking it will
    immediately begin the game.
  - "Not Ready" if you are currently ready; clicking it will unready
    you.

4.  As a helper for #3, a new function gtk_stockbutton_set_label is written.

A screenshot won't really help here.  You have to try it out to see it
in action.  The only issue I can see is that the "%d out of %d players
are ready" message is only printed when your readiness is turned on.
This message is not really needed anymore for the GTK client but is
still useful for other clients.

-jason

Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.518
diff -u -r1.518 packhand.c
--- client/packhand.c   22 May 2005 17:48:10 -0000      1.518
+++ client/packhand.c   28 May 2005 19:50:23 -0000
@@ -1500,7 +1500,7 @@
     city_report_dialog_update();
   }
 
-  pplayer->is_started = pinfo->is_started;
+  pplayer->is_ready = pinfo->is_ready;
 
   if (pplayer == game.player_ptr
       && pplayer->phase_done != pinfo->phase_done) {
Index: client/gui-gtk-2.0/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gui_main.c,v
retrieving revision 1.126
diff -u -r1.126 gui_main.c
--- client/gui-gtk-2.0/gui_main.c       26 May 2005 15:06:01 -0000      1.126
+++ client/gui-gtk-2.0/gui_main.c       28 May 2005 19:50:24 -0000
@@ -1223,9 +1223,32 @@
 void update_conn_list_dialog(void)
 {
   GtkTreeIter it;
+  char *text;
+
+  if (game.player_ptr->is_ready) {
+    text = _("Not _ready");
+  } else {
+    int num_unready = 0;
+
+    players_iterate(pplayer) {
+      if (!pplayer->ai.control && !pplayer->is_ready) {
+       num_unready++;
+      }
+    } players_iterate_end;
+
+    if (num_unready > 1) {
+      text = _("_Ready");
+    } else {
+      /* We are the last unready player so clicking here will
+       * immediately start the game. */
+      text = _("_Start");
+    }
+  }
+
+  gtk_stockbutton_set_label(ready_button, text);
   
   if (get_client_state() != CLIENT_GAME_RUNNING_STATE) {
-    bool is_started;
+    bool is_ready;
     const char *name, *nation, *leader;
 
     gtk_list_store_clear(conn_model);
@@ -1238,7 +1261,7 @@
       } else {
        name = pplayer->username;
       }
-      is_started = pplayer->ai.control ? TRUE: pplayer->is_started;
+      is_ready = pplayer->ai.control ? TRUE: pplayer->is_ready;
       if (pplayer->nation == NO_NATION_SELECTED) {
        nation = _("Random");
        leader = "";
@@ -1250,7 +1273,7 @@
       gtk_list_store_append(conn_model, &it);
       gtk_list_store_set(conn_model, &it,
                         0, name,
-                        1, is_started,
+                        1, is_ready,
                         2, leader,
                         3, nation,
                         4, pplayer->player_no,
@@ -1261,14 +1284,14 @@
        continue; /* Already listed above. */
       }
       name = pconn->username;
-      is_started = FALSE;
+      is_ready = FALSE;
       nation = "";
       leader = "";
 
       gtk_list_store_append(conn_model, &it);
       gtk_list_store_set(conn_model, &it,
                         0, name,
-                        1, is_started,
+                        1, is_ready,
                         2, leader,
                         3, nation,
                         4, -1,
Index: client/gui-gtk-2.0/gui_stuff.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gui_stuff.c,v
retrieving revision 1.23
diff -u -r1.23 gui_stuff.c
--- client/gui-gtk-2.0/gui_stuff.c      14 May 2005 22:49:02 -0000      1.23
+++ client/gui-gtk-2.0/gui_stuff.c      28 May 2005 19:50:24 -0000
@@ -78,8 +78,11 @@
 
   label = gtk_label_new_with_mnemonic(label_text);
   gtk_label_set_mnemonic_widget(GTK_LABEL(label), button);
+  g_object_set_data(G_OBJECT(button), "label", label);
 
   image = gtk_image_new_from_stock(stock, GTK_ICON_SIZE_BUTTON);
+  g_object_set_data(G_OBJECT(button), "image", image);
+
   hbox = gtk_hbox_new(FALSE, 2);
 
   align = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
@@ -94,6 +97,18 @@
 }
 
 /**************************************************************************
+  Changes the lable (with mnemonic) on an existing stockbutton.  See
+  gtk_stockbutton_new.
+**************************************************************************/
+void gtk_stockbutton_set_label(GtkWidget *button, const gchar *label_text)
+{
+  GtkWidget *label;
+
+  label = g_object_get_data(G_OBJECT(button), "label");
+  gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), label_text);
+}
+
+/**************************************************************************
   Returns gettext-converted list of n strings.  The individual strings
   in the list are as returned by gettext().  In case of no NLS, the strings
   will be the original strings, so caller should ensure that the originals
Index: client/gui-gtk-2.0/gui_stuff.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gui_stuff.h,v
retrieving revision 1.13
diff -u -r1.13 gui_stuff.h
--- client/gui-gtk-2.0/gui_stuff.h      10 Apr 2005 03:31:23 -0000      1.13
+++ client/gui-gtk-2.0/gui_stuff.h      28 May 2005 19:50:24 -0000
@@ -18,6 +18,7 @@
 #include "shared.h"
 
 GtkWidget *gtk_stockbutton_new(const gchar *stock, const gchar *label_text);
+void gtk_stockbutton_set_label(GtkWidget *button, const gchar *label_text);
 void gtk_expose_now(GtkWidget *w);
 void gtk_set_relative_position(GtkWidget *ref, GtkWidget *w, int px, int py);
 
Index: client/gui-gtk-2.0/pages.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/pages.c,v
retrieving revision 1.30
diff -u -r1.30 pages.c
--- client/gui-gtk-2.0/pages.c  26 May 2005 15:06:01 -0000      1.30
+++ client/gui-gtk-2.0/pages.c  28 May 2005 19:50:24 -0000
@@ -49,9 +49,10 @@
 GtkWidget *start_message_area;
 
 GtkListStore *conn_model;
-GtkTreeViewColumn *nation_col;
+static GtkTreeViewColumn *nation_col, *ready_col;
 
 static GtkWidget *start_options_table;
+GtkWidget *ready_button;
 
 static GtkListStore *load_store, *scenario_store,
   *nation_store, *meta_store, *lan_store; 
@@ -928,7 +929,8 @@
 static void start_start_callback(GtkWidget *w, gpointer data)
 {
   really_close_connection_dialog();
-  send_chat("/start");
+  dsend_packet_player_ready(&aconnection, game.info.player_idx,
+                           !game.player_ptr->is_ready);
 }
 
 /**************************************************************************
@@ -969,20 +971,31 @@
     return FALSE;
   }
 
-  if (column != nation_col) {
-    return show_conn_popup(widget, event, data);
-  }
-
   gtk_tree_model_get_iter(model, &iter, path);
   gtk_tree_path_free(path);
   gtk_tree_model_get(model, &iter, 4, &player_no, -1);
   pplayer = get_player(player_no);
-  if (!pplayer) {
-    return FALSE;
-  }
 
-  popup_races_dialog(pplayer);
-  return TRUE;
+  if (column == nation_col) {
+    if (!pplayer) {
+      return FALSE;
+    }
+
+    popup_races_dialog(pplayer);
+    return TRUE;
+  } else if (column == ready_col) {
+    gboolean is_ready;
+
+    if (!pplayer) {
+      return FALSE;
+    }
+
+    gtk_tree_model_get(model, &iter, 1, &is_ready, -1);
+    dsend_packet_player_ready(&aconnection, pplayer->player_no, !is_ready);
+    return TRUE;
+  } else {
+    return show_conn_popup(widget, event, data);
+  }
 }
 
 /**************************************************************************
@@ -1098,9 +1111,10 @@
 
   /* FIXME: should change to always be minimum-width. */
   rend = gtk_cell_renderer_toggle_new();
-  gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
-                                             -1, _("Ready"), rend,
-                                             "active", 1, NULL);
+  ready_col = gtk_tree_view_column_new_with_attributes(_("Ready"),
+                                                      rend,
+                                                      "active", 1, NULL);
+  gtk_tree_view_insert_column(GTK_TREE_VIEW(view), ready_col, -1);
 
   rend = gtk_cell_renderer_text_new();
   gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
@@ -1166,10 +1180,10 @@
                   G_CALLBACK(pick_nation_callback), NULL);
   gtk_container_add(GTK_CONTAINER(bbox), button);
 
-  button = gtk_stockbutton_new(GTK_STOCK_EXECUTE, _("_Start"));
-  g_signal_connect(button, "clicked",
+  ready_button = gtk_stockbutton_new(GTK_STOCK_EXECUTE, _("_Ready"));
+  g_signal_connect(ready_button, "clicked",
       G_CALLBACK(start_start_callback), NULL);
-  gtk_container_add(GTK_CONTAINER(bbox), button);
+  gtk_container_add(GTK_CONTAINER(bbox), ready_button);
 
   return box;
 }
Index: client/gui-gtk-2.0/pages.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/pages.h,v
retrieving revision 1.3
diff -u -r1.3 pages.h
--- client/gui-gtk-2.0/pages.h  25 Mar 2005 10:20:49 -0000      1.3
+++ client/gui-gtk-2.0/pages.h  28 May 2005 19:50:24 -0000
@@ -20,6 +20,7 @@
 #include "pages_g.h"
 
 extern GtkWidget *start_message_area;
+extern GtkWidget *ready_button;
 
 GtkWidget *create_main_page(void);
 GtkWidget *create_start_page(void);
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.128
diff -u -r1.128 packets.def
--- common/packets.def  22 May 2005 18:05:06 -0000      1.128
+++ common/packets.def  28 May 2005 19:50:24 -0000
@@ -228,7 +228,7 @@
   Spaceship
   Ruleset
 
-The last used packet number is 116.
+The last used packet number is 117.
 ****************************************************/
 
 
@@ -295,6 +295,11 @@
   UINT8 city_style;
 end
 
+PACKET_PLAYER_READY=117;cs,dsend
+  PLAYER player_no;
+  BOOL is_ready;
+end
+
 PACKET_GAME_STATE=12;post-send,post-recv,sc,dsend,lsend
   UINT32 value;
 end
@@ -620,7 +625,7 @@
   UINT8 city_style;
   NATION nation;
   TEAM team;
-  BOOL is_started;
+  BOOL is_ready;
   BOOL phase_done;
   TURN nturns_idle;
   BOOL is_alive;
Index: common/player.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.c,v
retrieving revision 1.183
diff -u -r1.183 player.c
--- common/player.c     22 May 2005 17:48:11 -0000      1.183
+++ common/player.c     28 May 2005 19:50:24 -0000
@@ -108,7 +108,7 @@
   plr->is_male = TRUE;
   plr->nation = NO_NATION_SELECTED;
   plr->team = NULL;
-  plr->is_started = FALSE;
+  plr->is_ready = FALSE;
   plr->revolution_finishes = -1;
   plr->capital = FALSE;
   plr->units = unit_list_new();
Index: common/player.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
retrieving revision 1.154
diff -u -r1.154 player.h
--- common/player.h     22 May 2005 17:48:11 -0000      1.154
+++ common/player.h     28 May 2005 19:50:25 -0000
@@ -205,7 +205,7 @@
   int target_government;
   Nation_type_id nation;
   struct team *team;
-  bool is_started; /* Did the player click "start" yet? */
+  bool is_ready; /* Did the player click "start" yet? */
   bool phase_done;
   int nturns_idle;
   bool is_alive;
Index: server/plrhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v
retrieving revision 1.382
diff -u -r1.382 plrhand.c
--- server/plrhand.c    27 May 2005 08:21:11 -0000      1.382
+++ server/plrhand.c    28 May 2005 19:50:25 -0000
@@ -1455,7 +1455,7 @@
   packet->is_male=plr->is_male;
   packet->is_observer=plr->is_observer;
   packet->team = plr->team ? plr->team->index : -1;
-  packet->is_started = plr->is_started;
+  packet->is_ready = plr->is_ready;
   packet->city_style=plr->city_style;
 
   packet->is_alive=plr->is_alive;
@@ -1995,8 +1995,8 @@
     return;
   }
   players_iterate(pplayer) {
-    if (pplayer->is_started) {
-      pplayer->is_started = FALSE;
+    if (pplayer->is_ready) {
+      pplayer->is_ready = FALSE;
       send_player_info_c(pplayer, game.est_connections);
     }
   } players_iterate_end;
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.264
diff -u -r1.264 srv_main.c
--- server/srv_main.c   24 May 2005 16:45:39 -0000      1.264
+++ server/srv_main.c   28 May 2005 19:50:26 -0000
@@ -986,6 +986,7 @@
 
   if (server_state != RUN_GAME_STATE
       && type != PACKET_NATION_SELECT_REQ
+      && type != PACKET_PLAYER_READY
       && type != PACKET_CONN_PONG
       && type != PACKET_REPORT_REQ) {
     if (server_state == GAME_OVER_STATE) {
@@ -1017,7 +1018,13 @@
            type, conn_description(pconn));
   }
 
-  if (server_state == RUN_GAME_STATE) {
+  if (server_state == RUN_GAME_STATE
+      && type != PACKET_PLAYER_READY) {
+    /* HACK: the player-ready packet puts the server into RUN_GAME_STATE
+     * but doesn't actually start the game.  The game isn't started until
+     * the main loop is re-entered, so kill_dying_players would think
+     * all players are dead.  This should be solved by adding a new
+     * game state GAME_GENERATION_STATE. */
     kill_dying_players();
   }
 
@@ -1293,6 +1300,60 @@
   }
 }
 
+/****************************************************************************
+  Handle a player-ready packet.
+****************************************************************************/
+void handle_player_ready(struct player *requestor,
+                        int player_no,
+                        bool is_ready)
+{
+  struct player *pplayer = get_player(player_no);
+  bool old_ready;
+
+  if (server_state != PRE_GAME_STATE
+      || !pplayer) {
+    return;
+  }
+
+  if (pplayer != requestor) {
+    /* Currently you can only change your own readiness. */
+    return;
+  }
+
+  old_ready = pplayer->is_ready;
+  pplayer->is_ready = is_ready;
+  send_player_info(pplayer, NULL);
+
+  /* Note this is called even if the player has pressed /start once
+   * before.  This is a good thing given that no other code supports
+   * is_started yet.  For instance if a player leaves everyone left
+   * might have pressed /start already but the start won't happen
+   * until someone presses it again.  Also you can press start more
+   * than once to remind other people to start (which is a good thing
+   * until somebody does it too much and it gets labeled as spam). */
+  if (is_ready) {
+    int num_ready = 0, num_unready = 0;
+
+    players_iterate(pplayer) {
+      if (pplayer->is_connected) {
+       if (pplayer->is_ready) {
+         num_ready++;
+       } else {
+         num_unready++;
+       }
+      }
+    } players_iterate_end;
+    if (num_unready > 0) {
+      notify_player(NULL, _("Waiting to start game: %d out of %d players "
+                           "are ready to start."),
+                   num_ready, num_ready + num_unready);
+    } else {
+      notify_player(NULL, _("All players are ready; starting game."));
+      start_game();
+    }
+  }
+}
+
 /**************************************************************************
   Returns how much two nations looks good in the same game
 **************************************************************************/
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.414
diff -u -r1.414 stdinhand.c
--- server/stdinhand.c  26 May 2005 04:49:38 -0000      1.414
+++ server/stdinhand.c  28 May 2005 19:50:26 -0000
@@ -3607,34 +3607,7 @@
       /* A detached or observer player can't do /start. */
       return TRUE;
     } else {
-      int started = 0, notstarted = 0;
-
-      /* Note this is called even if the player has pressed /start once
-       * before.  This is a good thing given that no other code supports
-       * is_started yet.  For instance if a player leaves everyone left
-       * might have pressed /start already but the start won't happen
-       * until someone presses it again.  Also you can press start more
-       * than once to remind other people to start (which is a good thing
-       * until somebody does it too much and it gets labeled as spam). */
-      caller->player->is_started = TRUE;
-      send_player_info(caller->player, NULL);
-      players_iterate(pplayer) {
-       if (pplayer->is_connected) {
-         if (pplayer->is_started) {
-           started++;
-         } else {
-           notstarted++;
-         }
-       }
-      } players_iterate_end;
-      if (notstarted > 0) {
-       notify_player(NULL, _("Waiting to start game: %d out of %d players "
-                             "are ready to start."),
-                     started, started + notstarted);
-       return TRUE;
-      }
-      notify_player(NULL, _("All players are ready; starting game."));
-      start_game();
+      handle_player_ready(caller->player, caller->player->player_no, TRUE);
       return TRUE;
     }
   case GAME_OVER_STATE:
@@ -3999,7 +3972,7 @@
       cat_snprintf(buf2, sizeof(buf2), _(", team %s"),
                   pplayer->team->name);
       if (server_state == PRE_GAME_STATE && pplayer->is_connected) {
-       if (pplayer->is_started) {
+       if (pplayer->is_ready) {
          cat_snprintf(buf2, sizeof(buf2), _(", ready"));
        } else {
          cat_snprintf(buf2, sizeof(buf2), _(", not ready"));

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#13184) unreadiness in pregame, Jason Dorje Short <=