Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2004:
[Freeciv-Dev] (PR#11142) allow specialists to provide science, gold, or
Home

[Freeciv-Dev] (PR#11142) allow specialists to provide science, gold, or

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#11142) allow specialists to provide science, gold, or luxury
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 24 Nov 2004 23:46:45 -0800
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=11142 >

> [jdorje - Mon Nov 22 01:59:15 2004]:
> 
> This patch allows specialists to provide any or all of science, gold, or 
> luxury.

Here is a new: bigger, badder, better version.

However it relies on the get_output_identifier() function provided in a
separate patch.

jason

Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.423
diff -u -r1.423 packhand.c
--- client/packhand.c   24 Nov 2004 06:31:25 -0000      1.423
+++ client/packhand.c   25 Nov 2004 07:44:55 -0000
@@ -2641,7 +2641,30 @@
   specialist_type_iterate(sp) {
     sz_strlcpy(game.rgame.specialists[sp].name, packet->specialist_name[sp]);
     game.rgame.specialists[sp].min_size = packet->specialist_min_size[sp];
-    game.rgame.specialists[sp].bonus = packet->specialist_bonus[sp];
+    if (has_capability("spec_multi", aconnection.capability)) {
+      int *bonus = game.rgame.specialists[sp].bonus;
+
+      output_type_iterate(o) {
+       bonus[o] = packet->specialist_bonus_new[sp * O_COUNT + o];
+      } output_type_iterate_end;
+    } else {
+      /* This is included for compatability. */
+      int bonus = packet->specialist_bonus_old[sp];
+
+      memset(game.rgame.specialists[sp].bonus, 0,
+            O_COUNT * sizeof(*game.rgame.specialists[sp].bonus));
+      switch (sp) {
+      case SP_ELVIS:
+       game.rgame.specialists[sp].bonus[O_LUXURY] = bonus;
+       break;
+      case SP_SCIENTIST:
+       game.rgame.specialists[sp].bonus[O_SCIENCE] = bonus;
+       break;
+      case SP_TAXMAN:
+       game.rgame.specialists[sp].bonus[O_GOLD] = bonus;
+       break;
+      }
+    }
   } specialist_type_iterate_end;
   tilespec_setup_specialist_types();
 
Index: client/gui-gtk/cma_fe.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/cma_fe.c,v
retrieving revision 1.24
diff -u -r1.24 cma_fe.c
--- client/gui-gtk/cma_fe.c     25 Nov 2004 07:20:02 -0000      1.24
+++ client/gui-gtk/cma_fe.c     25 Nov 2004 07:44:55 -0000
@@ -224,7 +224,7 @@
   gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 0, 1);
 
   output_type_iterate(i) {
-    label = gtk_label_new(cm_get_stat_name(i));
+    label = gtk_label_new(get_output_name(i));
     gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, i + 1, i + 2);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 
Index: client/gui-gtk-2.0/cma_fe.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/cma_fe.c,v
retrieving revision 1.23
diff -u -r1.23 cma_fe.c
--- client/gui-gtk-2.0/cma_fe.c 25 Nov 2004 07:20:02 -0000      1.23
+++ client/gui-gtk-2.0/cma_fe.c 25 Nov 2004 07:44:55 -0000
@@ -244,7 +244,7 @@
   gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 0, 1);
 
   output_type_iterate(i) {
-    label = gtk_label_new(cm_get_stat_name(i));
+    label = gtk_label_new(get_output_name(i));
     gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, i + 1, i + 2);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 
