Complete.Org: Mailing Lists: Archives: freeciv-dev: April 2005:
[Freeciv-Dev] (PR#12930) RFC: generalizing output types in effects
Home

[Freeciv-Dev] (PR#12930) RFC: generalizing output types in effects

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#12930) RFC: generalizing output types in effects
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 28 Apr 2005 22:16:06 -0700
Reply-to: bugs@xxxxxxxxxxx

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

See als PR#10116, PR#12856.

It would be nice to generalize the output types in the effects code.
This would cut down on the number of output-modifying effects by a
factor of 6, as well as allowing potential future gen-output work.

There are basically 3 ways we can do effects with output:

1.  Hard-code each type of output as a different type of effect.  This
is what's done now.  Advantages: fast, easy.  Disadvantages: many
different effect types bloat the (user) API; impossible to change or add
effect types without breaking things.

2.  Add a new parameter to the effect structure.  I'm not entirely sure
how this would work, but it would amount to a new entry in the
[effect_xxx] section in the effects.ruleset.  This would be its very own
variable in the effect structure in effects.h.  Advantages: fast.
Disadvantages: more effect parameters bloat the (user) API; parameter is
specific to just a few effect types; lots of work to code.

3.  Add an output type as a requirement.  I hinted at this before but
here is how it would work: a new requirement source type REQ_OUTPUT_TYPE
is added.  At first glance this may not make any sense whatsoever.
However when we pass in a target_output_type to the req functions then
the requirement is only met if the output type we're considering at the
moment is the one in the requirement.  Advantages: easy, extensible.
Disadvantages: the req can only have range REQ_LOCAL and only applies to
a few effects (and never to buildings or other reqs users); it's slower
than #1 or #2 because you have to go through the inapplicable effects to
get to the ones you want (for instance to find the prod bonus you have
to iterate over science, luxury, and gold bonus effects as well).

The attached patch implements #3.  This is basically a demo at this
point.  To be workable it'll need some cleaning up, plus documentation
(README.effects) and updates for the other rulesets.  However I think
this is the best way to do it, at least for now.

-jason

? diff
? gmon.out
Index: ai/aicity.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aicity.c,v
retrieving revision 1.214
diff -u -r1.214 aicity.c
--- ai/aicity.c 29 Apr 2005 01:52:09 -0000      1.214
+++ ai/aicity.c 29 Apr 2005 05:14:28 -0000
@@ -271,7 +271,7 @@
     struct requirement *mypreq;
     bool useful;
 
-    if (is_effect_disabled(pplayer, pcity, pimpr, NULL, peffect)) {
+    if (is_effect_disabled(pplayer, pcity, pimpr, NULL, NULL, peffect)) {
       CITY_LOG(LOG_DEBUG, pcity, "%s has a disabled effect: %s", 
                get_improvement_name(id), effect_type_name(peffect->type));
       continue;
@@ -287,7 +287,7 @@
        mypreq = preq;
         continue;
       }
-      if (!is_req_active(pplayer, pcity, pimpr, NULL, preq)) {
+      if (!is_req_active(pplayer, pcity, pimpr, NULL, NULL, preq)) {
        useful = FALSE;
        break;
       }
@@ -308,29 +308,12 @@
        case EFT_UPKEEP_FREE:
        case EFT_POLLU_POP_PCT:
        case EFT_POLLU_PROD_PCT:
-       case EFT_TRADE_PER_TILE:
-       case EFT_TRADE_INC_TILE:
-       case EFT_FOOD_INC_TILE:
-       case EFT_TRADE_ADD_TILE:
-       case EFT_PROD_INC_TILE:
-       case EFT_PROD_PER_TILE:
-       case EFT_PROD_ADD_TILE:
-       case EFT_FOOD_PER_TILE:
-       case EFT_FOOD_ADD_TILE:
-      case EFT_FOOD_BONUS:
-       case EFT_PROD_BONUS:
-      case EFT_TRADE_BONUS:
-       case EFT_TAX_BONUS:
-       case EFT_SCIENCE_BONUS:
-       case EFT_LUXURY_BONUS:
-      case EFT_FOOD_BONUS_2:
-      case EFT_PROD_BONUS_2:
-      case EFT_TRADE_BONUS_2:
-      case EFT_TAX_BONUS_2:
-      case EFT_SCIENCE_BONUS_2:
-      case EFT_LUXURY_BONUS_2:
-       case EFT_CORRUPT_PCT:
-       case EFT_WASTE_PCT:
+      case EFT_OUTPUT_BONUS:
+      case EFT_OUTPUT_BONUS_2:
+      case EFT_OUTPUT_ADD_TILE:
+      case EFT_OUTPUT_INC_TILE:
+      case EFT_OUTPUT_PER_TILE:
+      case EFT_OUTPUT_WASTE_PCT:
          break;
 
       case EFT_SLOW_DOWN_TIMELINE:
@@ -1249,8 +1232,11 @@
 **************************************************************************/
 static bool building_unwanted(struct player *plr, Impr_Type_id i)
 {
+#if 0 /* This check will become more complicated now. */ 
   return (ai_wants_no_science(plr)
           && building_has_effect(i, EFT_SCIENCE_BONUS));
+#endif
+  return FALSE;
 }
 
 /**************************************************************************
Index: ai/aidata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidata.c,v
retrieving revision 1.64
diff -u -r1.64 aidata.c
--- ai/aidata.c 23 Apr 2005 17:40:21 -0000      1.64
+++ ai/aidata.c 29 Apr 2005 05:14:28 -0000
@@ -289,23 +289,15 @@
       case EFT_MAKE_CONTENT_PCT:
       case EFT_MAKE_HAPPY:
 #endif
-      case EFT_LUXURY_BONUS:
-      case EFT_SCIENCE_BONUS:
-      case EFT_TAX_BONUS:
       case EFT_CAPITAL_CITY:
-      case EFT_CORRUPT_PCT:
-      case EFT_FOOD_ADD_TILE:
-      case EFT_FOOD_INC_TILE:
-      case EFT_FOOD_PER_TILE:
       case EFT_POLLU_POP_PCT:
       case EFT_POLLU_PROD_PCT:
-      case EFT_PROD_ADD_TILE:
-      case EFT_PROD_BONUS:
-      case EFT_PROD_INC_TILE:
-      case EFT_PROD_PER_TILE:
-      case EFT_TRADE_ADD_TILE:
-      case EFT_TRADE_INC_TILE:
-      case EFT_TRADE_PER_TILE:
+      case EFT_OUTPUT_BONUS:
+      case EFT_OUTPUT_BONUS_2:
+      case EFT_OUTPUT_ADD_TILE:
+      case EFT_OUTPUT_PER_TILE:
+      case EFT_OUTPUT_INC_TILE:
+      case EFT_OUTPUT_WASTE_PCT:
       case EFT_UPKEEP_FREE:
        requirement_list_iterate(peffect->reqs, preq) {
          if (preq->source.type == REQ_BUILDING
Index: client/citydlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/citydlg_common.c,v
retrieving revision 1.74
diff -u -r1.74 citydlg_common.c
--- client/citydlg_common.c     21 Apr 2005 21:37:34 -0000      1.74
+++ client/citydlg_common.c     29 Apr 2005 05:14:29 -0000
@@ -386,6 +386,7 @@
   int total = 0;
   int priority;
   int tax[O_COUNT];
+  struct output_type *output = &output_types[otype];
 
   buf[0] = '\0';
 
@@ -430,13 +431,13 @@
   }
 
   for (priority = 0; priority < 2; priority++) {
-    enum effect_type eft = get_output_bonus_effect(otype, priority);
+    enum effect_type eft[] = {EFT_OUTPUT_BONUS, EFT_OUTPUT_BONUS_2};
 
-    if (eft != EFT_LAST) {
+    {
       int base = total, bonus = 100;
       struct effect_list *plist = effect_list_new();
 
-      (void) get_city_bonus_effects(plist, pcity, eft);
+      (void) get_city_bonus_effects(plist, pcity, output, eft[priority]);
 
       effect_list_iterate(plist, peffect) {
        char buf2[512];
Index: client/helpdata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/helpdata.c,v
retrieving revision 1.106
diff -u -r1.106 helpdata.c
--- client/helpdata.c   23 Apr 2005 04:27:30 -0000      1.106
+++ client/helpdata.c   29 Apr 2005 05:14:29 -0000
@@ -186,6 +186,10 @@
     cat_snprintf(buf, bufsz, _("Requires the %s nation.\n\n"),
                 get_nation_name(req->source.value.nation));
     return;
+  case REQ_OUTPUT:
+    cat_snprintf(buf, bufsz, _("Applies only to %s.\n\n"),
+                get_output_name(req->source.value.output_type));
+    return;
   case REQ_MINSIZE:
     cat_snprintf(buf, bufsz, _("Requires a minimum size of %d.\n\n"),
                 req->source.value.minsize);
Index: client/text.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/text.c,v
retrieving revision 1.34
diff -u -r1.34 text.c
--- client/text.c       27 Apr 2005 02:48:00 -0000      1.34
+++ client/text.c       29 Apr 2005 05:14:29 -0000
@@ -800,7 +800,7 @@
 
   add_line(_("Buildings: "));
 
-  get_city_bonus_effects(plist, pcity, EFT_MAKE_CONTENT);
+  get_city_bonus_effects(plist, pcity, NULL, EFT_MAKE_CONTENT);
 
   effect_list_iterate(plist, peffect) {
     if (faces != 0) {
@@ -833,9 +833,9 @@
   INIT;
 
   add_line(_("Wonders: "));
-  get_city_bonus_effects(plist, pcity, EFT_MAKE_HAPPY);
-  get_city_bonus_effects(plist, pcity, EFT_FORCE_CONTENT);
-  get_city_bonus_effects(plist, pcity, EFT_NO_UNHAPPY);
+  get_city_bonus_effects(plist, pcity, NULL, EFT_MAKE_HAPPY);
+  get_city_bonus_effects(plist, pcity, NULL, EFT_FORCE_CONTENT);
+  get_city_bonus_effects(plist, pcity, NULL, EFT_NO_UNHAPPY);
 
   effect_list_iterate(plist, peffect) {
     if (faces != 0) {
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.334
diff -u -r1.334 city.c
--- common/city.c       29 Apr 2005 01:52:09 -0000      1.334
+++ common/city.c       29 Apr 2005 05:14:30 -0000
@@ -41,7 +41,18 @@
 struct citystyle *city_styles = NULL;
 
 int city_tiles;
+
+/* One day these values may be read in from the ruleset.  In the meantime
+ * they're just an easy way to access information about each output type. */
 const Output_type_id num_output_types = O_LAST;
+struct output_type output_types[O_LAST] = {
+  {O_FOOD, "Food", "food"},
+  {O_SHIELD, "Shield", "shield"},
+  {O_TRADE, "Trade", "trade"},
+  {O_GOLD, "Gold", "gold"},
+  {O_LUXURY, "Luxury", "luxury"},
+  {O_SCIENCE, "Science", "science"}
+};
 
 /**************************************************************************
   Return TRUE if the given city coordinate pair is "valid"; that is, if it
@@ -223,24 +234,11 @@
 *****************************************************************************/
 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;
+  if (output < 0 || output >= O_LAST) {
+    assert(0);
+    return NULL;
   }
-  die("Unknown output type in get_output_id: %d", output);
-  return NULL;
+  return output_types[output].id;
 }
 
 /****************************************************************************
@@ -249,171 +247,29 @@
 *****************************************************************************/
 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;
-}
-
-/**************************************************************************
-  Return the effect for the production bonus for this output type.
-**************************************************************************/
-inline enum effect_type get_output_bonus_effect(Output_type_id otype,
-                                               int priority)
-{
-  switch (priority) {
-  case 0:
-    switch (otype) {
-    case O_FOOD:
-      return EFT_FOOD_BONUS;
-    case O_SHIELD:
-      return EFT_PROD_BONUS;
-    case O_TRADE:
-      return EFT_TRADE_BONUS;
-    case O_GOLD:
-      return EFT_TAX_BONUS;
-    case O_LUXURY:
-      return EFT_LUXURY_BONUS;
-    case O_SCIENCE:
-      return EFT_SCIENCE_BONUS;
-    case O_LAST:
-      break;
-    }
-    break;
-  case 1:
-    switch (otype) {
-    case O_FOOD:
-      return EFT_FOOD_BONUS_2;
-    case O_SHIELD:
-      return EFT_PROD_BONUS_2;
-    case O_TRADE:
-      return EFT_TRADE_BONUS_2;
-    case O_GOLD:
-      return EFT_TAX_BONUS_2;
-    case O_LUXURY:
-      return EFT_LUXURY_BONUS_2;
-    case O_SCIENCE:
-      return EFT_SCIENCE_BONUS_2;
-    case O_LAST:
-      break;
-    }
-    break;
-  }
-  assert(0);
-  return EFT_LAST;
-}
-
-/**************************************************************************
-  Return the effect for waste reduction for this output type.
-**************************************************************************/
-static inline enum effect_type get_output_waste_effect(Output_type_id otype)
-{
-  switch (otype) {
-  case O_SHIELD:
-    return EFT_WASTE_PCT;
-  case O_TRADE:
-    return EFT_CORRUPT_PCT;
-  case O_FOOD:
-  case O_GOLD:
-  case O_LUXURY:
-  case O_SCIENCE:
-    return EFT_LAST;
-  case O_LAST:
-    break;
-  }
-
-  assert(0);
-  return EFT_LAST;
-}
-
-/**************************************************************************
-  Return the effect for add-tile city bonuses for this output type.
-**************************************************************************/
-static inline enum effect_type get_output_add_tile_effect(Output_type_id o)
-{
-  switch (o) {
-  case O_FOOD:
-    return EFT_FOOD_ADD_TILE;
-  case O_SHIELD:
-    return EFT_PROD_ADD_TILE;
-  case O_TRADE:
-    return EFT_TRADE_ADD_TILE;
-  case O_GOLD:
-  case O_LUXURY:
-  case O_SCIENCE:
-    return EFT_LAST;
-  case O_LAST:
-    break;
+  if (output < 0 || output >= O_LAST) {
+    assert(0);
+    return NULL;
   }
-
-  assert(0);
-  return EFT_LAST;
+  return _(output_types[output].name);
 }
 
 /**************************************************************************
-  Return the effect for inc-tile city bonuses for this output type.
+  Find the output type for this output identifier.
 **************************************************************************/
-static inline enum effect_type get_output_inc_tile_effect(Output_type_id o)
+Output_type_id find_output_type_by_identifier(const char *id)
 {
-  switch (o) {
-  case O_FOOD:
-    return EFT_FOOD_INC_TILE;
-  case O_SHIELD:
-    return EFT_PROD_INC_TILE;
-  case O_TRADE:
-    return EFT_TRADE_INC_TILE;
-  case O_GOLD:
-  case O_LUXURY:
-  case O_SCIENCE:
-    return EFT_LAST;
-  case O_LAST:
-    break;
-  }
-
-  assert(0);
-  return EFT_LAST;
-}
+  Output_type_id o;
 
-/**************************************************************************
-  Return the effect for per-tile city bonuses for this output type.
-**************************************************************************/
-static inline enum effect_type get_output_per_tile_effect(Output_type_id o)
-{
-  switch (o) {
-  case O_FOOD:
-    return EFT_FOOD_PER_TILE;
-  case O_SHIELD:
-    return EFT_PROD_PER_TILE;
-  case O_TRADE:
-    return EFT_TRADE_PER_TILE;
-  case O_GOLD:
-  case O_LUXURY:
-  case O_SCIENCE:
-    return EFT_LAST;
-  case O_LAST:
-    break;
+  for (o = 0; o < O_LAST; o++) {
+    if (mystrcasecmp(output_types[o].name, id) == 0) {
+      return o;
+    }
   }
 
-  assert(0);
-  return EFT_LAST;
+  return O_LAST;
 }
 
-
-
 /**************************************************************************
   Set the worker on the citymap.  Also sets the worked field in the map.
 **************************************************************************/
@@ -540,7 +396,7 @@
     if (building->req[i].source.type == REQ_NONE) {
       break;
     }
-    if (!is_req_active(city_owner(pcity), pcity, 0, pcity->tile,
+    if (!is_req_active(city_owner(pcity), pcity, NULL, pcity->tile, NULL,
                       &building->req[i])) {
       return FALSE;
     }
@@ -587,7 +443,7 @@
       break;
     }
     if (is_req_unchanging(&building->req[r])
-       && !is_req_active(city_owner(pcity), pcity, NULL, pcity->tile,
+       && !is_req_active(city_owner(pcity), pcity, NULL, pcity->tile, NULL,
                          &building->req[r])) {
       return FALSE;
     }
@@ -665,7 +521,7 @@
 bool city_can_use_specialist(const struct city *pcity,
                             Specialist_type_id type)
 {
-  return are_reqs_active(city_owner(pcity), pcity, NULL, NULL,
+  return are_reqs_active(city_owner(pcity), pcity, NULL, NULL, NULL,
                         game.rgame.specialists[type].req, MAX_NUM_REQS);
 }
 
@@ -725,6 +581,7 @@
   const bool auto_water = (pcity && is_city_center(city_x, city_y)
                           && ptile->terrain == ptype->irrigation_result
                           && terrain_control.may_irrigate);
+  const struct output_type *output = &output_types[otype];
 
   assert(otype >= 0 && otype < O_LAST);
 
@@ -784,27 +641,21 @@
     int before_penalty = (is_celebrating
                          ? g->celeb_output_before_penalty[otype]
                          : g->output_before_penalty[otype]);
-    enum effect_type add = get_output_add_tile_effect(otype);
-    enum effect_type inc = get_output_inc_tile_effect(otype);
-    enum effect_type per = get_output_per_tile_effect(otype);
 
-    if (add != EFT_LAST) {
-      prod += get_city_tile_bonus(pcity, ptile, add);
-    }
+    prod += get_city_tile_output_bonus(pcity, ptile, output,
+                                      EFT_OUTPUT_ADD_TILE);
 
     /* Government & effect bonus/penalty. */
     if (prod > 0) {
       prod += (is_celebrating
            ? g->celeb_output_inc_tile[otype]
            : g->output_inc_tile[otype]);
-      if (inc != EFT_LAST) {
-       prod += get_city_tile_bonus(pcity, ptile, inc);
-      }
+      prod += get_city_tile_output_bonus(pcity, ptile, output,
+                                        EFT_OUTPUT_INC_TILE);
     }
 
-    if (per != EFT_LAST) {
-      prod += (prod * get_city_tile_bonus(pcity, ptile, per)) / 100;
-    }
+    prod += (prod * get_city_tile_output_bonus(pcity, ptile, output,
+                                              EFT_OUTPUT_PER_TILE)) / 100;
 
     if (before_penalty > 0 && prod > before_penalty) {
       prod--;
@@ -1255,7 +1106,7 @@
 
   while ((replace = city_styles[prev].replaced_by) != -1) {
     prev = replace;
-    if (are_reqs_active(plr, NULL, NULL, NULL,
+    if (are_reqs_active(plr, NULL, NULL, NULL, NULL,
                        city_styles[replace].req, MAX_NUM_REQS)) {
       style = replace;
     }
@@ -1593,17 +1444,13 @@
 **************************************************************************/
 int get_city_output_bonus(const struct city *pcity, Output_type_id otype)
 {
-  int bonus = 100, i;
-
-  for (i = 0; i < 2; i++) {
-    enum effect_type eft = get_output_bonus_effect(otype, i);
-
-    if (eft != EFT_LAST) {
-      bonus = bonus * (100 + get_city_bonus(pcity, eft)) / 100;
-    }
-  }
+  struct output_type *output = &output_types[otype];
+  int bonus1 = 100 + get_city_tile_output_bonus(pcity, NULL, output,
+                                               EFT_OUTPUT_BONUS);
+  int bonus2 = 100 + get_city_tile_output_bonus(pcity, NULL, output,
+                                               EFT_OUTPUT_BONUS_2);
 
-  return bonus;
+  return bonus1 * bonus2 / 100;
 }
 
 /**************************************************************************
@@ -2335,7 +2182,6 @@
   unsigned int val;
   int penalty = 0;
   struct gov_waste *waste = &g->waste[otype];
-  enum effect_type eft = get_output_waste_effect(otype);
 
   if (otype == O_TRADE) {
     /* FIXME: special case for trade: it is affected by notradesize and
@@ -2377,9 +2223,11 @@
   /* Now calculate the final waste.  Ordered to reduce integer
    * roundoff errors. */
   val = total * MAX(dist, 1) * waste->level;
-  if (eft != EFT_LAST) {
-    val -= (val * get_city_bonus(pcity, eft)) / 100;
-  }
+
+  /* FIXME: should be a get_city_output_bonus? */
+  val -= (val * get_city_tile_output_bonus(pcity, NULL, &output_types[otype],
+                                          EFT_OUTPUT_WASTE_PCT)) / 100;
+
   val /= 100 * 100; /* Level is a % multiplied by 100 */
   val = CLIP(penalty, val, total);
   return val;
Index: common/city.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.h,v
retrieving revision 1.207
diff -u -r1.207 city.h
--- common/city.h       26 Apr 2005 05:23:58 -0000      1.207
+++ common/city.h       29 Apr 2005 05:14:30 -0000
@@ -136,6 +136,12 @@
 }
 
 
+struct output_type {
+  int index;
+  const char *name; /* Untranslated name */
+  const char *id; /* Identifier string (for rulesets, etc.) */
+};
+
 enum choice_type { CT_NONE = 0, CT_BUILDING = 0, CT_NONMIL, CT_ATTACKER,
                    CT_DEFENDER, CT_LAST };
 
@@ -326,6 +332,7 @@
 
 extern struct citystyle *city_styles;
 extern const Output_type_id num_output_types;
+extern struct output_type output_types[];
 
 /* get 'struct city_list' and related functions: */
 #define SPECLIST_TAG city
@@ -354,8 +361,7 @@
 
 const char *get_output_identifier(Output_type_id output);
 const char *get_output_name(Output_type_id output);
-enum effect_type get_output_bonus_effect(Output_type_id otype,
-                                        int priority);
+Output_type_id find_output_type_by_identifier(const char *id);
 
 /* properties */
 
Index: common/effects.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/effects.c,v
retrieving revision 1.32
diff -u -r1.32 effects.c
--- common/effects.c    29 Apr 2005 01:52:09 -0000      1.32
+++ common/effects.c    29 Apr 2005 05:14:30 -0000
@@ -41,22 +41,19 @@
   "Airlift",
   "Any_Government",
   "Capital_City",
-  "Corrupt_Pct",
-  "Waste_Pct",
   "Enable_Nuke",
   "Enable_Space",
-  "Food_Add_Tile",
-  "Food_Bonus",
-  /* TODO: "Food_Pct", */
-  "Food_Inc_Tile",
-  "Food_Per_Tile",
+  "Output_Bonus",
+  "Output_Bonus_2",
+  "Output_Add_Tile",
+  "Output_Inc_Tile",
+  "Output_Per_Tile",
+  "Output_Waste_Pct",
   "Force_Content",
   /* TODO: "Force_Content_Pct", */
   "Give_Imm_Tech",
   "Growth_Food",
   "Have_Embassies",
-  "Luxury_Bonus",
-  /* TODO: "Luxury_Pct", */
   "Make_Content",
   "Make_Content_Mil",
   "Make_Content_Mil_Per",
@@ -71,37 +68,17 @@
   "Pollu_Pop_Pct",
   /* TODO: "Pollu_Prod_Adj", */
   "Pollu_Prod_Pct",
-  "Prod_Add_Tile",
-  "Prod_Bonus",
-  /* TODO: "Prod_Pct", */
-  "Prod_Inc_Tile",
-  "Prod_Per_Tile",
   "Prod_To_Gold",
   "Reveal_Cities",
   "Reveal_Map",
   /* TODO: "Incite_Dist_Adj", */
   "Incite_Dist_Pct",
-  "Science_Bonus",
-  /* TODO: "Science_Pct", */
   "Size_Adj",
   "Size_Unlimit",
   "SS_Structural",
   "SS_Component",
   "SS_Module",
   "Spy_Resistant",
-  "Tax_Bonus",
-  /* TODO: "Tax_Pct", */
-  "Trade_Add_Tile",
-  "Trade_Bonus",
-  /* TODO: "Trade_Pct", */
-  "Trade_Inc_Tile",
-  "Trade_Per_Tile",
-  "Food_Bonus_2",
-  "Prod_Bonus_2",
-  "Trade_Bonus_2",
-  "Tax_Bonus_2",
-  "Luxury_Bonus_2",
-  "Science_Bonus_2",
   "Sea_Move",
   "Unit_No_Lose_Pop",
   "Unit_Recover",
@@ -558,11 +535,12 @@
                        const struct city *target_city,
                        const struct impr_type *target_building,
                        const struct tile *target_tile,
+                       const struct output_type *target_output,
                        const struct effect *peffect)
 {
   requirement_list_iterate(peffect->nreqs, preq) {
     if (is_req_active(target_player, target_city, target_building,
-                     target_tile, preq)) {
+                     target_tile, target_output, preq)) {
       return TRUE;
     }
   } requirement_list_iterate_end;
@@ -578,11 +556,12 @@
                              const struct city *target_city,
                              const struct impr_type *target_building,
                              const struct tile *target_tile,
+                             const struct output_type *target_output,
                              const struct effect *peffect)
 {
   requirement_list_iterate(peffect->reqs, preq) {
     if (!is_req_active(target_player, target_city, target_building,
-                      target_tile, preq)) {
+                      target_tile, target_output, preq)) {
       return FALSE;
     }
   } requirement_list_iterate_end;
@@ -602,12 +581,13 @@
                             const struct city *target_city,
                             const struct impr_type *target_building,
                             const struct tile *target_tile,
+                            const struct output_type *target_output,
                             const struct effect *peffect)
 {
   return is_effect_enabled(target_player, target_city, target_building,
-                          target_tile, peffect)
+                          target_tile, target_output, peffect)
     && !is_effect_disabled(target_player, target_city, target_building,
-                          target_tile, peffect);
+                          target_tile, target_output, peffect);
 }
 
 /**************************************************************************
@@ -626,10 +606,12 @@
                      const struct city *target_city,
                      const struct impr_type *target_building,
                      const struct tile *target_tile,
+                     const struct output_type *target_output,
                      Impr_Type_id source, const struct effect *peffect)
 {
   if (is_effect_disabled(target_player, target_city,
-                        target_building, target_tile, peffect)) {
+                        target_building, target_tile, target_output,
+                        peffect)) {
     return FALSE;
   }
   requirement_list_iterate(peffect->reqs, preq) {
@@ -638,7 +620,7 @@
       continue;
     }
     if (!is_req_active(target_player, target_city, target_building,
-                      target_tile, preq)) {
+                      target_tile, target_output, preq)) {
       return FALSE;
     }
   } requirement_list_iterate_end;
@@ -669,7 +651,8 @@
      * the building is its own target - but whether this is actually
      * checked depends on the range of the effect. */
     if (!is_effect_disabled(city_owner(pcity), pcity,
-                           get_improvement_type(building), NULL, peffect)) {
+                           get_improvement_type(building), NULL, NULL,
+                           peffect)) {
       return FALSE;
     }
   } effect_list_iterate_end;
@@ -693,6 +676,7 @@
                                    const struct city *target_city,
                                    const struct impr_type *target_building,
                                    const struct tile *target_tile,
+                                   const struct output_type *target_output,
                                    enum effect_type effect_type)
 {
   int bonus = 0;
@@ -701,7 +685,8 @@
   effect_list_iterate(get_effects(effect_type), peffect) {
     /* For each effect, see if it is active. */
     if (is_effect_active(target_player, target_city,
-                        target_building, target_tile, peffect)) {
+                        target_building, target_tile, target_output,
+                        peffect)) {
       /* And if so add on the value. */
       bonus += peffect->value;
 
@@ -719,8 +704,8 @@
 **************************************************************************/
 int get_world_bonus(enum effect_type effect_type)
 {
-  return get_target_bonus_effects(NULL,
-                                 NULL, NULL, NULL, NULL, effect_type);
+  return get_target_bonus_effects(NULL, NULL, NULL, NULL, NULL, NULL,
+                                 effect_type);
 }
 
 /**************************************************************************
@@ -730,8 +715,7 @@
                     enum effect_type effect_type)
 {
   assert(pplayer != NULL);
-  return get_target_bonus_effects(NULL,
-                                 pplayer, NULL, NULL, NULL,
+  return get_target_bonus_effects(NULL, pplayer, NULL, NULL, NULL, NULL,
                                  effect_type);
 }
 
@@ -742,19 +726,23 @@
 {
   assert(pcity != NULL);
   return get_target_bonus_effects(NULL,
-                                 city_owner(pcity), pcity, NULL, NULL,
+                                 city_owner(pcity), pcity, NULL, NULL, NULL,
                                  effect_type);
 }
 
 /**************************************************************************
-  Returns the effect bonus at a city tile.
+  Returns the effect bonus at a city tile.  Tile may be NULL for city-
+  wide output bonuses, or output may be NULL for non-output tile bonuses.
 **************************************************************************/
-int get_city_tile_bonus(const struct city *pcity, const struct tile *ptile,
-                       enum effect_type effect_type)
+int get_city_tile_output_bonus(const struct city *pcity,
+                              const struct tile *ptile,
+                              const struct output_type *poutput,
+                              enum effect_type effect_type)
 {
-  assert(pcity != NULL && ptile != NULL);
+  assert(pcity != NULL);
   return get_target_bonus_effects(NULL,
                                  city_owner(pcity), pcity, NULL, ptile,
+                                 poutput,
                                  effect_type);
 }
 
@@ -767,7 +755,7 @@
   assert(pcity != NULL && id != B_LAST);
   return get_target_bonus_effects(NULL,
                                  city_owner(pcity), pcity,
-                                 get_improvement_type(id), NULL,
+                                 get_improvement_type(id), NULL, NULL,
                                  effect_type);
 }
 
@@ -783,7 +771,7 @@
 {
   assert(pplayer != NULL);
   return get_target_bonus_effects(plist,
-                                 pplayer, NULL, NULL, NULL,
+                                 pplayer, NULL, NULL, NULL, NULL,
                                  effect_type);
 }
 
@@ -795,11 +783,13 @@
 **************************************************************************/
 int get_city_bonus_effects(struct effect_list *plist,
                           const struct city *pcity,
+                          const struct output_type *poutput,
                           enum effect_type effect_type)
 {
   assert(pcity != NULL);
   return get_target_bonus_effects(plist,
                                  city_owner(pcity), pcity, NULL, NULL,
+                                 poutput,
                                  effect_type);
 }
 
@@ -830,7 +820,7 @@
          continue;
        }
        if (is_effect_useful(city_owner(pcity),
-                            pcity, building, NULL, id, peffect)) {
+                            pcity, building, NULL, NULL, id, peffect)) {
          power += peffect->value;
        }
       } effect_list_iterate_end;
