diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/city.c freeciv-patched/common/city.c
--- freeciv-cvs/common/city.c	2003-07-10 11:53:00.000000000 +0100
+++ freeciv-patched/common/city.c	2003-07-10 11:53:12.000000000 +0100
@@ -1713,6 +1713,33 @@
   pcity->unlimit_impr = unlimit_impr;
 }
 
+static void update_bonus(int bonus[4], int amount, struct eff_iter *iter,
+    			 bool add_bonus)
+{
+  int bonusind = 0;
+
+  if (iter->imeff->outside) {
+    switch(iter->range) {
+    case EFR_ISLAND:
+      bonusind = 1;
+      break;
+    case EFR_PLAYER:
+      bonusind = 2;
+      break;
+    case EFR_WORLD:
+      bonusind = 3;
+      break;
+    default:
+      break;
+    }
+  }
+  if (add_bonus) {
+    bonus[bonusind] += amount;
+  } else {
+    bonus[bonusind] = bonus[bonusind] * amount / 100;
+  }
+}
+
 /**************************************************************************
   Updates the various modifiers and bonuses due to city improvements
   (should be called whenever city effects change - i.e. by
@@ -1720,10 +1747,12 @@
 **************************************************************************/
 void update_city_bonuses(struct city *pcity)
 {
-  int tax_bonus = 100, science_bonus = 100,   /* City bonuses */
-      shield_bonus = 100, luxury_bonus = 100;
-  int tax_pct = 100, science_pct = 100,       /* City bonus multipliers */
-      shield_pct = 100, luxury_pct = 100;
+  int tax_bonus[4] = { 100, 100, 100, 100 };
+  int science_bonus[4] = { 100, 100, 100, 100 };
+  int shield_bonus = 100, luxury_bonus = 100; /* City bonuses */
+  int tax_pct[4] = { 100, 100, 100, 100 };
+  int science_pct[4] = { 100, 100, 100, 100 };
+  int shield_pct = 100, luxury_pct = 100;     /* City bonus multipliers */
   int poppoladj = 100, prodpoladj = 100,      /* Pollution adjustments */
       poladj = 100;
   int poppolpct = 100, prodpolpct = 100,      /* Pollution multipliers */
@@ -1810,17 +1839,21 @@
 	  				     * amount / 100;
         break;
       case EFT_TAX_BONUS:
-        tax_bonus += amount; break;
+	update_bonus(tax_bonus, amount, &iter, TRUE);
+	break;
       case EFT_TAX_PCT:
-        tax_pct = tax_pct * amount / 100; break;
+	update_bonus(tax_pct, amount, &iter, FALSE);
+	break;
       case EFT_LUXURY_BONUS:
         luxury_bonus += amount; break;
       case EFT_LUXURY_PCT:
         luxury_pct = luxury_pct * amount / 100; break;
       case EFT_SCIENCE_BONUS:
-        science_bonus += amount; break;
+	update_bonus(science_bonus, amount, &iter, TRUE);
+	break;
       case EFT_SCIENCE_PCT:
-        science_pct = science_pct * amount / 100; break;
+	update_bonus(science_pct, amount, &iter, FALSE);
+	break;
       case EFT_PROD_BONUS:
         shield_bonus += amount; break;
       case EFT_PROD_PCT:
@@ -1887,8 +1920,10 @@
 
   /* Apply the multipliers to the bonuses (such that the bonuses are all
      summed first, and only then are the multipliers applied) */
-  tax_bonus = tax_bonus * tax_pct / 100;
-  science_bonus = science_bonus * science_pct / 100;
+  for (i = 0; i < 4; ++i) {
+    tax_bonus[i] = tax_bonus[i] * tax_pct[i] / 100;
+    science_bonus[i] = science_bonus[i] * science_pct[i] / 100;
+  }
   shield_bonus = shield_bonus * shield_pct / 100;
   luxury_bonus = luxury_bonus * luxury_pct / 100;
   makecontent = makecontent * makecontentpct / 100;
@@ -1906,11 +1941,17 @@
   }
 
   if (government_has_flag(gov, G_REDUCED_RESEARCH)) {
-    science_bonus /= 2;
+    science_bonus[0] /= 2;
   }
 