Index: client/gui-sdl/cma_fe.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-sdl/cma_fe.c,v
retrieving revision 1.15
diff -u -r1.15 cma_fe.c
--- client/gui-sdl/cma_fe.c     25 Nov 2004 07:20:02 -0000      1.15
+++ client/gui-sdl/cma_fe.c     25 Nov 2004 07:44:55 -0000
@@ -857,7 +857,7 @@
     
   /* ---------- */
   output_type_iterate(i) {
-    copy_chars_to_string16(pStr, cm_get_stat_name(i));
+    copy_chars_to_string16(pStr, get_output_name(i));
     pText[i] = create_text_surf_from_str16(pStr);
     text_w = MAX(text_w, pText[i]->w);
     
Index: client/gui-win32/cma_fe.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/cma_fe.c,v
retrieving revision 1.5
diff -u -r1.5 cma_fe.c
--- client/gui-win32/cma_fe.c   25 Nov 2004 07:20:03 -0000      1.5
+++ client/gui-win32/cma_fe.c   25 Nov 2004 07:44:55 -0000
@@ -214,7 +214,7 @@
   fcwin_box_add_static(vbox[1], _("Minimal Surplus"), 0, SS_LEFT, TRUE, TRUE, 
0);
   fcwin_box_add_static(vbox[2], _("Factor"), 0, SS_LEFT, TRUE, TRUE, 0);
   output_type_iterate(i) {
-    cmagui_add_slider(pdialog, win, vbox, FALSE, cm_get_stat_name(i), i);
+    cmagui_add_slider(pdialog, win, vbox, FALSE, get_output_name(i), i);
   } output_type_iterate_end;
   cmagui_add_slider(pdialog, win, vbox, TRUE, _("Celebrate"), i);
 }
Index: client/gui-xaw/cma_fe.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/cma_fe.c,v
retrieving revision 1.5
diff -u -r1.5 cma_fe.c
--- client/gui-xaw/cma_fe.c     25 Nov 2004 07:20:03 -0000      1.5
+++ client/gui-xaw/cma_fe.c     25 Nov 2004 07:44:55 -0000
@@ -180,7 +180,7 @@
                                 XtNfromVert, prev,
                                 XtNvertDistance, 1,
                                 XtNlabel, (i == O_COUNT) ? 
-                                  _("Celebrate") : cm_get_stat_name(i),
+                                  _("Celebrate") : get_output_name(i),
                                 NULL));
     prev = stat_surplus_label[i];
   }
@@ -222,7 +222,7 @@
                                 XtNfromVert, prev,
                                 XtNvertDistance, 1,
                                 XtNlabel, (i == O_COUNT) ?
-                                  _("Celebrate") : cm_get_stat_name(i),
+                                  _("Celebrate") : get_output_name(i),
                                 NULL));
     prev = stat_factor_label[i];
   }
@@ -694,14 +694,14 @@
 
   output_type_iterate(i) {
     my_snprintf(buf, sizeof(buf), "%-9s%3d",
-                cm_get_stat_name(i),
+                get_output_name(i),
                 minimal_surplus[i]);
     xaw_set_label(stat_surplus_label[i], buf);
   } output_type_iterate_end;
 
   output_type_iterate(i) {
     my_snprintf(buf, sizeof(buf), "%-9s%3d",
-                cm_get_stat_name(i),
+                get_output_name(i),
                 factors[i]);
     xaw_set_label(stat_factor_label[i], buf);
   } output_type_iterate_end;
Index: common/capstr.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v
retrieving revision 1.195
diff -u -r1.195 capstr.c
--- common/capstr.c     16 Nov 2004 18:09:46 -0000      1.195
+++ common/capstr.c     25 Nov 2004 07:44:55 -0000
@@ -83,6 +83,12 @@
  *
  * "username_info" means that the username is sent in the player_info packet
  *
+ * "new_hack" means a new-style hack-request method
+ *
+ * "spec_multi" means specialists may provide more than one type of output.
+ * Note that actually using this feature with an unsupported client will
+ * break it.
+ *
  *   - No new manditory capabilities can be added to the release branch; doing
  *     so would break network capability of supposedly "compatible" releases.
  *
@@ -90,7 +96,8 @@
  *     as long as possible.  We want to maintain network compatibility with
  *     the stable branch for as long as possible.
  */