Index: common/effects.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/effects.h,v
retrieving revision 1.19
diff -u -r1.19 effects.h
--- common/effects.h    29 Apr 2005 01:52:09 -0000      1.19
+++ common/effects.h    29 Apr 2005 05:14:30 -0000
@@ -28,22 +28,19 @@
   EFT_AIRLIFT,
   EFT_ANY_GOVERNMENT,
   EFT_CAPITAL_CITY,
-  EFT_CORRUPT_PCT,
-  EFT_WASTE_PCT,
   EFT_ENABLE_NUKE,
   EFT_ENABLE_SPACE,
-  EFT_FOOD_ADD_TILE,
-  EFT_FOOD_BONUS,
-  /*TODO: EFT_FOOD_PCT, */
-  EFT_FOOD_INC_TILE,
-  EFT_FOOD_PER_TILE,
+  EFT_OUTPUT_BONUS,
+  EFT_OUTPUT_BONUS_2,
+  EFT_OUTPUT_ADD_TILE,
+  EFT_OUTPUT_INC_TILE,
+  EFT_OUTPUT_PER_TILE,
+  EFT_OUTPUT_WASTE_PCT,
   EFT_FORCE_CONTENT,
   /* TODO: EFT_FORCE_CONTENT_PCT, */
   EFT_GIVE_IMM_TECH,
   EFT_GROWTH_FOOD,
   EFT_HAVE_EMBASSIES,
