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

Well, I was wrong again.  It *is* possible to handle without changing the
network packets!  Woke up this morning with another idea -- and it works!
Inefficiently for 2.1, but third times the charm!

So far, only done for gtk2....

client/gui-gtk-2.0/repodlgs.c

   settable_options_processing() [was set_options()]
     Re-written (while learning GTK2 from the web pages).  Instead of
     recursion, use a (faster and simpler) while loop!

   create_settable_options_dialog()
     Pass useful pointers as data, not integers or boolean cast to pointers!

client/repodlgs_common.c

   handle_options_settable()
     Fixes an outstanding client memory leak, for every single set string
     packet after the first groups -- the old strings weren't freed.

     There's no good way to know when the settings are done sending.  But it
     is possible to count the packets, and check the local rc file after
     processing the last packet.

     In 2.1, the settings packets are sent 3 times (down from 4 after
     PR#39964), so the user "set"s are sent 3 times, too.

client/options.c

   load_settable_options()
   save_settable_options()
     The above is ameliorated by keeping track of the settings that are
     different from default, and only saving and sending those.  This way,
     the new [server] section should stay very short and easy to read.

   option_file_name()
   load_general_options()
     Fixes an append_output_window() problem with GTK2.  For some odd reason,
     the GTK2 ui_init() doesn't actually do gtk_init() -- done later in
     ui_main() -- so the existing options loading error messages just won't
     work!  (Obviously never tested.)  Instead, replaced them with freelog().

client/clinet.c

   disconnect_from_server()
     The save_options_on_exit menu option didn't work for Leave, only Quit.
     Fixed.


Index: server/stdinhand.c
===================================================================
--- server/stdinhand.c  (revision 14160)
+++ server/stdinhand.c  (working copy)
@@ -1698,8 +1698,8 @@
        packet.default_val = setting->int_default_value;
        break;
       case SSET_STRING:
-       strcpy(packet.strval, setting->string_value);
-       strcpy(packet.default_strval, setting->string_default_value);
+       sz_strlcpy(packet.strval, setting->string_value);
+       sz_strlcpy(packet.default_strval, setting->string_default_value);
        break;
       };
     }
Index: client/options.h
===================================================================
--- client/options.h    (revision 14160)
+++ client/options.h    (working copy)
@@ -176,6 +176,7 @@
 
 void load_general_options(void);
 void load_ruleset_specific_options(void);
+void load_settable_options(bool send_it);
 void save_options(void);
 
 /* Callback functions for changing options. */
Index: client/gui-gtk-2.0/repodlgs.c
===================================================================
--- client/gui-gtk-2.0/repodlgs.c       (revision 14160)
+++ client/gui-gtk-2.0/repodlgs.c       (working copy)
@@ -27,6 +27,7 @@
 #include "fcintl.h"
 #include "game.h"
 #include "government.h"
+#include "log.h"
 #include "packets.h"
 #include "shared.h"
 #include "support.h"
@@ -1386,37 +1387,59 @@
 *************************************************************************/
 static void option_changed_callback(GtkWidget *widget, gpointer data) 
 {
-  g_object_set_data(G_OBJECT(widget), "changed", (gpointer)TRUE); 
+  /* pass along the pointer to the changed option */
+  g_object_set_data(G_OBJECT(widget), "changed", data); 
 }
 
 /*************************************************************************
   helper function for server options dialog
 *************************************************************************/