-#define CAPABILITY "+2.0 connecting conn_ping_info username_info new_hack"
+#define CAPABILITY "+2.0 connecting conn_ping_info username_info new_hack " \
+                   "spec_multi"
 
 void init_our_capability(void)
 {
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.257
diff -u -r1.257 city.c
--- common/city.c       25 Nov 2004 05:34:35 -0000      1.257
+++ common/city.c       25 Nov 2004 07:44:56 -0000
@@ -206,6 +206,60 @@
   cm_init_citymap();
 }
 
+
+/****************************************************************************
+  Return an id string for the output type.  This string can be used
+  internally by rulesets and tilesets and should not be changed or
+  translated.
+*****************************************************************************/
+const char *get_output_identifier(Output_type_id output)
+{
+  switch (output) {
+  case O_FOOD:
+    return "food";
+  case O_SHIELD:
+    return "shield";
+  case O_TRADE:
+    return "trade";
+  case O_GOLD:
+    return "gold";
+  case O_LUXURY:
+    return "luxury";
+  case O_SCIENCE:
+    return "science";
+  case O_LAST:
+    break;
+  }
+  die("Unknown output type in get_output_id: %d", output);
+  return NULL;
+}
+
+/****************************************************************************
+  Return a translated name for the output type.  This name should only be
+  used for user display.
+*****************************************************************************/
+const char *get_output_name(Output_type_id output)
+{
+  switch (output) {
+  case O_FOOD:
+    return _("Food");
+  case O_SHIELD:
+    return _("Shield");
+  case O_TRADE:
+    return _("Trade");
+  case O_GOLD:
+    return _("Gold");
+  case O_LUXURY:
+    return _("Luxury");
+  case O_SCIENCE:
+    return _("Science");
+  case O_LAST:
+    break;
+  }
+  die("Unknown output type in get_output_name: %d", output);
+  return NULL;
+}
+
 /**************************************************************************
   Set the worker on the citymap.  Also sets the worked field in the map.
 **************************************************************************/
@@ -1677,12 +1731,15 @@
   get_tax_income(city_owner(pcity), pcity->trade_prod, &pcity->science_total, 
                  &pcity->luxury_total, &pcity->tax_total);
 
-  pcity->luxury_total += (pcity->specialists[SP_ELVIS]
-                         * game.rgame.specialists[SP_ELVIS].bonus);
-  pcity->science_total += (pcity->specialists[SP_SCIENTIST]
-                          * game.rgame.specialists[SP_SCIENTIST].bonus);
-  pcity->tax_total += (pcity->specialists[SP_TAXMAN]
-                       * game.rgame.specialists[SP_TAXMAN].bonus);
+  specialist_type_iterate(sp) {
+    int *bonus = game.rgame.specialists[sp].bonus;
+    int count = pcity->specialists[sp];
+
+    pcity->luxury_total += count * bonus[O_LUXURY];
+    pcity->science_total += count * bonus[O_SCIENCE];
+    pcity->tax_total += count * bonus[O_GOLD];
+  } specialist_type_iterate_end;
+
   pcity->tax_total += get_city_tithes_bonus(pcity);
 }
 
Index: common/city.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.h,v
retrieving revision 1.168
diff -u -r1.168 city.h
--- common/city.h       25 Nov 2004 07:20:03 -0000      1.168
+++ common/city.h       25 Nov 2004 07:44:56 -0000
@@ -363,6 +363,11 @@
 }
 
 
+/* output type functions */
+
+const char *get_output_identifier(Output_type_id output);
+const char *get_output_name(Output_type_id output);
+
 /* properties */
 
 struct player *city_owner(const struct city *pcity);