-  EFT_LUXURY_BONUS,
-  /* TODO: EFT_LUXURY_PCT, */
   EFT_MAKE_CONTENT,
   EFT_MAKE_CONTENT_MIL,
   EFT_MAKE_CONTENT_MIL_PER,
@@ -58,37 +55,18 @@
   EFT_POLLU_POP_PCT,
   /* TODO: EFT_POLLU_PROD_ADJ, */
   EFT_POLLU_PROD_PCT,
-  EFT_PROD_ADD_TILE,
-  EFT_PROD_BONUS,
   /* TODO: EFT_PROD_PCT, */
-  EFT_PROD_INC_TILE,
-  EFT_PROD_PER_TILE,
   EFT_PROD_TO_GOLD,
   EFT_REVEAL_CITIES,
   EFT_REVEAL_MAP,
   /* TODO: EFT_INCITE_DIST_ADJ, */
   EFT_INCITE_DIST_PCT,
-  EFT_SCIENCE_BONUS,
-  /* TODO: EFT_SCIENCE_PCT, */
   EFT_SIZE_ADJ,
   EFT_SIZE_UNLIMIT,
   EFT_SS_STRUCTURAL,
   EFT_SS_COMPONENT,
   EFT_SS_MODULE,
   EFT_SPY_RESISTANT,