-  pcity->tax_bonus = tax_bonus;
-  pcity->science_bonus = science_bonus;
+  pcity->tax_bonus = tax_bonus[0];
+  pcity->science_bonus = science_bonus[0];
+  /* FIXME: no handling of Island-range yet */
+  pplayer->tax_bonus = tax_bonus[2];
+  pplayer->science_bonus = science_bonus[2];
+  game.tax_bonus = tax_bonus[3];
+  game.science_bonus = science_bonus[3];
+
   pcity->shield_bonus = shield_bonus;
   pcity->shield_prod = pcity->shield_prod * shield_bonus / 100;
   pcity->makecontent = makecontent;
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/game.h freeciv-patched/common/game.h
--- freeciv-cvs/common/game.h	2003-07-10 11:53:00.000000000 +0100
+++ freeciv-patched/common/game.h	2003-07-10 11:53:12.000000000 +0100
@@ -166,6 +166,9 @@
   int watchtower_vision;
   int allowed_city_names;
 
+  /* Bonuses that affect all cities */
+  int science_bonus, tax_bonus;
+
   char rulesetdir[MAX_LEN_NAME];
   int firepower_factor;		/* See README.rulesets */
   struct {
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/improvement.c freeciv-patched/common/improvement.c
--- freeciv-cvs/common/improvement.c	2003-07-10 11:53:12.000000000 +0100
+++ freeciv-patched/common/improvement.c	2003-07-10 11:53:12.000000000 +0100
@@ -1214,7 +1214,8 @@
                 && iter->imeff->range == iter->range
                 && (iter->imeff->range != EFR_LOCAL
                     || effect->impr == iter->impr)
-                && is_city_affected(iter->imeff, iter->pcity)) {
+                && is_city_affected(iter->imeff, iter->pcity)
+		&& is_effect_outside(iter->imeff, iter->pcity)) {
               return iter->imeff;
             }
           }
@@ -1295,13 +1296,39 @@
   Returns TRUE if the given effect should affect the given city (i.e. it
   has the building required for the effect to be active)
 **************************************************************************/
-int is_city_affected(struct impr_effect *imeff, struct city *pcity)
+bool is_city_affected(struct impr_effect *imeff, struct city *pcity)
 {
   return (imeff->cond_bldg == B_LAST
           || (pcity && city_got_building(pcity, imeff->cond_bldg)));
 }
 
 /**************************************************************************
+  Returns TRUE if the given effect is in a city, or if it's in the field
+  and its "outside" flag is set, or if "outside" is ignored for this effect
+**************************************************************************/
+bool is_effect_outside(struct impr_effect *imeff, struct city *pcity)
+{
+  if (!pcity && !imeff->outside) {
+    switch(imeff->type) {
+    case EFT_UNIT_DEFEND:
+    case EFT_UNIT_ATTACK:
+    case EFT_UNIT_DEFEND_FIREPOWER:
+    case EFT_UNIT_ATTACK_FIREPOWER:
+    case EFT_UNIT_RECOVER:
+    case EFT_UNIT_VET_COMBAT:
+    case EFT_UPGRADE_ONE_STEP:
+    case EFT_UPGRADE_ONE_LEAP:
+    case EFT_UPGRADE_ALL_STEP:
+    case EFT_UPGRADE_ALL_LEAP:
+      return FALSE;
+    default:
+      break;
+    }
+  }
+  return TRUE;
+}
+
+/**************************************************************************
   Returns TRUE if the given effect should affect the given
   unit/terrain/special, by checking the relevant aff_xxx fields
   (Pass in NULL, T_UNKNOWN, and S_ALL respectively if you don't care
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/improvement.h freeciv-patched/common/improvement.h
--- freeciv-cvs/common/improvement.h	2003-07-10 11:53:12.000000000 +0100
+++ freeciv-patched/common/improvement.h	2003-07-10 11:53:12.000000000 +0100
@@ -192,6 +192,9 @@
   enum effect_range range;
   int amount;
   int survives;			   /* 1 = effect survives wonder destruction */
+  int outside;				/* 1 = effect influences units outside
+					 * of cities, not just those in the
+					 * center tile */
   Impr_Type_id cond_bldg;	   /* B_LAST = unconditional */
   int cond_gov;			   /* game.government_count = unconditional */
   Tech_Type_id cond_adv;	   /* A_NONE = unconditional; A_LAST = never */
@@ -329,7 +332,8 @@
     			     struct unit_classes *aff_unit,
                              enum tile_terrain_type aff_terr,
                              enum tile_special_type aff_spec);