Index: common/game.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.h,v
retrieving revision 1.159
diff -u -r1.159 game.h
--- common/game.h       25 Nov 2004 06:29:49 -0000      1.159
+++ common/game.h       25 Nov 2004 07:44:56 -0000
@@ -195,7 +195,8 @@
   struct {
     struct {
       char name[MAX_LEN_NAME];
-      int min_size, bonus;
+      int min_size;
+      int bonus[O_MAX];
     } specialists[SP_COUNT];
 #define DEFAULT_SPECIALIST SP_ELVIS
     bool changable_tax;
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.59
diff -u -r1.59 packets.def
--- common/packets.def  16 Nov 2004 18:09:46 -0000      1.59
+++ common/packets.def  25 Nov 2004 07:44:56 -0000
@@ -973,7 +973,8 @@
 PACKET_RULESET_GAME=97;sc,lsend
   STRING specialist_name[SP_COUNT][MAX_LEN_NAME];
   UINT8 specialist_min_size[SP_COUNT];
-  UINT8 specialist_bonus[SP_COUNT];
+  UINT8 specialist_bonus_old[SP_COUNT]; remove-cap(spec_multi)
+  UINT8 specialist_bonus_new[SP_COUNT * O_MAX]; add-cap(spec_multi)
   BOOL changable_tax;
   UINT8 forced_science;
   UINT8 forced_luxury;
Index: common/aicore/cm.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/cm.c,v
retrieving revision 1.46
diff -u -r1.46 cm.c
--- common/aicore/cm.c  25 Nov 2004 07:20:03 -0000      1.46
+++ common/aicore/cm.c  25 Nov 2004 07:44:56 -0000
@@ -174,7 +174,7 @@
   int production[O_MAX];
   double estimated_fitness; /* weighted sum of production */
   bool is_specialist;
-  enum specialist_type spec; /* valid only if is_specialist */
+  Specialist_type_id spec; /* valid only if is_specialist */
   struct tile_vector tiles;  /* valid only if !is_specialist */
   struct tile_type_vector better_types;
   struct tile_type_vector worse_types;
@@ -911,19 +911,7 @@
 
 /*
  * Add the specialist types to the lattice.
- * This structure is necessary for now because each specialist
- * creates only one type of production and we need to map
- * indices from specialist_type to cm_stat.
  */
-struct spec_stat_pair {
-  enum specialist_type spec;
-  Output_type_id stat;
-};
-const static struct spec_stat_pair pairs[SP_COUNT] =  {
-  { SP_ELVIS, O_LUXURY },
-  { SP_SCIENTIST, O_SCIENCE },
-  { SP_TAXMAN, O_GOLD }
-};
 
 /****************************************************************************
   Create lattice nodes for each type of specialist.  This adds a new
@@ -940,14 +928,15 @@
   /* for each specialist type, create a tile_type that has as production
    * the bonus for the specialist (if the city is allowed to use it) */
   specialist_type_iterate(i) {
-    if (city_can_use_specialist(pcity, pairs[i].spec)) {
-      type.spec = pairs[i].spec;
-      type.production[pairs[i].stat]
-        = game.rgame.specialists[pairs[i].spec].bonus;
+    if (city_can_use_specialist(pcity, i)) {
+      type.spec = i;
+      output_type_iterate(output) {
+       type.production[output] = game.rgame.specialists[i].bonus[output];
+      } output_type_iterate_end;
 
       tile_type_lattice_add(lattice, &type, 0, 0);
 
-      type.production[pairs[i].stat] = 0;
+
     }
   } specialist_type_iterate_end;
 }
@@ -1506,7 +1495,7 @@
   output_type_iterate(stat) {
     if (production[stat] < state->min_production[stat]) {
       freelog(LOG_PRUNE_BRANCH, "--- pruning: insufficient %s (%d < %d)",
-             cm_get_stat_name(stat), production[stat],
+             get_output_name(stat), production[stat],
              state->min_production[stat]);
       return FALSE;
     }
@@ -1818,32 +1807,6 @@
   cm_free_state(state);
 }
 
-
-/****************************************************************************
-  Return a translated name for the stat type.
-*****************************************************************************/
-const char *cm_get_stat_name(Output_type_id stat)
-{
-  switch (stat) {
-  case O_FOOD:
-    return _("Food");
-  case O_SHIELD:
-    return _("Shield");
-  case O_TRADE:
-    return _("Trade");
-  case O_GOLD:
-    return _("Gold");
-  case O_LUXURY:
-    return _("Luxury");
-  case O_SCIENCE:
-    return _("Science");
-  case O_LAST:
-    break;
-  }
-  die("Unknown stat value in cm_get_stat_name: %d", stat);
-  return NULL;
-}
-
 /**************************************************************************
   Returns true if the two cm_parameters are equal.
 **************************************************************************/
@@ -2164,6 +2127,6 @@
 
   output_type_iterate(i) {
     freelog(LOG_NORMAL, "print_result:  %10s surplus=%d",
-        cm_get_stat_name(i), result->surplus[i]);
+        get_output_name(i), result->surplus[i]);
   } output_type_iterate_end;
 }
