Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2005:
[Freeciv-Dev] Re: (PR#13501) rewrite city options code
Home

[Freeciv-Dev] Re: (PR#13501) rewrite city options code

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] Re: (PR#13501) rewrite city options code
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 21 Jul 2005 10:27:40 -0700
Reply-to: bugs@xxxxxxxxxxx

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

Per I. Mathisen wrote:
> <URL: http://bugs.freeciv.org/Ticket/Display.html?id=13501 >
> 
> On Wed, 20 Jul 2005, Jason Short wrote:
> 
>>This patch rewrites and simplifies portions of the city options code.
>>
>>1.The city options are changed into a bitvector (BV) instead of an
>>integer bitfield.
> 
> -  UINT8 city_options;
> +  BOOL city_options[CITYO_LAST];
> 
> Why not transmit it as a bitvector type?

I didn't realize that was possible.

-jason

Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.535
diff -p -u -r1.535 packhand.c
--- client/packhand.c   20 Jul 2005 07:19:19 -0000      1.535
+++ client/packhand.c   21 Jul 2005 17:26:58 -0000
@@ -715,7 +715,7 @@ void handle_city_short_info(struct packe
     pcity->food_stock         = 0;
     pcity->shield_stock       = 0;
     pcity->pollution          = 0;
-    pcity->city_options       = 0;
+    BV_CLR_ALL(pcity->city_options);
     pcity->is_building_unit   = FALSE;
     pcity->currently_building = 0;
     init_worklist(&pcity->worklist);
Index: client/gui-gtk-2.0/citydlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/citydlg.c,v
retrieving revision 1.130
diff -p -u -r1.130 citydlg.c
--- client/gui-gtk-2.0/citydlg.c        4 Jul 2005 17:48:36 -0000       1.130
+++ client/gui-gtk-2.0/citydlg.c        21 Jul 2005 17:26:59 -0000
@@ -91,7 +91,6 @@ enum { OVERVIEW_PAGE, WORKLIST_PAGE,
 enum info_style { NORMAL, ORANGE, RED, NUM_INFO_STYLES };
 
 #define NUM_CITIZENS_SHOWN 25
-#define NUM_CITY_OPTS 5
 #define NUM_INFO_FIELDS 11      /* number of fields in city_info */
 #define NUM_PAGES 6             /* the number of pages in city dialog notebook 
                                  * (+1) if you change this, you must add an
@@ -153,7 +152,7 @@ struct city_dialog {
   struct {
     GtkWidget *rename_command;
     GtkWidget *new_citizens_radio[3];
-    GtkWidget *city_opts[NUM_CITY_OPTS];
+    GtkWidget *disband_on_settler;
     GtkWidget *whichtab_radio[NUM_PAGES];
     short block_signal;
   } misc;
@@ -1024,13 +1023,7 @@ static void create_and_append_settings_p
     N_("Taxmen")
   };
 
-  static const char *city_opts_label[NUM_CITY_OPTS] = {
-    N_("Land units"),
-    N_("Sea units"),
-    N_("Helicopters"),
-    N_("Air units"),
-    N_("Disband if build settler at size 1")
-  };
+  static const char *disband_label = N_("Disband if build settler at size 1");
 
   static const char *misc_whichtab_label[NUM_PAGES] = {
     N_("Overview page"),
@@ -1042,7 +1035,6 @@ static void create_and_append_settings_p
   };
 
   static bool new_citizens_label_done;
-  static bool city_opts_label_done;
   static bool misc_whichtab_label_done;
 
   /* initialize signal_blocker */
@@ -1083,24 +1075,6 @@ static void create_and_append_settings_p
                     G_CALLBACK(cityopt_callback), pdialog);
     group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
   }
-  
-  /* auto-attack table */
-  frame = gtk_frame_new(_("Auto attack vs"));
-  gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
-
-  intl_slist(ARRAY_SIZE(city_opts_label), city_opts_label,
-             &city_opts_label_done);
-
-  vbox2 = gtk_vbox_new(TRUE, 0);
-  gtk_container_add(GTK_CONTAINER(frame), vbox2);
-
-  for (i = 0; i < ARRAY_SIZE(city_opts_label) - 1; i++) {
-    button = gtk_check_button_new_with_mnemonic(city_opts_label[i]);
-    pdialog->misc.city_opts[i] = button;
-    gtk_container_add(GTK_CONTAINER(vbox2), button);
-    g_signal_connect(button, "toggled",
-                    G_CALLBACK(cityopt_callback), pdialog);
-  }
 
   /* next is the next-time-open radio group in the right column */
   frame = gtk_frame_new(_("Next time open"));
@@ -1141,8 +1115,8 @@ static void create_and_append_settings_p
   gtk_widget_set_sensitive(button, can_client_issue_orders());
   
   /* the disband-if-size-1 button */
-  button = 
gtk_check_button_new_with_mnemonic(city_opts_label[NUM_CITY_OPTS-1]);
-  pdialog->misc.city_opts[NUM_CITY_OPTS - 1] = button;
+  button = gtk_check_button_new_with_mnemonic(_(disband_label));
+  pdialog->misc.disband_on_settler = button;
   gtk_container_add(GTK_CONTAINER(vbox2), button);
   g_signal_connect(button, "toggled",
                   G_CALLBACK(cityopt_callback), pdialog);
@@ -2660,18 +2634,20 @@ static void cityopt_callback(GtkWidget *
   }
 
   if(!pdialog->misc.block_signal){
-    int i, new_options = 0;
     struct city *pcity = pdialog->pcity;
+    bv_city_options new_options;
 
-    for(i = 0; i < NUM_CITY_OPTS; i++){
-      if(GTK_TOGGLE_BUTTON(pdialog->misc.city_opts[i])->active)
-        new_options |= (1 << i);
-    }
+    assert(CITYO_LAST == 3);
 
+    BV_CLR_ALL(new_options);
+    if (GTK_TOGGLE_BUTTON(pdialog->misc.disband_on_settler)->active) {
+      BV_SET(new_options, CITYO_DISBAND);
+    }
     if (GTK_TOGGLE_BUTTON(pdialog->misc.new_citizens_radio[1])->active) {
-      new_options |= (1 << CITYO_NEW_EINSTEIN);
-    } else if(GTK_TOGGLE_BUTTON(pdialog->misc.new_citizens_radio[2])->active) {
-      new_options |= (1 << CITYO_NEW_TAXMAN);
+      BV_SET(new_options, CITYO_NEW_EINSTEIN);
+    }
+    if (GTK_TOGGLE_BUTTON(pdialog->misc.new_citizens_radio[2])->active) {
+      BV_SET(new_options, CITYO_NEW_TAXMAN);
     }
 
     dsend_packet_city_options_req(&aconnection, pcity->id,new_options);
@@ -2685,14 +2661,11 @@ static void cityopt_callback(GtkWidget *
 static void set_cityopt_values(struct city_dialog *pdialog)
 {
   struct city *pcity = pdialog->pcity;
-  int i;
 
   pdialog->misc.block_signal = 1;
-  for (i = 0; i < NUM_CITY_OPTS; i++) {
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
-                                (pdialog->misc.city_opts[i]),
-                                is_city_option_set(pcity, i));
-  }
+
+  
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pdialog->misc.disband_on_settler),
+                              is_city_option_set(pcity, CITYO_DISBAND));
 
   if (is_city_option_set(pcity, CITYO_NEW_EINSTEIN)) {
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
Index: common/capstr.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v
retrieving revision 1.260
diff -p -u -r1.260 capstr.c
--- common/capstr.c     3 Jul 2005 06:53:18 -0000       1.260
+++ common/capstr.c     21 Jul 2005 17:26:59 -0000
@@ -82,7 +82,7 @@ const char * const our_capability = our_
  *     as long as possible.  We want to maintain network compatibility with
  *     the stable branch for as long as possible.
  */
-#define CAPABILITY "+Freeciv.Devel.2005.Jul.03"
+#define CAPABILITY "+Freeciv.Devel.2005.Jul.20"
 
 void init_our_capability(void)
 {
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.354
diff -p -u -r1.354 city.c
--- common/city.c       14 Jul 2005 19:25:45 -0000      1.354
+++ common/city.c       21 Jul 2005 17:27:00 -0000
@@ -2318,7 +2318,7 @@ void get_worker_on_map_position(const st
 **************************************************************************/
 bool is_city_option_set(const struct city *pcity, enum city_options option)
 {
-  return TEST_BIT(pcity->city_options, option);
+  return BV_ISSET(pcity->city_options, option);
 }
 
 /**************************************************************************
@@ -2443,7 +2443,7 @@ struct city *create_city_virtual(struct 
   pcity->last_turns_shield_surplus = 0;
   pcity->anarchy = 0;
   pcity->rapture = 0;
-  pcity->city_options = CITYOPT_DEFAULT;
+  BV_CLR_ALL(pcity->city_options);
 
   pcity->server.workers_frozen = 0;
   pcity->server.needs_arrange = FALSE;
Index: common/city.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.h,v
retrieving revision 1.216
diff -p -u -r1.216 city.h
--- common/city.h       4 Jul 2005 17:48:37 -0000       1.216
+++ common/city.h       21 Jul 2005 17:27:00 -0000
@@ -26,31 +26,17 @@ enum city_tile_type {
   C_TILE_EMPTY, C_TILE_WORKER, C_TILE_UNAVAILABLE
 };
 
+/* Various city options.  These are stored by the server and can be
+ * toggled by the user.  Each one defaults to off.  Adding new ones
+ * will break network compatibility.  Reordering them will break savegame
+ * compatibility. */
 enum city_options {
-  /* The first 4 are whether to auto-attack versus each unit move_type
-   * from with auto-attack units within this city.  Note that these
-   * should stay the first four, and must stay in the same order as
-   * enum unit_move_type.  
-   *
-   * The next is whether building a settler at size 1 disbands a city.
-   *
-   * The following 2 are what to do of new citizens when the city grows:
-   * make them workers, scientists, or taxmen. Should have only one set,
-   * or if neither is set, that means make workers.
-   *
-   * Any more than 8 options requires a protocol extension, since
-   * we only send 8 bits.
-   */
-  CITYO_ATT_LAND=0, CITYO_ATT_SEA, CITYO_ATT_HELI, CITYO_ATT_AIR,
-  CITYO_DISBAND, CITYO_NEW_EINSTEIN, CITYO_NEW_TAXMAN
+  CITYO_DISBAND,      /* If building a settler at size 1 disbands the city */
+  CITYO_NEW_EINSTEIN, /* If new citizens are science specialists */
+  CITYO_NEW_TAXMAN,   /* If new citizens are gold specialists */
+  CITYO_LAST
 };
-
-/* first four bits are for auto-attack: */
-#define CITYOPT_AUTOATTACK_BITS 0xF
-
-/* for new city: default auto-attack options all on, others off: */
-#define CITYOPT_DEFAULT (CITYOPT_AUTOATTACK_BITS)
-
+BV_DEFINE(bv_city_options, CITYO_LAST);
 
 /* Changing this requires updating CITY_TILES and network capabilities. */
 #define CITY_MAP_RADIUS 2
@@ -291,7 +277,7 @@ struct city {
   bool was_happy;
   bool airlift;
   struct player *original;     /* original owner - cannot be NULL */
-  int city_options;            /* bitfield; positions as enum city_options */
+  bv_city_options city_options;
 
   /* server variable. indicates if the city map is synced with the client. */
   bool synced;
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.144
diff -p -u -r1.144 packets.def
--- common/packets.def  21 Jul 2005 08:33:36 -0000      1.144
+++ common/packets.def  21 Jul 2005 17:27:01 -0000
@@ -196,6 +196,7 @@ type BV_IMPRS               = bitvector(bv_imprs)
 type BV_FLAGS          = bitvector(bv_flags)
 type BV_ROLES          = bitvector(bv_roles)
 type BV_TERRAIN_FLAGS  = bitvector(bv_terrain_flags)
+type BV_CITY_OPTIONS    = bitvector(bv_city_options)
 type DIPLSTATE         = diplstate(struct player_diplstate)
 type VISION            = uint32(unsigned int)
 
@@ -528,7 +529,7 @@ PACKET_CITY_INFO=21; sc,lsend
 
   BOOL did_buy, did_sell, was_happy, airlift, diplomat_investigate;
 
-  UINT8 city_options;
+  BV_CITY_OPTIONS city_options;
   TURN turn_founded;
 end
 
@@ -588,7 +589,7 @@ end
 
 PACKET_CITY_OPTIONS_REQ=31;cs,dsend
   CITY city_id;
-  UINT8 value;
+  BV_CITY_OPTIONS options;
 end
 
 PACKET_CITY_REFRESH=32;cs,dsend
Index: server/cityhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/cityhand.c,v
retrieving revision 1.147
diff -p -u -r1.147 cityhand.c
--- server/cityhand.c   5 May 2005 18:32:52 -0000       1.147
+++ server/cityhand.c   21 Jul 2005 17:27:02 -0000
@@ -391,7 +391,8 @@ void handle_city_rename(struct player *p
 /**************************************************************************
 ...
 **************************************************************************/
-void handle_city_options_req(struct player *pplayer, int city_id, int value)
+void handle_city_options_req(struct player *pplayer, int city_id,
+                            bv_city_options options)
 {
   struct city *pcity = player_find_city_by_id(pplayer, city_id);
 
@@ -399,7 +400,8 @@ void handle_city_options_req(struct play
     return;
   }
 
-  pcity->city_options = value;
+  pcity->city_options = options;
+
   send_city_info(pplayer, pcity);
 }
 
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.335
diff -p -u -r1.335 citytools.c
--- server/citytools.c  18 Jul 2005 22:46:28 -0000      1.335
+++ server/citytools.c  21 Jul 2005 17:27:02 -0000
@@ -1564,8 +1564,7 @@ void package_city(struct city *pcity, st
   packet->food_stock=pcity->food_stock;
   packet->shield_stock=pcity->shield_stock;
   packet->pollution=pcity->pollution;
-
-  packet->city_options=pcity->city_options;
+  packet->city_options = pcity->city_options;
   
   packet->is_building_unit=pcity->is_building_unit;
   packet->currently_building=pcity->currently_building;
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.265
diff -p -u -r1.265 savegame.c
--- server/savegame.c   20 Jul 2005 18:28:48 -0000      1.265
+++ server/savegame.c   21 Jul 2005 17:27:03 -0000
@@ -2237,9 +2237,16 @@ static void player_load(struct player *p
     pcity->airlift = secfile_lookup_bool_default(file, FALSE,
                                        "player%d.c%d.airlift", plrno,i);
 
-    pcity->city_options =
-      secfile_lookup_int_default(file, CITYOPT_DEFAULT,
-                                "player%d.c%d.options", plrno, i);
+    /* New city-options form as of freeciv 2.1.  Old (<= 2.0) city options
+     * are lost on upgrade. */
+    BV_CLR_ALL(pcity->city_options);
+    for (j = 0; j < CITYO_LAST; j++) {
+      if (secfile_lookup_bool_default(file, FALSE,
+                                     "player%d.c%d.option%d",
+                                     plrno, i, j)) {
+       BV_SET(pcity->city_options, j);
+      }
+    }
 
     /* Fix for old buggy savegames. */
     if (!has_capability("known32fix", savefile_options)
@@ -3005,10 +3012,12 @@ static void player_save(struct player *p
     secfile_insert_bool(file, pcity->did_sell, "player%d.c%d.did_sell", 
plrno,i);
     secfile_insert_bool(file, pcity->airlift, "player%d.c%d.airlift", plrno,i);
 
-    /* for auto_attack */
-    secfile_insert_int(file, pcity->city_options,
-                      "player%d.c%d.options", plrno, i);
-    
+    /* New options format as of Freeciv 2.1. */
+    for (j = 0; j < CITYO_LAST; j++) {
+      secfile_insert_bool(file, BV_ISSET(pcity->city_options, j),
+                         "player%d.c%d.option%d", plrno, i, j);
+    }
+
     j=0;
     for(y=0; y<CITY_MAP_SIZE; y++) {
       for(x=0; x<CITY_MAP_SIZE; x++) {

[Prev in Thread] Current Thread [Next in Thread]