-int is_city_affected(struct impr_effect *imeff, struct city *pcity);
+bool is_city_affected(struct impr_effect *imeff, struct city *pcity);
+bool is_effect_outside(struct impr_effect *imeff, struct city *pcity);
 
 #define city_effects_iterate(EI_iter, pcity) \
   { \
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/packets.c freeciv-patched/common/packets.c
--- freeciv-cvs/common/packets.c	2003-07-10 11:53:12.000000000 +0100
+++ freeciv-patched/common/packets.c	2003-07-10 11:53:12.000000000 +0100
@@ -179,8 +179,11 @@
 }
 
 static void dio_put_effects(struct data_out *dout,
+                            struct connection *pc,
                             const struct impr_effect *effect);
-static void dio_get_effects(struct data_in *din, struct impr_effect **peff);
+static void dio_get_effects(struct data_in *din,
+                            struct connection *pc,
+                            struct impr_effect **peff);
 
 /**************************************************************************
 presult indicates if there is more packets in the cache. We return result
@@ -2064,7 +2067,7 @@
   dio_put_uint8(&dout, packet->pop_cost);
 
   if (has_capability("impr_gen", pc->capability)) {
-    dio_put_effects(&dout, packet->effect);
+    dio_put_effects(&dout, pc, packet->effect);
   }
 
   /* This must be last, so client can determine length: */