-  EFT_TAX_BONUS,
-  /* TODO: EFT_TAX_PCT, */
-  EFT_TRADE_ADD_TILE,
-  EFT_TRADE_BONUS,
-  /* TODO: EFT_TRADE_PCT, */
-  EFT_TRADE_INC_TILE,
-  EFT_TRADE_PER_TILE,
-  EFT_FOOD_BONUS_2,
-  EFT_PROD_BONUS_2,
-  EFT_TRADE_BONUS_2,
-  EFT_TAX_BONUS_2,
-  EFT_LUXURY_BONUS_2,
-  EFT_SCIENCE_BONUS_2,
   EFT_SEA_MOVE,
   EFT_UNIT_NO_LOSE_POP,
   EFT_UNIT_RECOVER,
@@ -167,6 +145,7 @@
                      const struct city *target_pcity,
                      const struct impr_type *target_building,
                      const struct tile *target_tile,
+                     const struct output_type *target_output,
                      Impr_Type_id source, const struct effect *effect);
 
 bool is_building_replaced(const struct city *pcity, Impr_Type_id building);
@@ -175,8 +154,10 @@
 int get_world_bonus(enum effect_type effect_type);
 int get_player_bonus(const struct player *plr, enum effect_type effect_type);
 int get_city_bonus(const struct city *pcity, enum effect_type effect_type);