Index: common/aicore/cm.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/cm.h,v
retrieving revision 1.11
diff -u -r1.11 cm.h
--- common/aicore/cm.h  24 Nov 2004 03:34:57 -0000      1.11
+++ common/aicore/cm.h  25 Nov 2004 07:44:57 -0000
@@ -74,7 +74,6 @@
 void cm_clear_cache(struct city *pcity);
 
 /***************** utility methods *************************************/
-const char *cm_get_stat_name(Output_type_id stat);
 bool cm_are_parameter_equal(const struct cm_parameter *const p1,
                            const struct cm_parameter *const p2);
 void cm_copy_parameter(struct cm_parameter *dest,
Index: data/default/cities.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/cities.ruleset,v
retrieving revision 1.11
diff -u -r1.11 cities.ruleset
--- data/default/cities.ruleset 9 Jun 2004 04:39:13 -0000       1.11
+++ data/default/cities.ruleset 25 Nov 2004 07:44:57 -0000
@@ -21,14 +21,13 @@
 ; the city is of a certain size.
 [specialist]
 
-; Changing the order or names of specialists will break things
 types = "elvis", "scientist", "taxman"
 elvis_min_size = 0
-elvis_base_bonus = 2
+elvis_bonus_luxury = 2
 scientist_min_size = 5
-scientist_base_bonus = 3
+scientist_bonus_science = 3
 taxman_min_size = 5
-taxman_base_bonus = 3
+taxman_bonus_gold = 3
 
 changable_tax = 1
 ;forced_science = 0
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.200
diff -u -r1.200 ruleset.c
--- server/ruleset.c    17 Nov 2004 19:21:14 -0000      1.200
+++ server/ruleset.c    25 Nov 2004 07:44:58 -0000
@@ -2554,13 +2554,17 @@
 
   for (i = 0; i < nval; i++) {
     const char *name = specialist_names[i];
+    int *bonus = game.rgame.specialists[i].bonus;
 
     sz_strlcpy(game.rgame.specialists[i].name, name);
     game.rgame.specialists[i].min_size
       = secfile_lookup_int(file, "specialist.%s_min_size", name);
-    game.rgame.specialists[i].bonus
-      = secfile_lookup_int(file, "specialist.%s_base_bonus", name);
-    
+
+    output_type_iterate(o) {
+      bonus[o] = secfile_lookup_int_default(file, 0,
+                                           "specialist.%s_bonus_%s",
+                                           name, get_output_identifier(o));
+    } output_type_iterate_end;
   }
   free(specialist_names);
 
@@ -3149,9 +3153,19 @@
   struct packet_ruleset_game misc_p;
 
   specialist_type_iterate(sp) {
+    int *bonus = game.rgame.specialists[sp].bonus;
+    int max_bonus = 0;
+
     sz_strlcpy(misc_p.specialist_name[sp], game.rgame.specialists[sp].name);
     misc_p.specialist_min_size[sp] = game.rgame.specialists[sp].min_size;
-    misc_p.specialist_bonus[sp] = game.rgame.specialists[sp].bonus;
+
+    output_type_iterate(o) {
+      misc_p.specialist_bonus_new[sp * O_COUNT + o] = bonus[o];
+      max_bonus = MAX(max_bonus, bonus[0]);
+    } output_type_iterate_end;
+
+    /* This is included for compatability. */
+    misc_p.specialist_bonus_old[sp] = max_bonus;
   } specialist_type_iterate_end;
   misc_p.changable_tax = game.rgame.changable_tax;
   misc_p.forced_science = game.rgame.forced_science;

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