@@ -2128,7 +2131,7 @@
   dio_get_uint8(&din, &packet->pop_cost);
 
   if (has_capability("impr_gen", pc->capability)) {
-    dio_get_effects(&din, &packet->effect);
+    dio_get_effects(&din, pc, &packet->effect);
   } else {
     packet->effect = fc_malloc(sizeof(struct impr_effect));
     packet->effect[0].type = EFT_LAST;
@@ -2220,6 +2223,7 @@
 ...
 **************************************************************************/
 static void dio_put_effects(struct data_out *dout,
+                            struct connection *pc,
                             const struct impr_effect *effect)
 {
   const struct impr_effect *eff;
@@ -2237,6 +2241,9 @@
     dio_put_uint8(dout, eff->range);
     dio_put_sint16(dout, eff->amount);
     dio_put_uint8(dout, eff->survives);
+    if (has_capability("impr_gen", pc->capability)) {
+      dio_put_uint8(dout, eff->outside);
+    }
     dio_put_uint8(dout, eff->cond_bldg);
     dio_put_uint8(dout, eff->cond_gov);
     dio_put_uint8(dout, eff->cond_adv);
@@ -2276,7 +2283,7 @@
   dio_put_uint16(&dout, packet->build_cost);
   dio_put_uint8(&dout, packet->upkeep);
   dio_put_uint8(&dout, packet->sabotage);
-  dio_put_effects(&dout, packet->effect);
+  dio_put_effects(&dout, pc, packet->effect);
 
   dio_put_uint8(&dout, packet->variant);	/* FIXME: remove when gen-impr obsoletes */
   dio_put_string(&dout, packet->name);
@@ -2300,7 +2307,9 @@
 /**************************************************************************
 ...
 **************************************************************************/
-static void dio_get_effects(struct data_in *din, struct impr_effect **peff)
+static void dio_get_effects(struct data_in *din,
+                            struct connection *pc,
+                            struct impr_effect **peff)
 {
   int count, inx;
   struct impr_effect *effect;
@@ -2312,6 +2321,9 @@
     dio_get_uint8(din, (int *)&(effect[inx].range));
     dio_get_sint16(din, &(effect[inx].amount));
     dio_get_uint8(din, &(effect[inx].survives));
+    if (has_capability("impr_gen", pc->capability)) {
+      dio_get_uint8(din, &(effect[inx].outside));
+    }
     dio_get_uint8(din, &(effect[inx].cond_bldg));
     dio_get_uint8(din, &(effect[inx].cond_gov));
     dio_get_uint8(din, &(effect[inx].cond_adv));
@@ -2350,7 +2362,7 @@
   dio_get_uint16(&din, &packet->build_cost);
   dio_get_uint8(&din, &packet->upkeep);
   dio_get_uint8(&din, &packet->sabotage);
-  dio_get_effects(&din, &packet->effect);
+  dio_get_effects(&din, pc, &packet->effect);
 
   dio_get_uint8(&din, &packet->variant);	/* FIXME: remove when gen-impr obsoletes */
   dio_get_string(&din, packet->name, sizeof(packet->name));
@@ -2634,7 +2646,7 @@
   dio_put_string(&dout, packet->graphic_alt);
 
   if (has_capability("impr_gen", pc->capability)) {
-    dio_put_effects(&dout, packet->effect);
+    dio_put_effects(&dout, pc, packet->effect);
   }
 
   /* This must be last, so client can determine length: */
@@ -2731,7 +2743,7 @@
   dio_get_string(&din, packet->graphic_alt, sizeof(packet->graphic_alt));
   
   if (has_capability("impr_gen", pc->capability)) {
-    dio_get_effects(&din, &packet->effect);
+    dio_get_effects(&din, pc, &packet->effect);
   } else {
     packet->effect = fc_malloc(sizeof(struct impr_effect));
     packet->effect[0].type = EFT_LAST;
@@ -2788,7 +2800,7 @@
   dio_put_uint8(&dout, packet->city_style);
   dio_put_tech_list(&dout, packet->init_techs);
   if (has_capability("impr_gen", pc->capability)) {
-    dio_put_effects(&dout, packet->effect);
+    dio_put_effects(&dout, pc, packet->effect);
   }
   if (has_capability("class_legend", pc->capability)) {
     dio_put_string(&dout, packet->class);
@@ -2828,7 +2840,7 @@
   dio_get_uint8(&din, &packet->city_style);
   dio_get_tech_list(&din, packet->init_techs);
   if (has_capability("impr_gen", pc->capability)) {
-    dio_get_effects(&din, &packet->effect);
+    dio_get_effects(&din, pc, &packet->effect);
   }
   if (has_capability("class_legend", pc->capability)) {
     dio_get_string(&din, packet->class, sizeof(packet->class));
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/player.h freeciv-patched/common/player.h
--- freeciv-cvs/common/player.h	2003-07-10 11:53:12.000000000 +0100
+++ freeciv-patched/common/player.h	2003-07-10 11:53:12.000000000 +0100
@@ -210,6 +210,9 @@
   struct ceff_vector destroyed_effects;/* list of effects that have survived
 					* building destruction */
 
+  /* Bonuses that affect all cities */
+  int science_bonus, tax_bonus;
+
   struct {
     int length;
     void *data;
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/tech.c freeciv-patched/common/tech.c
--- freeciv-cvs/common/tech.c	2003-07-10 11:49:12.000000000 +0100
+++ freeciv-patched/common/tech.c	2003-07-10 11:53:12.000000000 +0100
@@ -22,6 +22,7 @@
 
 #include "fcintl.h"
 #include "game.h"
+#include "log.h"
 #include "player.h"
 #include "shared.h" /* ARRAY_SIZE */
 #include "support.h"
@@ -327,18 +328,33 @@
 }
 
 /**************************************************************************
- Returns number of turns to advance (assuming current state of
- civilization).
+ Returns the total number of bulbs the civilization produces every turn
 **************************************************************************/
-int tech_turns_to_advance(struct player *pplayer)
+int total_science_output(struct player *pplayer)
 {
-  /* The number of bulbs the civilization produces every turn. */
   int current_output = 0;
 
   city_list_iterate(pplayer->cities, pcity) {
     current_output += pcity->science_total;
   } city_list_iterate_end;
 
+  freelog(LOG_DEBUG, "Total science output: %d", current_output);
+  current_output = current_output * pplayer->science_bonus / 100;
+  current_output = current_output * game.science_bonus / 100;
+  freelog(LOG_DEBUG, "Player bonus %d; game bonus %d; total %d",
+	  pplayer->science_bonus, game.science_bonus, current_output);
+
+  return current_output;
+}
+
+/**************************************************************************
+ Returns number of turns to advance (assuming current state of
+ civilization).
+**************************************************************************/
+int tech_turns_to_advance(struct player *pplayer)
+{
+  int current_output = total_science_output(pplayer);
+
   if (current_output <= 0) {
     return FC_INFINITY;
   }
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/tech.h freeciv-patched/common/tech.h
--- freeciv-cvs/common/tech.h	2003-07-07 18:23:57.000000000 +0100
+++ freeciv-patched/common/tech.h	2003-07-10 11:53:12.000000000 +0100
@@ -119,6 +119,7 @@
 enum tech_flag_id tech_flag_from_str(const char *s);
 Tech_Type_id find_tech_by_flag(int index, enum tech_flag_id flag);
 
+int total_science_output(struct player *pplayer);
 int tech_turns_to_advance(struct player *pplayer);
 
 int total_bulbs_required(struct player *pplayer);
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/data/civ1/buildings.ruleset freeciv-patched/data/civ1/buildings.ruleset
--- freeciv-cvs/data/civ1/buildings.ruleset	2003-07-10 11:53:00.000000000 +0100
+++ freeciv-patched/data/civ1/buildings.ruleset	2003-07-10 11:53:12.000000000 +0100
@@ -1793,9 +1793,9 @@
 upkeep		= 0
 sabotage	= 0
 effect		=
-    { "type", "range", "amount", "aff_unit"
+    { "type", "range", "amount", "aff_unit", "outside"
+	"Unit_Vet_Combat", "Player", 100, "Land", 1
 	"Unit_Veteran", "Player", 0, "Land"
-	"Unit_Vet_Combat", "Player", 100, "Land"
     }
 sound		= "w_sun_tzus_war_academy"
 sound_alt	= "w_generic"
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/data/civ2/buildings.ruleset freeciv-patched/data/civ2/buildings.ruleset
--- freeciv-cvs/data/civ2/buildings.ruleset	2003-07-10 11:52:25.000000000 +0100
+++ freeciv-patched/data/civ2/buildings.ruleset	2003-07-10 11:53:12.000000000 +0100
@@ -1801,9 +1801,9 @@
 upkeep		= 0
 sabotage	= 0
 effect		=
-    { "type", "range", "amount", "aff_unit"
+    { "type", "range", "amount", "aff_unit", "outside"
+	"Unit_Vet_Combat", "Player", 100, "Land", 1
 	"Unit_Veteran", "Player", 0, "Land"
-	"Unit_Vet_Combat", "Player", 100, "Land"
     }
 sound		= "w_sun_tzus_war_academy"
 sound_alt	= "w_generic"
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/data/default/buildings.ruleset freeciv-patched/data/default/buildings.ruleset
--- freeciv-cvs/data/default/buildings.ruleset	2003-07-10 11:53:00.000000000 +0100
+++ freeciv-patched/data/default/buildings.ruleset	2003-07-10 11:53:12.000000000 +0100
@@ -1999,9 +1999,9 @@
 upkeep		= 0
 sabotage	= 0
 effect		=
-    { "type", "range", "amount", "aff_unit"
+    { "type", "range", "amount", "aff_unit", "outside"
+	"Unit_Vet_Combat", "Player", 100, "Land", 1
 	"Unit_Veteran", "Player", 0, "Land"
-	"Unit_Vet_Combat", "Player", 100, "Land"
     }
 sound		= "w_sun_tzus_war_academy"
 sound_alt	= "w_generic"
@@ -2028,12 +2028,12 @@
 upkeep		= 0
 sabotage	= 0
 effect		=
-    { "type", "range", "amount", "aff_unit"
-	"Unit_Recover", "Player", 2, "Air"
-	"Unit_Recover", "Player", 2, "Heli"
-	"Unit_Recover", "Player", 2, "Land"
-	"Unit_Recover", "Player", 2, "Missile"
-	"Unit_Recover", "Player", 2, "Sea"
+    { "type", "range", "amount", "aff_unit", "outside"
+	"Unit_Recover", "Player", 2, "Air", 1
+	"Unit_Recover", "Player", 2, "Heli", 1
+	"Unit_Recover", "Player", 2, "Land", 1
+	"Unit_Recover", "Player", 2, "Missile", 1
+	"Unit_Recover", "Player", 2, "Sea", 1
     }
 sound		= "w_united_nations"
 sound_alt	= "w_generic"
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/doc/README.effects freeciv-patched/doc/README.effects
--- freeciv-cvs/doc/README.effects	2003-07-10 11:53:00.000000000 +0100
+++ freeciv-patched/doc/README.effects	2003-07-10 11:53:12.000000000 +0100
@@ -270,6 +270,16 @@
 	    (must be in the range -32767 to 32767)
 .survives  = 1 if effect survives destruction (wonders only)
 	    (if unspecified, 0 (doesn't survive) is assumed)
+.outside   = 1 if, for effects at greater than City-range, the effect
+	     is active in all tiles, not just the city center. For tax
+	     and science city bonuses, this means that the TOTAL science
+	     output of all cities affected is subject to the bonus,
+	     rather than the output of each city individually.
+	     Applicable effects: Science_Bonus, Science_Pct,
+	     Tax_Bonus, Tax_Pct, Unit_Defend, Unit_Attack,
+	     Unit_Attack_Firepower, Unit_Defend_Firepower,
+	     Unit_Recover, Unit_Vet_Combat, Upgrade_*
+	    (if unspecified, 0 (city center only) is assumed)
 .cond_bldg = effect is only active in cities that have this building
 	    (if unspecified, effect not conditional on building)
 .cond_nat  = must be this nation for effect
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/server/cityturn.c freeciv-patched/server/cityturn.c
--- freeciv-cvs/server/cityturn.c	2003-07-10 11:52:48.000000000 +0100
+++ freeciv-patched/server/cityturn.c	2003-07-10 11:53:12.000000000 +0100
@@ -400,16 +400,36 @@
 }
 
 /**************************************************************************
+  N.B. We call update_tech for the total science output, rather than for
+  each city individually, to reduce rounding error when applying science
+  bonuses.
+***************************************************************************/
+static void update_all_tech(struct player *pplayer)
+{
+  int current_output = total_science_output(pplayer);
+
+  update_tech(pplayer, current_output);
+}
+
+/**************************************************************************
 ...
 **************************************************************************/
 void update_city_activities(struct player *pplayer)
 {
-  int gold;
+  int gold, goldmade;
   gold=pplayer->economic.gold;
   pplayer->got_tech = FALSE;
   city_list_iterate(pplayer->cities, pcity)
      update_city_activity(pplayer, pcity);
   city_list_iterate_end;
+
+  /* Apply impr. gen. global tax bonuses */
+  goldmade = pplayer->economic.gold - gold;
+  goldmade = goldmade * pplayer->tax_bonus / 100;
+  goldmade = goldmade * game.tax_bonus / 100;
+  pplayer->economic.gold = gold + goldmade;
+
+  update_all_tech(pplayer);
   pplayer->ai.prev_gold = gold;
   /* This test include the cost of the units because pay_for_units is called
    * in update_city_activity */
@@ -1307,7 +1327,6 @@
 
     pcity->did_sell=FALSE;
     pcity->did_buy = FALSE;
-    update_tech(pplayer, pcity->science_total);
     pplayer->economic.gold+=pcity->tax_total;
     pay_for_units(pplayer, pcity);
     pay_for_buildings(pplayer, pcity);
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/server/ruleset.c freeciv-patched/server/ruleset.c
--- freeciv-cvs/server/ruleset.c	2003-07-10 11:53:12.000000000 +0100
+++ freeciv-patched/server/ruleset.c	2003-07-10 11:53:12.000000000 +0100
@@ -767,6 +767,8 @@
       e->survives = secfile_lookup_int_default(file, 0, "%s.effect%d.survives",
 					       secname, j);
     }
+    e->outside = secfile_lookup_int_default(file, 0, "%s.effect%d.outside",
+					    secname, j);
 
     item = secfile_lookup_str_default(file, "", "%s.effect%d.cond_bldg",
 				      secname, j);
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/server/unittools.c freeciv-patched/server/unittools.c
--- freeciv-cvs/server/unittools.c	2003-07-10 11:53:00.000000000 +0100
+++ freeciv-patched/server/unittools.c	2003-07-10 11:53:12.000000000 +0100
@@ -245,14 +245,17 @@
   unit_list_init(&candidates);
 	
   unit_list_iterate(pplayer->units, punit) {
+    struct city *mapcity = map_get_city(punit->x, punit->y);
+
     tile_t = map_get_terrain(punit->x, punit->y);
     spec_t = map_get_special(punit->x, punit->y);
     get_unit_classes(punit, &aff_unit);
 
     if (is_unit_terrain_affected(iter->imeff, &aff_unit, tile_t, spec_t) &&
+	is_effect_outside(iter->imeff, mapcity) &&
 	(continent == -1 ||
 	 continent == map_get_continent(punit->x, punit->y)) &&
-	(!pcity || pcity == map_get_city(punit->x, punit->y)) &&
+	(!pcity || pcity == mapcity) &&
 	(upgrade_type = can_upgrade_unittype(pplayer, punit->type,
 					   upgrade_leap)) != -1 &&
 	!upgrade_would_strand(punit, upgrade_type)) {