-int get_city_tile_bonus(const struct city *pcity, const struct tile *ptile,
-                       enum effect_type effect_type);
+int get_city_tile_output_bonus(const struct city *pcity,
+                              const struct tile *ptile,
+                              const struct output_type *poutput,
+                              enum effect_type effect_type);
 int get_building_bonus(const struct city *pcity, Impr_Type_id building,
                       enum effect_type effect_type);
 
@@ -186,12 +167,15 @@
                        const struct city *target_city,
                        const struct impr_type *target_building,
                        const struct tile *target_tile,
+                       const struct output_type *target_output,
                        const struct effect *peffect);
 
 int get_player_bonus_effects(struct effect_list *plist,
     const struct player *pplayer, enum effect_type effect_type);
 int get_city_bonus_effects(struct effect_list *plist,
-    const struct city *pcity, enum effect_type effect_type);
+                          const struct city *pcity,
+                          const struct output_type *poutput,
+                          enum effect_type effect_type);
 
 bool building_has_effect(Impr_Type_id building,
                         enum effect_type effect_type);
Index: common/fc_types.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/fc_types.h,v
retrieving revision 1.21
diff -u -r1.21 fc_types.h
--- common/fc_types.h   29 Apr 2005 01:52:09 -0000      1.21
+++ common/fc_types.h   29 Apr 2005 05:14:30 -0000
@@ -35,7 +35,7 @@
 #define MAX_LEN_VET_SHORT_NAME 8
 #define MAX_VET_LEVELS 10
 