-static void set_options(GtkWidget *w)
+static void settable_options_processing(GtkWidget *final)
 {
-  GtkWidget *tmp;
+  char buffer[MAX_LEN_MSG];
+  const char *desired_string;
+  GtkWidget *w = final;
 
-  /* if the entry has been changed, then send the changes to the server */
-  if (g_object_get_data(G_OBJECT(w), "changed")) {
-    char buffer[MAX_LEN_MSG];
+  while (NULL != w) {
+    struct options_settable *o =
+      (struct options_settable *)g_object_get_data(G_OBJECT(w), "changed");
 
-    /* append the name of the option */
-    my_snprintf(buffer, MAX_LEN_MSG, "/set %s ", gtk_widget_get_name(w));
+    /* if the entry has been changed, then send the changes to the server */
+    if (NULL != o) {
+      /* append the name of the option */
+      my_snprintf(buffer, sizeof(buffer), "/set %s ", gtk_widget_get_name(w));
 
-    /* append the setting */
-    if (GTK_IS_ENTRY(w)) {
-      sz_strlcat(buffer, gtk_entry_get_text(GTK_ENTRY(w)));
-    } else {
-      bool active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
-      sz_strlcat(buffer, active ? "1" : "0");
+      /* append the setting */
+      switch (o->stype) {
+      case SSET_BOOL:
+        o->desired_val = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
+        sz_strlcat(buffer, o->desired_val ? "1" : "0");
+        break;
+      case SSET_INT:
+        o->desired_val = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(w));
+        sz_strlcat(buffer, gtk_entry_get_text(GTK_ENTRY(w)));
+        break;
+      case SSET_STRING:
+        desired_string = gtk_entry_get_text(GTK_ENTRY(w));
+        if (NULL != desired_string) {
+          if (NULL != o->desired_strval) {
+            free(o->desired_strval);
+          }
+          o->desired_strval = mystrdup(desired_string);
+          sz_strlcat(buffer, desired_string);
+        }
+        break;
+      default:
+        freelog(LOG_ERROR,
+                "settable_options_processing() bad type %d.",
+                o->stype);
+        break;
+      };
+      send_chat(buffer);
     }
-    send_chat(buffer);
-  }
 
-  /* using the linked list, work backwards and check the previous widget */
-  tmp = (GtkWidget *)g_object_get_data(G_OBJECT(w), "prev");
-  if (tmp) {
-    set_options(tmp);
+    /* using the linked list, work backwards and check the previous widget */
+    w = (GtkWidget *)g_object_get_data(G_OBJECT(w), "prev");
   }
 }
 
@@ -1426,7 +1449,7 @@
 static void settable_options_callback(GtkWidget *win, gint rid, GtkWidget *w)
 {
   if (rid == GTK_RESPONSE_OK) {
-    set_options(w);
+    settable_options_processing(w);
   }
   gtk_widget_destroy(win);
 }
@@ -1436,15 +1459,14 @@
 *************************************************************************/
 static void create_settable_options_dialog(void)
 {
-  GtkWidget *win, *book, **vbox, *label, *prev_widget = NULL;
-  GtkTooltips *tips;
-  bool *used;
   int i;
+  GtkWidget *win, *book, **vbox, *label;
+  GtkWidget *prev_widget = NULL;
+  GtkTooltips *tips = gtk_tooltips_new();
+  bool *used = fc_calloc(num_options_categories, sizeof(*used));
 
-  used = fc_calloc(num_options_categories, sizeof(*used));
-
-  tips = gtk_tooltips_new();
-  settable_options_dialog_shell = gtk_dialog_new_with_buttons(_("Game 
Settings"),
+  settable_options_dialog_shell =
+    gtk_dialog_new_with_buttons(_("Game Settings"),
       NULL, 0,
       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
       GTK_STOCK_OK, GTK_RESPONSE_OK,
@@ -1510,7 +1532,7 @@
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ent), o->val);
 
        g_signal_connect(ent, "toggled", 
-                        G_CALLBACK(option_changed_callback), NULL);
+                        G_CALLBACK(option_changed_callback), o);
        break;
 
       case SSET_INT:
@@ -1530,7 +1552,7 @@
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(ent), o->val);
 
        g_signal_connect(ent, "changed", 
-                        G_CALLBACK(option_changed_callback), NULL);
+                        G_CALLBACK(option_changed_callback), o);
        break;
       case SSET_STRING:
        /* string */