-enum output_type {
+enum output_type_id {
   O_FOOD, O_SHIELD, O_TRADE, O_GOLD, O_LUXURY, O_SCIENCE, O_LAST
 };
 #define O_COUNT num_output_types
@@ -45,7 +45,7 @@
 typedef int Terrain_type_id;
 typedef int Specialist_type_id;
 typedef int Impr_Type_id;
-typedef enum output_type Output_type_id;
+typedef enum output_type_id Output_type_id;
 typedef enum unit_activity Activity_type_id;
 typedef int Nation_Type_id;
 typedef int Team_Type_id;
@@ -57,6 +57,7 @@
 struct tile;
 struct unit;
 struct impr_type;
+struct output_type;
 
 /* Changing these will break network compatibility. */
 #define SP_MAX 20
Index: common/government.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/government.c,v
retrieving revision 1.53
diff -u -r1.53 government.c
--- common/government.c 29 Apr 2005 01:52:09 -0000      1.53
+++ common/government.c 29 Apr 2005 05:14:30 -0000
@@ -204,7 +204,7 @@
     return TRUE;
   }
 
-  return are_reqs_active(pplayer, NULL, NULL, NULL,
+  return are_reqs_active(pplayer, NULL, NULL, NULL, NULL,
                         gov->req, MAX_NUM_REQS);
 }
 
Index: common/improvement.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/improvement.c,v
retrieving revision 1.56
diff -u -r1.56 improvement.c
--- common/improvement.c        29 Apr 2005 01:52:09 -0000      1.56
+++ common/improvement.c        29 Apr 2005 05:14:32 -0000
@@ -308,7 +308,7 @@
       break;
     }
     if (impr->req[i].range >= REQ_RANGE_PLAYER
-       && !is_req_active(p, NULL, 0, NULL, &impr->req[i])) {
+       && !is_req_active(p, NULL, NULL, NULL, NULL, &impr->req[i])) {
       return FALSE;
     }
   }
@@ -392,7 +392,8 @@
     }
     if (building->req[r].range >= REQ_RANGE_PLAYER
        && is_req_unchanging(&building->req[r])
-       && !is_req_active(p, NULL, NULL, NULL, &building->req[r])) {
+       && !is_req_active(p, NULL, NULL, NULL, NULL,
+                         &building->req[r])) {
       return FALSE;
     }
   }
Index: common/requirements.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.c,v
retrieving revision 1.17
diff -u -r1.17 requirements.c
--- common/requirements.c       29 Apr 2005 01:52:09 -0000      1.17
+++ common/requirements.c       29 Apr 2005 05:14:32 -0000
@@ -35,6 +35,7 @@
   "Special",
   "Terrain",
   "Nation",
+  "Output",
   "MinSize"
 };
 
@@ -135,6 +136,12 @@
       return source;
     }
     break;
+  case REQ_OUTPUT:
+    source.value.output_type = find_output_type_by_identifier(value);
+    if (source.value.output_type != O_LAST) {
+      return source;
+    }
+    break;
   case REQ_MINSIZE:
     source.value.minsize = atoi(value);
     if (source.value.minsize > 0) {
@@ -181,6 +188,9 @@
   case REQ_NATION:
     source.value.nation = value;
     return source;
+  case REQ_OUTPUT:
+    source.value.output_type = value;
+    return source;
   case REQ_MINSIZE:
     source.value.minsize = value;
     return source;
@@ -224,6 +234,9 @@
   case REQ_NATION:
     *value = source->value.nation;
     return;
+  case REQ_OUTPUT:
+    *value = source->value.output_type;
+    return;
   case REQ_MINSIZE:
     *value = source->value.minsize;
     return;
@@ -262,6 +275,7 @@
     case REQ_BUILDING:
     case REQ_SPECIAL:
     case REQ_TERRAIN:
+    case REQ_OUTPUT:
       req.range = REQ_RANGE_LOCAL;
       break;
     case REQ_MINSIZE:
@@ -304,6 +318,9 @@
     invalid = (req.range != REQ_RANGE_PLAYER
               && req.range != REQ_RANGE_WORLD);
     break;
+  case REQ_OUTPUT:
+    invalid = (req.range != REQ_RANGE_LOCAL);
+    break;
   case REQ_NONE:
     invalid = FALSE;
     break;
@@ -643,6 +660,7 @@
                   const struct city *target_city,
                   const struct impr_type *target_building,
                   const struct tile *target_tile,
+                  const struct output_type *target_output,
                   const struct requirement *req)
 {
   /* Note the target may actually not exist.  In particular, effects that
@@ -679,6 +697,9 @@
   case REQ_NATION:
     return is_nation_in_range(target_player, req->range, req->survives,
                              req->source.value.nation);
+  case REQ_OUTPUT:
+    return (target_output
+           && target_output->index == req->source.value.output_type);
   case REQ_MINSIZE:
     return target_city && target_city->size >= req->source.value.minsize;
   case REQ_LAST:
@@ -707,6 +728,7 @@
                     const struct city *target_city,
                     const struct impr_type *target_building,
                     const struct tile *target_tile,
+                    const struct output_type *target_output,
                     const struct requirement *reqs, int num_reqs)
 {
   int i;
@@ -715,7 +737,7 @@
     if (reqs[i].source.type == REQ_NONE) {
       break; /* Short-circuit any more checks. */
     } else if (!is_req_active(target_player, target_city,
-                             target_building, target_tile,
+                             target_building, target_tile, target_output,
                              &reqs[i])) {
       return FALSE;
     }
@@ -739,6 +761,7 @@
   switch (req->source.type) {
   case REQ_NATION:
   case REQ_NONE:
+  case REQ_OUTPUT:
     return TRUE;
   case REQ_TECH:
   case REQ_GOV:
@@ -784,6 +807,8 @@
     return psource1->value.terrain == psource2->value.terrain;
   case REQ_NATION:
     return psource1->value.nation == psource2->value.nation;
+  case REQ_OUTPUT:
+    return psource1->value.output_type == psource2->value.output_type;
   case REQ_MINSIZE:
     return psource1->value.minsize == psource2->value.minsize;
   case REQ_LAST:
@@ -823,6 +848,9 @@
   case REQ_NATION:
     mystrlcat(buf, get_nation_name(psource->value.nation), bufsz);
     break;
+  case REQ_OUTPUT:
+    mystrlcat(buf, get_output_name(psource->value.output_type), bufsz);
+    break;
   case REQ_MINSIZE:
     cat_snprintf(buf, bufsz, "Size %d", psource->value.minsize);
     break;
Index: common/requirements.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.h,v
retrieving revision 1.12
diff -u -r1.12 requirements.h
--- common/requirements.h       29 Apr 2005 01:52:09 -0000      1.12
+++ common/requirements.h       29 Apr 2005 05:14:32 -0000
@@ -27,6 +27,7 @@
   REQ_SPECIAL,
   REQ_TERRAIN,
   REQ_NATION,
+  REQ_OUTPUT,
   REQ_MINSIZE, /* Minimum size: at city range means city size */
   REQ_LAST
 };
@@ -54,6 +55,7 @@
     enum tile_special_type special;     /* source special */
     Terrain_type_id terrain;            /* source terrain type */
     Nation_Type_id nation;              /* source nation type */
+    Output_type_id output_type;         /* source output type */
     int minsize;                        /* source minsize type */
   } value;                              /* source value */
 };
@@ -100,11 +102,13 @@
                   const struct city *target_city,
                   const struct impr_type *target_building,
                   const struct tile *target_tile,
+                  const struct output_type *target_output,
                   const struct requirement *req);
 bool are_reqs_active(const struct player *target_player,
                     const struct city *target_city,
                     const struct impr_type *target_building,
                     const struct tile *target_tile,
+                    const struct output_type *target_output,
                     const struct requirement *reqs, int num_reqs);
 
 bool is_req_unchanging(const struct requirement *req);
Index: data/default/effects.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/effects.ruleset,v
retrieving revision 1.6
diff -u -r1.6 effects.ruleset
--- data/default/effects.ruleset        21 Apr 2005 22:53:13 -0000      1.6
+++ data/default/effects.ruleset        29 Apr 2005 05:14:32 -0000
@@ -63,21 +63,23 @@
     }
 
 [effect_bank]
-name   = "Tax_Bonus"
+name   = "Output_Bonus"
 value  = 50
 reqs   =
     { "type", "name", "range"
       "Building", "Marketplace", "City"
       "Building", "Bank", "City"
+      "Output", "Gold", "Local"
     }
 
 [effect_bank_1]
-name   = "Luxury_Bonus"
+name   = "Output_Bonus"
 value  = 50
 reqs   =
     { "type", "name", "range"
       "Building", "Marketplace", "City"
       "Building", "Bank", "City"
+      "Output", "Luxury", "Local"
     }
 
 [effect_barracks]
@@ -212,28 +214,29 @@
     }
 
 [effect_courthouse]
-name   = "Corrupt_Pct"
+name   = "Output_Waste_Pct"
 value  = 50
 reqs   =
     { "type", "name", "range"
       "Building", "Courthouse", "City"
+      "Output", "Trade", "Local"
     }
 nreqs  =
     { "type", "name", "range"
       "Building", "Palace", "City"
     }
 
-[effect_courthouse_1]
-name   = "Waste_Pct"
-value  = 50
-reqs   =
-    { "type", "name", "range"
-      "Building", "Courthouse", "City"
-    }
-nreqs  =
-    { "type", "name", "range"
-      "Building", "Palace", "City"
-    }
+;[effect_courthouse_1]
+;name  = "Waste_Pct"
+;value = 50
+;reqs  =
+;    { "type", "name", "range"
+;      "Building", "Courthouse", "City"
+;    }
+;nreqs =
+;    { "type", "name", "range"
+;      "Building", "Palace", "City"
+;    }
 
 [effect_courthouse_2]
 name   = "Make_Content"
@@ -253,11 +256,12 @@
     }
 
 [effect_factory]
-name   = "Prod_Bonus"
+name   = "Output_Bonus"
 value  = 50
 reqs   =
     { "type", "name", "range"
       "Building", "Factory", "City"
+      "Output", "Shield", "Local"
     }
 
 [effect_granary]
@@ -269,21 +273,23 @@
     }
 
 [effect_harbour]
-name   = "Food_Add_Tile"
+name   = "Output_Add_Tile"
 value  = 1
 reqs   =
     { "type", "name", "range"
       "Terrain", "Ocean", "Local"
       "Building", "Harbour", "City"
+      "Output", "Food", "Local"
     }
 
 [effect_hydro_plant]
-name   = "Prod_Bonus"
+name   = "Output_Bonus"
 value  = 25
 reqs   =
     { "type", "name", "range"
       "Building", "Factory", "City"
       "Building", "Hydro Plant", "City"
+      "Output", "Shield", "Local"
     }
 nreqs  =
     { "type", "name", "range"
@@ -292,12 +298,13 @@
     }
 
 [effect_hydro_plant_1]
-name   = "Prod_Bonus"
+name   = "Output_Bonus"
 value  = 25
 reqs   =
     { "type", "name", "range"
       "Building", "Mfg. Plant", "City"
       "Building", "Hydro Plant", "City"
+      "Output", "Shield", "Local"
     }
 nreqs  =
     { "type", "name", "range"
@@ -336,27 +343,30 @@
     }
 
 [effect_library]
-name   = "Science_Bonus"
+name   = "Output_Bonus"
 value  = 100
 reqs   =
     { "type", "name", "range"
       "Building", "Library", "City"
+      "Output", "Science", "Local"
     }
 
 [effect_marketplace]
-name   = "Tax_Bonus"
+name   = "Output_Bonus"
 value  = 50
 reqs   =
     { "type", "name", "range"
       "Building", "Marketplace", "City"
+      "Output", "Gold", "Local"
     }
 
 [effect_marketplace_1]
-name   = "Luxury_Bonus"
+name   = "Output_Bonus"
 value  = 50
 reqs   =
     { "type", "name", "range"
       "Building", "Marketplace", "City"
+      "Output", "Luxury", "Local"
     }
 
 [effect_mass_transit]
@@ -368,21 +378,23 @@
     }
 
 [effect_mfg_plant]
-name   = "Prod_Bonus"
+name   = "Output_Bonus"
 value  = 50
 reqs   =
     { "type", "name", "range"
       "Building", "Factory", "City"
       "Building", "Mfg. Plant", "City"
+      "Output", "Shield", "Local"
     }
 
 [effect_nuclear_plant]
-name   = "Prod_Bonus"
+name   = "Output_Bonus"
 value  = 25
 reqs   =
     { "type", "name", "range"
       "Building", "Factory", "City"
       "Building", "Nuclear Plant", "City"
+      "Output", "Shield", "Local"
     }
 nreqs  =
     { "type", "name", "range"
@@ -390,12 +402,13 @@
     }
 
 [effect_nuclear_plant_1]
-name   = "Prod_Bonus"
+name   = "Output_Bonus"
 value  = 25
 reqs   =
     { "type", "name", "range"
       "Building", "Mfg. Plant", "City"
       "Building", "Nuclear Plant", "City"
+      "Output", "Shield", "Local"
     }
 nreqs  =
     { "type", "name", "range"
@@ -431,29 +444,31 @@
     }
 
 [effect_offshore_platform]
-name   = "Prod_Add_Tile"
+name   = "Output_Add_Tile"
 value  = 1
 reqs   =
     { "type", "name", "range"
       "Terrain", "Ocean", "Local"
       "Building", "Offshore Platform", "City"
+      "Output", "Shield", "Local"
     }
 
 [effect_palace]
-name   = "Corrupt_Pct"
+name   = "Output_Waste_Pct"
 value  = 50
 reqs   =
     { "type", "name", "range"
       "Building", "Palace", "City"
+      "Output", "Trade", "Local"
     }
 
-[effect_palace_1]
-name   = "Waste_Pct"
-value  = 50
-reqs   =
-    { "type", "name", "range"
-      "Building", "Palace", "City"
-    }
+;[effect_palace_1]
+;name  = "Waste_Pct"
+;value = 50
+;reqs  =
+;    { "type", "name", "range"
+;      "Building", "Palace", "City"
+;    }
 
 [effect_palace_2]
 name   = "Spy_Resistant"
@@ -522,12 +537,13 @@
     }
 
 [effect_power_plant]
-name   = "Prod_Bonus"
+name   = "Output_Bonus"
 value  = 25
 reqs   =
     { "type", "name", "range"
       "Building", "Factory", "City"
       "Building", "Power Plant", "City"
+      "Output", "Shield", "Local"
     }
 nreqs  =
     { "type", "name", "range"
@@ -537,12 +553,13 @@
     }
 
 [effect_power_plant_1]
-name   = "Prod_Bonus"
+name   = "Output_Bonus"
 value  = 25
 reqs   =
     { "type", "name", "range"
       "Building", "Mfg. Plant", "City"
       "Building", "Power Plant", "City"
+      "Output", "Shield", "Local"
     }
 nreqs  =
     { "type", "name", "range"
@@ -560,21 +577,23 @@
     }
 
 [effect_research_lab]