@@ -1538,7 +1560,7 @@
        gtk_entry_set_text(GTK_ENTRY(ent), o->strval);
 
        g_signal_connect(ent, "changed", 
-                        G_CALLBACK(option_changed_callback), NULL);
+                        G_CALLBACK(option_changed_callback), o);
        break;
       }
     } else {
@@ -1567,7 +1589,7 @@
     /* set up a linked list so we can work our way through the widgets */
     gtk_widget_set_name(ent, o->name);
     g_object_set_data(G_OBJECT(ent), "prev", prev_widget);
-    g_object_set_data(G_OBJECT(ent), "changed", FALSE);
+    g_object_set_data(G_OBJECT(ent), "changed", NULL);
     prev_widget = ent;
   }
 
Index: client/repodlgs_common.c
===================================================================
--- client/repodlgs_common.c    (revision 14160)
+++ client/repodlgs_common.c    (working copy)
@@ -30,15 +30,16 @@
 
 #include "civclient.h"         /* can_client_issue_orders */
 #include "control.h"
+#include "options.h"
 #include "repodlgs_common.h"
 #include "packhand_gen.h"
 
+char **options_categories;
 struct options_settable *settable_options;
+int num_options_categories;
 int num_settable_options;
+bool settable_options_loaded;  /* desired options from file */
 
-char **options_categories;
-int num_options_categories;
-
 /****************************************************************
   Fills out the array of struct improvement_entry given by
   entries. The array must be able to hold at least B_LAST entries.
@@ -193,6 +194,8 @@
 *******************************************************************/
 void settable_options_init(void)
 {
+  settable_options_loaded = FALSE;
+
   settable_options = NULL;
   num_settable_options = 0;
 
@@ -201,6 +204,33 @@
 }
 
 /******************************************************************
+ free and clear all settable_option packet strings
+*******************************************************************/
+static void settable_option_strings_free(struct options_settable *o)
+{
+  if (NULL != o->name) {
+    free(o->name);
+    o->name = NULL;
+  }
+  if (NULL != o->short_help) {
+    free(o->short_help);
+    o->short_help = NULL;
+  }
+  if (NULL != o->extra_help) {
+    free(o->extra_help);
+    o->extra_help = NULL;
+  }
+  if (NULL != o->strval) {
+    free(o->strval);
+    o->strval = NULL;
+  }
+  if (NULL != o->default_strval) {
+    free(o->default_strval);
+    o->default_strval = NULL;
+  }
+}
+
+/******************************************************************
  free settable_options[] and options_categories[]
 *******************************************************************/
 void settable_options_free(void)