-name   = "Science_Bonus"
+name   = "Output_Bonus"
 value  = 100
 reqs   =
     { "type", "name", "range"
       "Building", "Library", "City"
       "Building", "Research Lab", "City"
+      "Output", "Science", "Local"
     }
 
 [effect_research_lab_1]
-name   = "Science_Bonus"
+name   = "Output_Bonus"
 value  = 100
 reqs   =
     { "type", "name", "range"
       "Building", "University", "City"
       "Building", "Research Lab", "City"
+      "Output", "Science", "Local"
     }
 
 [effect_sam_battery]
@@ -659,39 +678,43 @@
     }
 
 [effect_stock_exchange]
-name   = "Tax_Bonus"
+name   = "Output_Bonus"
 value  = 50
 reqs   =
     { "type", "name", "range"
       "Building", "Bank", "City"
       "Building", "Stock Exchange", "City"
+      "Output", "Gold", "Local"
     }
 
 [effect_stock_exchange_1]
-name   = "Luxury_Bonus"
+name   = "Output_Bonus"
 value  = 50
 reqs   =
     { "type", "name", "range"
       "Building", "Bank", "City"
       "Building", "Stock Exchange", "City"
+      "Output", "Luxury", "Local"
     }
 
 [effect_super_highways]
-name   = "Trade_Per_Tile"
+name   = "Output_Per_Tile"
 value  = 50
 reqs   =
     { "type", "name", "range"
       "Special", "Road", "Local"
       "Building", "Super Highways", "City"
+      "Output", "Trade", "Local"
     }
 
 [effect_supermarket]
-name   = "Food_Per_Tile"
+name   = "Output_Per_Tile"
 value  = 50
 reqs   =
     { "type", "name", "range"
       "Special", "Farmland", "Local"
       "Building", "Supermarket", "City"
+      "Output", "Food", "Local"
     }
 
 [effect_temple]
@@ -712,12 +735,13 @@
     }
 
 [effect_university]
-name   = "Science_Bonus"
+name   = "Output_Bonus"
 value  = 150
 reqs   =
     { "type", "name", "range"
       "Building", "Library", "City"
       "Building", "University", "City"
+      "Output", "Science", "Local"
     }
 
 [effect_apollo_program]
@@ -745,19 +769,21 @@
     }
 
 [effect_colossus]
-name   = "Trade_Inc_Tile"
+name   = "Output_Inc_Tile"
 value  = 1
 reqs   =
     { "type", "name", "range"
       "Building", "Colossus", "City"
+      "Output", "Trade", "Local"
     }
 
 [effect_copernicus_observatory]
-name   = "Science_Bonus"
+name   = "Output_Bonus"
 value  = 100
 reqs   =
     { "type", "name", "range"
       "Building", "Copernicus' Observatory", "City"
+      "Output", "Science", "Local"
     }
 
 [effect_cure_for_cancer]
@@ -833,21 +859,23 @@
     }
 
 [effect_hoover_dam]
-name   = "Prod_Bonus"
+name   = "Output_Bonus"
 value  = 25
 reqs   =
     { "type", "name", "range"
       "Building", "Factory", "City"
       "Building", "Hoover Dam", "Player"
+      "Output", "Shield", "Local"
     }
 
 [effect_hoover_dam_1]
-name   = "Prod_Bonus"
+name   = "Output_Bonus"
 value  = 25
 reqs   =
     { "type", "name", "range"
       "Building", "Mfg. Plant", "City"
       "Building", "Hoover Dam", "Player"
+      "Output", "Shield", "Local"
     }
 
 [effect_hoover_dam_2]
@@ -877,12 +905,13 @@
     }
 
 [effect_isaac_newtons_college]
-name   = "Science_Bonus"
+name   = "Output_Bonus"
 value  = 100
 reqs   =
     { "type", "name", "range"
       "Building", "University", "City"
       "Building", "Isaac Newton's College", "Player"
+      "Output", "Science", "Local"
     }
 
 [effect_js_bachs_cathedral]
@@ -894,11 +923,12 @@
     }
 
 [effect_king_richards_crusade]
-name   = "Prod_Add_Tile"
+name   = "Output_Add_Tile"
 value  = 1
 reqs   =
     { "type", "name", "range"
       "Building", "King Richard's Crusade", "City"
+      "Output", "Shield", "Local"
     }
 
 [effect_leonardos_workshop]
@@ -1001,12 +1031,13 @@
     }
 
 [effect_seti_program]
-name   = "Science_Bonus"
+name   = "Output_Bonus"
 value  = 100
 reqs   =
     { "type", "name", "range"
       "Building", "Research Lab", "City"
       "Building", "SETI Program", "Player"
+      "Output", "Science", "Local"
     }
 
 [effect_shakespeares_theatre]
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.315
diff -u -r1.315 citytools.c
--- server/citytools.c  29 Apr 2005 01:52:10 -0000      1.315
+++ server/citytools.c  29 Apr 2005 05:14:34 -0000
@@ -2058,7 +2058,8 @@
          struct requirement *req = &get_improvement_type(impr)->req[r];
 
          if (req->source.type == REQ_TERRAIN
-             && !is_req_active(city_owner(pcity), pcity, NULL, NULL, req)) {
+             && !is_req_active(city_owner(pcity), pcity, NULL, NULL, NULL,
+                               req)) {
           do_sell_building(pplayer, pcity, impr);
           notify_player_ex(pplayer, tile1, E_IMP_SOLD,
                            _("You sell %s in %s (now landlocked)"
Index: server/cityturn.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/cityturn.c,v
retrieving revision 1.307
diff -u -r1.307 cityturn.c
--- server/cityturn.c   24 Apr 2005 06:18:28 -0000      1.307
+++ server/cityturn.c   29 Apr 2005 05:14:34 -0000
@@ -693,7 +693,7 @@
          if (req->source.type == REQ_NONE) {
            break;
          }
-         if (!is_req_active(pplayer, pcity, 0, NULL, req)) {
+         if (!is_req_active(pplayer, pcity, NULL, NULL, NULL, req)) {
            known = TRUE;
            switch (req->source.type) {
            case REQ_TECH:
@@ -748,6 +748,9 @@
                               get_impr_name_ex(pcity, target),
                               get_nation_name(req->source.value.nation));
              break;
+           case REQ_OUTPUT:
+             /* Should never happen. */
+             break;
            case REQ_MINSIZE:
              notify_player_ex(pplayer, pcity->tile, E_CITY_CANTBUILD,
                               _("%s can't build %s from the worklist; "
Index: server/score.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/score.c,v
retrieving revision 1.17
diff -u -r1.17 score.c
--- server/score.c      3 Feb 2005 09:51:51 -0000       1.17
+++ server/score.c      29 Apr 2005 05:14:34 -0000
@@ -412,7 +412,8 @@
     pplayer->score.bnp += pcity->surplus[O_TRADE];
     pplayer->score.mfg += pcity->surplus[O_SHIELD];
 
-    bonus = CLIP(0, get_city_bonus(pcity, EFT_SCIENCE_BONUS), 100);
+    bonus = get_city_output_bonus(pcity, O_SCIENCE) - 100;
+    bonus = CLIP(0, bonus, 100);
     pplayer->score.literacy += (city_population(pcity) * bonus) / 100;
   } city_list_iterate_end;
 

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#12930) RFC: generalizing output types in effects, Jason Short <=