@@ -209,22 +239,13 @@
 
   for (i = 0; i < num_settable_options; i++) {
     struct options_settable *o = &settable_options[i];
+    settable_option_strings_free(o);
 
-    if (o->name) {
-      free(o->name);
+    /* special handling for non-packet strings */
+    if (NULL != o->desired_strval) {
+      free(o->desired_strval);
+      o->desired_strval = NULL;
     }
-    if (o->short_help) {
-      free(o->short_help);
-    }
-    if (o->extra_help) {
-      free(o->extra_help);
-    }
-    if (o->strval) {
-      free(o->strval);
-    }
-    if (o->default_strval) {
-      free(o->default_strval);
-    }
   }
   free(settable_options);
 
@@ -286,39 +307,31 @@
   o->scategory = packet->scategory;
   o->sclass = packet->sclass;
 
+  o->val = packet->val;
+  o->default_val = packet->default_val;
+  if (!settable_options_loaded) {
+    o->desired_val = packet->default_val;
+    /* desired_val is loaded later */
+  }
+  o->min = packet->min;
+  o->max = packet->max;
+
+  /* ensure packet string fields are NULL for repeat calls */
+  settable_option_strings_free(o);
+
   switch (o->stype) {
   case SSET_BOOL:
-    o->val = packet->val;
-    o->default_val = packet->default_val;
     o->min = FALSE;
     o->max = TRUE;                             /* server sent FALSE */
-    o->strval = NULL;
-    o->default_strval = NULL;
     break;
   case SSET_INT:
-    o->val = packet->val;
-    o->default_val = packet->default_val;
-    o->min = packet->min;
-    o->max = packet->max;
-    o->strval = NULL;
-    o->default_strval = NULL;
     break;
   case SSET_STRING:
-    o->val = packet->val;
-    o->default_val = packet->default_val;
-    o->min = packet->min;
-    o->max = packet->max;
     o->strval = mystrdup(packet->strval);
     o->default_strval = mystrdup(packet->default_strval);
+    /* desired_strval is loaded later */
     break;
   default:
-    /* ensure string fields are NULL for free */
-    o->name = NULL;
-    o->short_help = NULL;
-    o->extra_help = NULL;
-    o->strval = NULL;
-    o->default_strval = NULL;
-
     freelog(LOG_ERROR,
            "handle_options_settable() bad type %d.",
            packet->stype);
@@ -330,6 +343,12 @@
   o->name = mystrdup(packet->name);
   o->short_help = mystrdup(packet->short_help);
   o->extra_help = mystrdup(packet->extra_help);
+
+  /* have no proper final packet, test for the last instead */
+  if (i == (num_settable_options - 1) && !settable_options_loaded) {
+    load_settable_options(TRUE);
+    settable_options_loaded = TRUE;
+  }
 }
 
 /****************************************************************************
Index: client/repodlgs_common.h
===================================================================
--- client/repodlgs_common.h    (revision 14160)
+++ client/repodlgs_common.h    (working copy)
@@ -57,11 +57,13 @@
 
   int val;
   int default_val;
+  int desired_val;
   int min;
   int max;
 
   char *strval;
   char *default_strval;
+  char *desired_strval;
 
   char *name;
   char *short_help;
Index: client/clinet.c
===================================================================
--- client/clinet.c     (revision 14160)
+++ client/clinet.c     (working copy)
@@ -285,6 +285,9 @@
   if (with_ggz) {
     client_exit();
   }
+  if (save_options_on_exit) {
+    save_options();
+  }
 }  
 
 /**************************************************************************
Index: client/options.c
===================================================================
--- client/options.c    (revision 14160)
+++ client/options.c    (working copy)
@@ -39,10 +39,17 @@
 #include "options.h"
 #include "overview_common.h"
 #include "plrdlg_common.h"
+#include "repodlgs_common.h"
 #include "servers.h"
 #include "themes_common.h"
 #include "tilespec.h"
 
+/****************************************************************
+ The "options" file handles actual "options", and also view options,
+ message options, dialog/report settings, cma settings, server settings,
+ and global worklists.
+*****************************************************************/
+
 /** Defaults for options normally on command line **/
 
 char default_user_name[512] = "\0";
@@ -397,18 +404,72 @@
 }
 
 
-static void save_cma_preset(struct section_file *file, char *name,
-                           const struct cm_parameter *const pparam,
-                           int inx);
-static void load_cma_preset(struct section_file *file, int inx);
+/****************************************************************
+ Does heavy lifting for looking up a preset.
+*****************************************************************/
+static void load_cma_preset(struct section_file *file, int inx)
+{
+  struct cm_parameter parameter;
+  const char *name =
+    secfile_lookup_str_default(file, "preset",
+                               "cma.preset%d.name", inx);
 
+  output_type_iterate(i) {
+    parameter.minimal_surplus[i] =
+        secfile_lookup_int_default(file, 0, "cma.preset%d.minsurp%d", inx, i);
+    parameter.factor[i] =
+        secfile_lookup_int_default(file, 0, "cma.preset%d.factor%d", inx, i);
+  } output_type_iterate_end;
+  parameter.require_happy =
+      secfile_lookup_bool_default(file, FALSE, "cma.preset%d.reqhappy", inx);
+  parameter.happy_factor =
+      secfile_lookup_int_default(file, 0, "cma.preset%d.happyfactor", inx);
+  parameter.allow_disorder = FALSE;
+  parameter.allow_specialists = TRUE;
+
+  cmafec_preset_add(name, &parameter);
+}
+
 /****************************************************************
- The "options" file handles actual "options", and also view options,
- message options, city report settings, cma settings, and 
- saved global worklists
+ Does heavy lifting for inserting a preset.
 *****************************************************************/
+static void save_cma_preset(struct section_file *file, int inx)
+{
+  const struct cm_parameter *const pparam = cmafec_preset_get_parameter(inx);
+  char *name = cmafec_preset_get_descr(inx);
 
+  secfile_insert_str(file, name, "cma.preset%d.name", inx);
+
+  output_type_iterate(i) {
+    secfile_insert_int(file, pparam->minimal_surplus[i],
+                       "cma.preset%d.minsurp%d", inx, i);
+    secfile_insert_int(file, pparam->factor[i],
+                       "cma.preset%d.factor%d", inx, i);
+  } output_type_iterate_end;
+  secfile_insert_bool(file, pparam->require_happy,
+                      "cma.preset%d.reqhappy", inx);
+  secfile_insert_int(file, pparam->happy_factor,
+                     "cma.preset%d.happyfactor", inx);
+}
+
 /****************************************************************
+ Insert all cma presets.
+*****************************************************************/
+static void save_cma_presets(struct section_file *file)
+{
+  int i;
+
+  secfile_insert_int_comment(file, cmafec_preset_num(),
+                             _("If you add a preset by hand,"
+                               " also update \"number_of_presets\""),
+                             "cma.number_of_presets");
+  for (i = 0; i < cmafec_preset_num(); i++) {
+    save_cma_preset(file, i);
+  }
+}
+
+
+/****************************************************************
  Returns pointer to static memory containing name of option file.
  Ie, based on FREECIV_OPT env var, and home dir. (or a
  OPTION_FILE_NAME define defined in config.h)
@@ -427,7 +488,7 @@
 #ifndef OPTION_FILE_NAME
     name = user_home_dir();
     if (!name) {
-      append_output_window(_("Cannot find your home directory"));
+      freelog(LOG_ERROR, _("Cannot find your home directory"));
       return NULL;
     }
     mystrlcpy(name_buffer, name, 231);
@@ -439,34 +500,158 @@
   freelog(LOG_VERBOSE, "settings file is %s", name_buffer);
   return name_buffer;
 }
-  
+
+
 /****************************************************************
- this loads from the rc file any options which are not ruleset specific 
- it is called on client init.
+ Load settable per connection/server options.
 *****************************************************************/
+void load_settable_options(bool send_it)
+{
+  char buffer[MAX_LEN_MSG];
+  struct section_file sf;
+  char *name;
+  char *desired_string;
+  int i = 0;
+
+  name = option_file_name();
+  if (!name) {
+    /* fail silently */
+    return;
+  }
+  if (!section_file_load(&sf, name))
+    return;
+
+  for (; i < num_settable_options; i++) {
+    struct options_settable *o = &settable_options[i];
+    bool changed = FALSE;
+
+    my_snprintf(buffer, sizeof(buffer), "/set %s ", o->name);
+
+    switch (o->stype) {
+    case SSET_BOOL:
+      o->desired_val = secfile_lookup_bool_default(&sf, o->default_val,
+                                                   "server.%s", o->name);
+      changed = (o->desired_val != o->default_val);
+      if (changed) {
+        sz_strlcat(buffer, o->desired_val ? "1" : "0");
+      }
+      break;
+    case SSET_INT:
+      o->desired_val = secfile_lookup_int_default(&sf, o->default_val,
+                                                  "server.%s", o->name);
+      changed = (o->desired_val != o->default_val);
+      if (changed) {
+        cat_snprintf(buffer, sizeof(buffer), "%d", o->desired_val);
+      }
+      break;
+    case SSET_STRING:
+      desired_string = secfile_lookup_str_default(&sf, o->default_strval,
+                                                  "server.%s", o->name);
+      if (NULL != desired_string) {
+        if (NULL != o->desired_strval) {
+          free(o->desired_strval);
+        }
+        o->desired_strval = mystrdup(desired_string);
+        changed = (0 != strcmp(desired_string, o->default_strval));
+        if (changed) {
+          sz_strlcat(buffer, desired_string);
+        }
+      }
+      break;
+    default:
+      freelog(LOG_ERROR,
+              "load_settable_options() bad type %d.",
+              o->stype);
+      break;
+    };
+
+    if (changed && send_it) {
+      send_chat(buffer);
+    }
+  }
+
+  section_file_free(&sf);
+}
+
+/****************************************************************
+ Save settable per connection/server options.
+*****************************************************************/
+static void save_settable_options(struct section_file *sf)
+{
+  int i = 0;
+
+  for (; i < num_settable_options; i++) {
+    struct options_settable *o = &settable_options[i];
+
+    switch (o->stype) {
+    case SSET_BOOL:
+      if (o->desired_val != o->default_val) {
+        secfile_insert_bool(sf, o->desired_val, "server.%s", o->name);
+      }
+      break;
+    case SSET_INT:
+      if (o->desired_val != o->default_val) {
+        secfile_insert_int(sf, o->desired_val, "server.%s",  o->name);
+      }
+      break;
+    case SSET_STRING:
+      if (NULL != o->desired_strval
+       && 0 != strcmp(o->desired_strval, o->default_strval)) {
+        secfile_insert_str(sf, o->desired_strval, "server.%s", o->name);
+      }
+      break;
+    default:
+      freelog(LOG_ERROR,
+              "save_settable_options() bad type %d.",
+              o->stype);
+      break;
+    };
+  }
+}
+
+
+/****************************************************************
+ Load from the rc file any options that are not ruleset specific.
+ It is called after ui_init(), yet before ui_main().
+ Unfortunately, this means that some clients cannot display.
+ Instead, use freelog().
+*****************************************************************/
 void load_general_options(void)
 {
   struct section_file sf;
-  const char * const prefix = "client";
-  char *name;
   int i, num;
   view_option *v;
+  char *name;
+  const char * const prefix = "client";
 
   assert(options == NULL);
   num_options = ARRAY_SIZE(common_options) + num_gui_options;
-  options = fc_malloc(num_options * sizeof(*options));
+  options = fc_calloc(num_options, sizeof(*options));
   memcpy(options, common_options, sizeof(common_options));
   memcpy(options + ARRAY_SIZE(common_options), gui_options,
         num_gui_options * sizeof(*options));
 
   name = option_file_name();
   if (!name) {
-    /* fail silently */
+    freelog(LOG_ERROR, "Unable to use option settings file.");
     return;
   }
   if (!section_file_load(&sf, name)) {
+    /* try to create the rc file */
+    section_file_init(&sf);
+    secfile_insert_str(&sf, VERSION_STRING, "client.version");
+
     create_default_cma_presets();
-    return;  
+    save_cma_presets(&sf);
+
+    /* FIXME: need better messages */
+    if (!section_file_save(&sf, name, 0)) {
+      freelog(LOG_ERROR, _("Save failed, cannot write to file %s"), name);
+    } else {
+      freelog(LOG_NORMAL, _("Saved settings to file %s"), name);
+    }
+    section_file_free(&sf);
+    return;
   }
 
   /* a "secret" option for the lazy. TODO: make this saveable */
@@ -538,10 +723,9 @@
 void load_ruleset_specific_options(void)
 {
   struct section_file sf;
-  char *name;
   int i;
+  char *name = option_file_name();
 
-  name = option_file_name();
   if (!name) {
     /* fail silently */
     return;
@@ -574,10 +758,10 @@
 void save_options(void)
 {
   struct section_file sf;
-  char *name = option_file_name();
   char output_buffer[256];
+  int i;
   view_option *v;
-  int i;
+  char *name = option_file_name();
 
   if(!name) {
     append_output_window(_("Save failed, cannot find a filename."));
@@ -624,7 +808,11 @@
                         "client.player_dlg_%s",
                         player_dlg_columns[i].tagname);
   }
-  
+
+  /* server settings */
+  save_cma_presets(&sf);
+  save_settable_options(&sf);
+
   /* insert global worklists */
   if (game.player_ptr) {
     for(i = 0; i < MAX_NUM_WORKLISTS; i++){
@@ -636,17 +824,6 @@
     }
   }
 
-
-  /* insert cma presets */
-  secfile_insert_int_comment(&sf, cmafec_preset_num(),
-                            _("If you add a preset by "
-                              "hand, also update \"number_of_presets\""),
-                            "cma.number_of_presets");
-  for (i = 0; i < cmafec_preset_num(); i++) {
-    save_cma_preset(&sf, cmafec_preset_get_descr(i),
-                   cmafec_preset_get_parameter(i), i);
-  }
-
   /* save to disk */
   if (!section_file_save(&sf, name, 0)) {
     my_snprintf(output_buffer, sizeof(output_buffer),
@@ -655,57 +832,10 @@
     my_snprintf(output_buffer, sizeof(output_buffer),
                _("Saved settings to file %s"), name);
   }
-
   append_output_window(output_buffer);
   section_file_free(&sf);
 }
 
-/****************************************************************
- Does heavy lifting for looking up a preset.
-*****************************************************************/
-static void load_cma_preset(struct section_file *file, int inx)
-{
-  struct cm_parameter parameter;
-  const char *name;
-
-  name = secfile_lookup_str_default(file, "preset", 
-                                   "cma.preset%d.name", inx);
-  output_type_iterate(i) {
-    parameter.minimal_surplus[i] =
-       secfile_lookup_int_default(file, 0, "cma.preset%d.minsurp%d", inx, i);
-    parameter.factor[i] =
-       secfile_lookup_int_default(file, 0, "cma.preset%d.factor%d", inx, i);
-  } output_type_iterate_end;
-  parameter.require_happy =
-      secfile_lookup_bool_default(file, FALSE, "cma.preset%d.reqhappy", inx);
-  parameter.happy_factor =
-      secfile_lookup_int_default(file, 0, "cma.preset%d.happyfactor", inx);
-  parameter.allow_disorder = FALSE;
-  parameter.allow_specialists = TRUE;
-
-  cmafec_preset_add(name, &parameter);
-}
-
-/****************************************************************
- Does heavy lifting for inserting a preset.
-*****************************************************************/
-static void save_cma_preset(struct section_file *file, char *name,
-                           const struct cm_parameter *const pparam,
-                           int inx)
-{
-  secfile_insert_str(file, name, "cma.preset%d.name", inx);
-  output_type_iterate(i) {
-    secfile_insert_int(file, pparam->minimal_surplus[i],
-                      "cma.preset%d.minsurp%d", inx, i);
-    secfile_insert_int(file, pparam->factor[i],
-                      "cma.preset%d.factor%d", inx, i);
-  } output_type_iterate_end;
-  secfile_insert_bool(file, pparam->require_happy,
-                     "cma.preset%d.reqhappy", inx);
-  secfile_insert_int(file, pparam->happy_factor,
-                    "cma.preset%d.happyfactor", inx);
-}
-
 /****************************************************************************
   Callback when a mapview graphics option is changed (redraws the canvas).
 ****************************************************************************/
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to