diff -Nur -Xfreecivdiff.ignore freeciv-cvs/client/packhand.c freeciv-patched/client/packhand.c
--- freeciv-cvs/client/packhand.c	2003-07-24 16:59:50.000000000 +0100
+++ freeciv-patched/client/packhand.c	2003-07-24 17:01:33.000000000 +0100
@@ -422,6 +422,9 @@
     pcity->trade[i]=packet->trade[i];
     pcity->trade_value[i]=packet->trade_value[i];
   }
+
+  pcity->buildflags = packet->buildflags;
+  pcity->upkeep_free = packet->upkeep_free;
   
   pcity->food_prod=packet->food_prod;
   pcity->food_surplus=packet->food_surplus;
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/capstr.c freeciv-patched/common/capstr.c
--- freeciv-cvs/common/capstr.c	2003-07-23 16:36:56.000000000 +0100
+++ freeciv-patched/common/capstr.c	2003-07-24 17:01:33.000000000 +0100
@@ -79,7 +79,7 @@
                    "+impr_req +waste +fastfocus +continent +small_dipl " \
                    "+no_nation_selected +diplomacy +no_extra_tiles " \
                    "+diplomacy2 +citizens_style +root_tech auth " \
-                   "+nat_ulimit retake +goto_pack borders"
+                   "+nat_ulimit retake +goto_pack borders impr_gen"
 
 /* "+1.14.0" is protocol for 1.14.0 release.
  *
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/city.c freeciv-patched/common/city.c
--- freeciv-cvs/common/city.c	2003-07-24 17:01:11.000000000 +0100
+++ freeciv-patched/common/city.c	2003-07-24 17:01:33.000000000 +0100
@@ -339,6 +339,21 @@
 }
 
 /**************************************************************************
+  Is the given improvement a space ship component?
+**************************************************************************/
+static bool is_space_part(Impr_Type_id id)
+{
+  struct impr_effect *eff;
+
+  for (eff = get_improvement_type(id)->effect;
+       eff && eff->type != EFT_LAST; eff++) {
+    if (eff->type == EFT_SPACE_PART)
+      return TRUE;
+  }
+  return FALSE;
+}
+
+/**************************************************************************
  Will this city ever be able to build this improvement?
  Doesn't check for building prereqs
 **************************************************************************/
@@ -348,6 +363,10 @@
   if (!could_player_eventually_build_improvement(city_owner(pcity),id))
     return FALSE;
 
+  if (!(pcity->buildflags & CITY_ENABLE_SPACE)
+      && is_space_part(id))
+    return FALSE;
+
   if (city_got_building(pcity, id))
     return FALSE;
 
@@ -412,6 +431,11 @@
     return FALSE;
   }
 
+  if (unit_type_flag(id, F_NUCLEAR)
+      && !(pcity->buildflags & CITY_ENABLE_NUKE)) {
+    return FALSE;
+  }
+
   /* You can't build naval units inland. */
   if (!is_ocean_near_tile(pcity->x, pcity->y) && is_water_unit(id)) {
     return FALSE;
@@ -482,9 +506,7 @@
     return 0;
   if (is_wonder(i))
     return 0;
-  if (improvement_types[i].upkeep == 1 &&
-      city_affected_by_wonder(pcity, B_ASMITHS)) 
-    return 0;
+  if (improvement_types[i].upkeep <= pcity->upkeep_free) return 0;
   if (government_has_flag(get_gov_pcity(pcity), G_CONVERT_TITHES_TO_MONEY)
       && (i == B_TEMPLE || i == B_COLOSSEUM || i == B_CATHEDRAL)) {
     return 0;
@@ -494,7 +516,8 @@
 }
 
 /**************************************************************************
-  Caller to pass asmiths = city_affected_by_wonder(pcity, B_ASMITHS)
+  Caller to pass asmiths = TRUE if we should honour the upkeep_free field
+  in pcity (set by improvements such as A.Smith's)
 **************************************************************************/
 static int improvement_upkeep_asmiths(struct city *pcity, Impr_Type_id i,
 				      bool asmiths)
@@ -503,7 +526,7 @@
     return 0;
   if (is_wonder(i))
     return 0;
-  if (asmiths && improvement_types[i].upkeep == 1) 
+  if (asmiths && improvement_types[i].upkeep <= pcity->upkeep_free)
     return 0;
   if (government_has_flag(get_gov_pcity(pcity), G_CONVERT_TITHES_TO_MONEY)
       && (i == B_TEMPLE || i == B_COLOSSEUM || i == B_CATHEDRAL)) {
@@ -1007,11 +1030,10 @@
 *************************************************************************/
 int city_gold_surplus(struct city *pcity)
 {
-  bool asmiths = city_affected_by_wonder(pcity, B_ASMITHS);
   int cost = 0;
 
   built_impr_iterate(pcity, i) {
-    cost += improvement_upkeep_asmiths(pcity, i, asmiths);
+    cost += improvement_upkeep_asmiths(pcity, i, TRUE);
   } built_impr_iterate_end;
 
   unit_list_iterate(pcity->units_supported, punit) {
@@ -1758,6 +1780,32 @@
 }
 
 /**************************************************************************
+  Sets the maximum size that the city can grow (-1 = no limit) and, if
+  applicable, the improvement needed to increase this limit
+**************************************************************************/
+static void set_city_size_limit(struct city *pcity, int size_unlimit)
+{
+  int impr, unlimit_impr = B_LAST, size_limit = -1;
+  struct impr_effect *imeff;
+
+  /* May be better to run this loop after reading rulesets, and store the
+   * unlimit effects, rather than running this every time - check profiles */
+  for (impr = 0; impr < game.num_impr_types; impr++) {
+    for (imeff = improvement_types[impr].effect;
+         imeff && imeff->type != EFT_LAST; imeff++) {
+      if (imeff->type == EFT_SIZE_UNLIMIT && imeff->amount > size_unlimit
+          && (size_limit == -1 || size_limit >= imeff->amount)) {
+        size_limit = imeff->amount;
+        unlimit_impr = impr;
+      }
+    }
+  }
+
+  pcity->size_limit = size_limit;
+  pcity->unlimit_impr = unlimit_impr;
+}
+
+/**************************************************************************
   Updates the various modifiers and bonuses due to city improvements
   (should be called whenever city effects change - i.e. by
   update_all_effects and friends)
@@ -1777,6 +1825,9 @@
   int makecontentpct = 100, forcecontentpct = 100;
   int makecontentmil = 0, makecontentmilper = 0;
   int corruptadj = 0, corruptpct = 100;
+  int size_unlimit = -1, upkeep_free = 0;
+  enum city_flags buildflags = 0;
+  int growth_food = 0, nuke_proof = 0;
 
   enum tile_special_type spec = map_get_special(pcity->x, pcity->y);
   enum tile_terrain_type terr = map_get_terrain(pcity->x, pcity->y);
@@ -1874,6 +1925,18 @@
 	corruptadj += amount; break;
       case EFT_CORRUPT_PCT:
 	corruptpct = corruptpct * amount / 100; break;
+      case EFT_UPKEEP_FREE:
+        upkeep_free = MAX(upkeep_free,amount); break;
+      case EFT_SIZE_UNLIMIT:
+        size_unlimit = MAX(size_unlimit,amount); break;
+      case EFT_GROWTH_FOOD:
+        growth_food = MAX(growth_food,amount); break;
+      case EFT_ENABLE_SPACE:
+        buildflags |= CITY_ENABLE_SPACE; break;
+      case EFT_ENABLE_NUKE:
+        buildflags |= CITY_ENABLE_NUKE; break;
+      case EFT_NUKE_PROOF:
+        nuke_proof = MAX(nuke_proof,amount); break;
       case EFT_AIRLIFT:
         pcity->airlift = TRUE; break;
       default:
@@ -1884,6 +1947,11 @@
 
   pcity->corruptadj = corruptadj;
   pcity->corruptpct = corruptpct;
+  pcity->buildflags = buildflags;
+  set_city_size_limit(pcity, size_unlimit);
+  pcity->nuke_proof = nuke_proof;
+  pcity->growth_food = growth_food;
+  pcity->upkeep_free = upkeep_free;
 
   /* Apply the multipliers to the bonuses (such that the bonuses are all
      summed first, and only then are the multipliers applied) */
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/city.h freeciv-patched/common/city.h
--- freeciv-cvs/common/city.h	2003-07-24 17:01:11.000000000 +0100
+++ freeciv-patched/common/city.h	2003-07-24 17:01:33.000000000 +0100
@@ -52,6 +52,12 @@
   CITYO_DISBAND, CITYO_NEW_EINSTEIN, CITYO_NEW_TAXMAN
 };
 
+/* Whether this city can build certain "special" units or improvements */
+enum city_flags {
+  CITY_ENABLE_SPACE = 1 << 0,
+  CITY_ENABLE_NUKE  = 1 << 1
+};
+
 /* first four bits are for auto-attack: */
 #define CITYOPT_AUTOATTACK_BITS 0xF
 
@@ -296,6 +302,13 @@
   int original;			/* original owner */
   int city_options;		/* bitfield; positions as enum city_options */
 
+  enum city_flags buildflags;	/* whether we can build spaceship/nukes */
+  int size_limit;		/* max. population with current improvements */
+  Impr_Type_id unlimit_impr;	/* the improvement that increases size_limit */
+  int nuke_proof;		/* nuclear attacks fail within this range */
+  int growth_food;		/* pct. size of foodbox on growth/shrink */
+  int upkeep_free;		/* improvements with this upkeep are free */
+
   /* server variable. indicates if the city map is synced with the client. */
   bool synced;
     
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/combat.c freeciv-patched/common/combat.c
--- freeciv-cvs/common/combat.c	2003-07-10 11:53:38.000000000 +0100
+++ freeciv-patched/common/combat.c	2003-07-24 17:01:33.000000000 +0100
@@ -354,11 +354,16 @@
 **************************************************************************/
 struct city *sdi_defense_close(struct player *owner, int x, int y)
 {
-  square_iterate(x, y, 2, x1, y1) {
-    struct city *pcity = map_get_city(x1, y1);
-    if (pcity && (!pplayers_allied(city_owner(pcity), owner))
-	&& city_got_building(pcity, B_SDI)) return pcity;
-  } square_iterate_end;
+  players_iterate(pplayer) {
+    if (pplayer != owner) {
+      city_list_iterate(pplayer->cities, pcity) {
+        if (pcity->nuke_proof > 0
+            && map_distance(pcity->x, pcity->y, x, y) <= pcity->nuke_proof) {
+          return pcity;
+        }
+      } city_list_iterate_end;
+    }
+  } players_iterate_end;
 
   return NULL;
 }
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/improvement.c freeciv-patched/common/improvement.c
--- freeciv-cvs/common/improvement.c	2003-07-24 16:59:50.000000000 +0100
+++ freeciv-patched/common/improvement.c	2003-07-24 17:01:33.000000000 +0100
@@ -511,9 +511,6 @@
     /* This if for a spaceship component is asked */
     while ((type = peffect->type) != EFT_LAST) {
       if (type == EFT_SPACE_PART) {
-      	/* TODO: remove this */
-	if (game.global_wonders[B_APOLLO] == 0)
-	  return FALSE;
         if (p->spaceship.state >= SSHIP_LAUNCHED)
 	  return FALSE;
 	if (peffect->amount == 1 && p->spaceship.structurals >= NUM_SS_STRUCTURALS)
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/packets.c freeciv-patched/common/packets.c
--- freeciv-cvs/common/packets.c	2003-07-23 16:36:56.000000000 +0100
+++ freeciv-patched/common/packets.c	2003-07-24 17:01:33.000000000 +0100
@@ -1374,6 +1374,11 @@
 
   dio_put_uint32(&dout, req->turn_founded);
 
+  if (has_capability("impr_gen", pc->capability)) {
+    dio_put_uint8(&dout, req->buildflags);
+    dio_put_uint8(&dout, req->upkeep_free);
+  }
+
   for (data = 0; data < NUM_TRADEROUTES; data++) {
     if (req->trade[data] != 0) {
       dio_put_uint16(&dout, req->trade[data]);
@@ -1465,6 +1470,11 @@
 
   dio_get_uint32(&din, &packet->turn_founded);
 
+  if (has_capability("impr_gen", pc->capability)) {
+    dio_get_uint8(&din, &packet->buildflags);
+    dio_get_uint8(&din, &packet->upkeep_free);
+  }
+
   for (data = 0; data < NUM_TRADEROUTES; data++) {
     if (dio_input_remaining(&din) < 3)
       break;
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/packets.h freeciv-patched/common/packets.h
--- freeciv-cvs/common/packets.h	2003-07-23 16:36:56.000000000 +0100
+++ freeciv-patched/common/packets.h	2003-07-24 17:01:33.000000000 +0100
@@ -377,6 +377,8 @@
   bool diplomat_investigate;
   int city_options;
   int turn_founded;
+
+  int buildflags, upkeep_free;
 };
 
 
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/player.c freeciv-patched/common/player.c
--- freeciv-cvs/common/player.c	2003-07-24 16:57:16.000000000 +0100
+++ freeciv-patched/common/player.c	2003-07-24 17:01:33.000000000 +0100
@@ -66,7 +66,7 @@
 {
   return (TEST_BIT(pplayer->embassy, pplayer2->player_no)
           || (pplayer == pplayer2)
-          || (player_owns_active_wonder(pplayer, B_MARCO)
+          || (is_under_effect(B_LAST, NULL, pplayer, EFT_HAVE_EMBASSIES)
               && !is_barbarian(pplayer2)));
 }
 
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/unit.c freeciv-patched/common/unit.c
--- freeciv-cvs/common/unit.c	2003-07-24 17:00:39.000000000 +0100
+++ freeciv-patched/common/unit.c	2003-07-24 17:01:33.000000000 +0100
@@ -475,14 +475,8 @@
     return AB_TOO_BIG;
   if (pcity->owner != punit->owner)
     return AB_NOT_OWNER;
-  if (improvement_exists(B_AQUEDUCT)
-      && !city_got_building(pcity, B_AQUEDUCT)
-      && new_pop > game.aqueduct_size)
+  if (pcity->size_limit >= 0 && new_pop > pcity->size_limit)
     return AB_NO_AQUEDUCT;
-  if (improvement_exists(B_SEWER)
-      && !city_got_building(pcity, B_SEWER)
-      && new_pop > game.sewer_size)
-    return AB_NO_SEWER;
   return AB_ADD_OK;
 }
 
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/unittype.c freeciv-patched/common/unittype.c
--- freeciv-cvs/common/unittype.c	2003-07-24 17:01:33.000000000 +0100
+++ freeciv-patched/common/unittype.c	2003-07-24 17:01:33.000000000 +0100
@@ -444,8 +444,8 @@
 
 /**************************************************************************
 Whether player can build given unit somewhere,
-ignoring whether unit is obsolete and assuming the
-player has a coastal city.
+ignoring whether unit is obsolete, any special requirements (e.g. for
+nuclear units) and assuming the player has a coastal city.
 **************************************************************************/
 bool can_player_build_unit_direct(struct player *p, Unit_Type_id id)
 {
@@ -454,8 +454,6 @@
 
   if (!unit_type_exists(id))
     return FALSE;
-  if (unit_type_flag(id, F_NUCLEAR) && game.global_wonders[B_MANHATTEN] == 0)
-    return FALSE;
   if (unit_type_flag(id, F_FANATIC)
       && !government_has_flag(get_gov_pplayer(p), G_FANATIC_TROOPS))
     return FALSE;
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/server/citytools.c freeciv-patched/server/citytools.c
--- freeciv-cvs/server/citytools.c	2003-07-24 17:00:39.000000000 +0100
+++ freeciv-patched/server/citytools.c	2003-07-24 17:01:33.000000000 +0100
@@ -560,14 +560,14 @@
 **************************************************************************/
 bool wants_to_be_bigger(struct city *pcity)
 {
-  if (pcity->size < game.aqueduct_size) return TRUE;
-  if (city_got_building(pcity, B_SEWER)) return TRUE;
-  if (city_got_building(pcity, B_AQUEDUCT)
-      && pcity->size < game.sewer_size) return TRUE;
-  if (!pcity->is_building_unit) {
-    if (pcity->currently_building == B_SEWER && pcity->did_buy) return TRUE;
-    if (pcity->currently_building == B_AQUEDUCT && pcity->did_buy) return TRUE;
-  } /* saves a lot of stupid flipflops -- Syela */
+  if (pcity->size_limit < 0) return TRUE;  /* No size restriction */
+  if (pcity->size < pcity->size_limit) return TRUE;
+
+  /* saves a lot of stupid flipflops -- Syela */
+  if (!pcity->is_building_unit
+      && pcity->currently_building == pcity->unlimit_impr
+      && pcity->did_buy) return TRUE;
+
   return FALSE;
 }
 
@@ -1614,6 +1614,9 @@
   packet->pollution=pcity->pollution;
 
   packet->city_options=pcity->city_options;
+
+  packet->buildflags = pcity->buildflags;
+  packet->upkeep_free = pcity->upkeep_free;
   
   packet->is_building_unit=pcity->is_building_unit;
   packet->currently_building=pcity->currently_building;
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/server/cityturn.c freeciv-patched/server/cityturn.c
--- freeciv-cvs/server/cityturn.c	2003-07-24 17:00:57.000000000 +0100
+++ freeciv-patched/server/cityturn.c	2003-07-24 17:01:33.000000000 +0100
@@ -370,10 +370,8 @@
       }
     }
 
-    can_grow = (city_got_building(pcity, B_AQUEDUCT)
-		|| pcity->size < game.aqueduct_size)
-      && (city_got_building(pcity, B_SEWER)
-	  || pcity->size < game.sewer_size);
+    can_grow = (pcity->size_limit < 0
+                || pcity->size < pcity->size_limit);
 
     if ((turns_growth <= 0) && !city_celebrating(pcity) && can_grow) {
       notify_conn_ex(dest, pcity->x, pcity->y,
@@ -474,44 +472,26 @@
 {
   struct player *powner = city_owner(pcity);
   bool have_square;
-  bool has_granary = city_got_effect(pcity, B_GRANARY);
   bool rapture_grow = city_rapture_grow(pcity); /* check before size increase! */
   int new_food;
 
-  if (!city_got_building(pcity, B_AQUEDUCT)
-      && pcity->size>=game.aqueduct_size) {/* need aqueduct */
-    if (!pcity->is_building_unit && pcity->currently_building == B_AQUEDUCT) {
+  /* Check for needed aqueduct/sewer system/etc. */
+  if (pcity->size_limit >= 0 && pcity->size >= pcity->size_limit) {
+    if (!pcity->is_building_unit
+        && pcity->currently_building == pcity->unlimit_impr) {
       notify_player_ex(powner, pcity->x, pcity->y, E_CITY_AQ_BUILDING,
 		       _("Game: %s needs %s (being built) "
 			 "to grow any further."), pcity->name,
-		       improvement_types[B_AQUEDUCT].name);
+		       get_improvement_name(pcity->unlimit_impr));
     } else {
       notify_player_ex(powner, pcity->x, pcity->y, E_CITY_AQUEDUCT,
 		       _("Game: %s needs %s to grow any further."),
-		       pcity->name, improvement_types[B_AQUEDUCT].name);
+		       pcity->name, get_improvement_name(pcity->unlimit_impr));
     }
     /* Granary can only hold so much */
     new_food = (city_granary_size(pcity->size) *
-		(100 - game.aqueductloss / (1 + (has_granary ? 1 : 0)))) / 100;
-    pcity->food_stock = MIN(pcity->food_stock, new_food);
-    return;
-  }
-
-  if (!city_got_building(pcity, B_SEWER)
-      && pcity->size>=game.sewer_size) {/* need sewer */
-    if (!pcity->is_building_unit && pcity->currently_building == B_SEWER) {
-      notify_player_ex(powner, pcity->x, pcity->y, E_CITY_AQ_BUILDING,
-		       _("Game: %s needs %s (being built) "
-			 "to grow any further."), pcity->name,
-		       improvement_types[B_SEWER].name);
-    } else {
-      notify_player_ex(powner, pcity->x, pcity->y, E_CITY_AQUEDUCT,
-		       _("Game: %s needs %s to grow any further."),
-		       pcity->name, improvement_types[B_SEWER].name);
-    }
-    /* Granary can only hold so much */
-    new_food = (city_granary_size(pcity->size) *
-		(100 - game.aqueductloss / (1 + (has_granary ? 1 : 0)))) / 100;
+		(100 - game.aqueductloss *
+		 (100 - pcity->growth_food) / 100)) / 100;
     pcity->food_stock = MIN(pcity->food_stock, new_food);
     return;
   }
@@ -521,10 +501,7 @@
   if (rapture_grow) {
     new_food = city_granary_size(pcity->size);
   } else {
-    if (has_granary)
-      new_food = city_granary_size(pcity->size) / 2;
-    else
-      new_food = 0;
+    new_food = city_granary_size(pcity->size) * pcity->growth_food / 100;
   }
   pcity->food_stock = MIN(pcity->food_stock, new_food);
 
@@ -591,10 +568,8 @@
 			 pcity->name, utname);
 	gamelog(GAMELOG_UNITFS, _("%s lose %s (famine)"),
 		get_nation_name_plural(city_owner(pcity)->nation), utname);
-	if (city_got_effect(pcity, B_GRANARY))
-	  pcity->food_stock=city_granary_size(pcity->size)/2;
-	else
-	  pcity->food_stock=0;
+	pcity->food_stock = city_granary_size(pcity->size) *
+			    pcity->growth_food / 100;
 	return;
       }
     }
@@ -602,10 +577,8 @@
     notify_player_ex(city_owner(pcity), pcity->x, pcity->y, E_CITY_FAMINE,
 		     _("Game: Famine causes population loss in %s."),
 		     pcity->name);
-    if (city_got_effect(pcity, B_GRANARY))
-      pcity->food_stock = city_granary_size(pcity->size - 1) / 2;
-    else
-      pcity->food_stock = 0;
+    pcity->food_stock = city_granary_size(pcity->size - 1) *
+			pcity->growth_food / 100;
     city_reduce_size(pcity, 1);
   }
 }
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/server/ruleset.c freeciv-patched/server/ruleset.c
--- freeciv-cvs/server/ruleset.c	2003-07-24 17:00:57.000000000 +0100
+++ freeciv-patched/server/ruleset.c	2003-07-24 17:01:33.000000000 +0100
@@ -1133,6 +1133,9 @@
 	 to the most convenient range for the code to deal with */
       switch(e->type) {
       case EFT_ADV_PARASITE:
+      case EFT_HAVE_EMBASSIES:
+      case EFT_REVEAL_CITIES:
+      case EFT_REVEAL_MAP:
         e->range = EFR_PLAYER; break;
       case EFT_GIVE_IMM_ADV:
         e->range = EFR_CITY; break;
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/server/settlers.c freeciv-patched/server/settlers.c
--- freeciv-cvs/server/settlers.c	2003-07-21 13:58:28.000000000 +0100
+++ freeciv-patched/server/settlers.c	2003-07-24 17:01:33.000000000 +0100
@@ -862,8 +862,7 @@
     struct city *pcity = map_get_city(punit->x, punit->y);
 
     assert(pcity != NULL);
-    cost = city_granary_size(pcity->size);
-    if (city_got_effect(pcity, B_GRANARY)) { cost /= 2; }
+    cost = city_granary_size(pcity->size) * (100 - pcity->growth_food) / 100;
   }
 
   return cost;
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/server/srv_main.c freeciv-patched/server/srv_main.c
--- freeciv-cvs/server/srv_main.c	2003-07-21 13:58:28.000000000 +0100
+++ freeciv-patched/server/srv_main.c	2003-07-24 17:01:33.000000000 +0100
@@ -298,42 +298,35 @@
 }
 
 /**************************************************************************
-...
-**************************************************************************/
-static void do_apollo_program(void)
-{
-  struct city *pcity = find_city_wonder(B_APOLLO);
-
-  if (pcity) {
-    struct player *pplayer = city_owner(pcity);
-
-    if (game.civstyle == 1) {
-      players_iterate(other_player) {
-	city_list_iterate(other_player->cities, pcity) {
-	  show_area(pplayer, pcity->x, pcity->y, 0);
-	} city_list_iterate_end;
-      } players_iterate_end;
-    } else {
-      /* map_know_all will mark all unknown tiles as known and send
-       * tile, unit, and city updates as necessary.  No other actions are
-       * needed. */
-      map_know_all(pplayer);
-    }
-  }
-}
-
-/**************************************************************************
-...
+  Carries out any actions that affect the whole world - e.g. Marco Polo,
+  Apollo Program
 **************************************************************************/
-static void marco_polo_make_contact(void)
+static void check_global_effects(void)
 {
-  struct city *pcity = find_city_wonder(B_MARCO);
 
-  if (pcity) {
-    players_iterate(pplayer) {
-      make_contact(city_owner(pcity), pplayer, pcity->x, pcity->y);
-    } players_iterate_end;
-  }
+  players_iterate(pplayer) {
+    impr_effects_iterate(iter, B_LAST, NULL, pplayer) {
+      switch(iter.imeff->type) {
+      case EFT_HAVE_EMBASSIES:
+        players_iterate(othplayer) {
+          make_contact(pplayer, othplayer, -1, -1);
+        } players_iterate_end;
+        break;
+      case EFT_REVEAL_MAP:
+        map_know_all(pplayer);
+        break;
+      case EFT_REVEAL_CITIES:
+        players_iterate(othplayer) {
+	  city_list_iterate(othplayer->cities, pcity) {
+	    show_area(pplayer, pcity->x, pcity->y, 0);
+	  } city_list_iterate_end;
+        } players_iterate_end;
+        break;
+      default:
+        break;
+      }
+    } impr_effects_iterate_end;
+  } players_iterate_end;
 }
 
 /**************************************************************************
@@ -526,8 +519,7 @@
 			     &game.nuclearwinter, &game.coolinglevel,
 			     nuclear_winter);
   update_diplomatics();
-  do_apollo_program();
-  marco_polo_make_contact();
+  check_global_effects();
   make_history_report();
   send_player_turn_notifications(NULL);
   freelog(LOG_DEBUG, "Turn ended.");
diff -Nur -Xfreecivdiff.ignore freeciv-cvs/server/unithand.c freeciv-patched/server/unithand.c
--- freeciv-cvs/server/unithand.c	2003-07-24 17:01:33.000000000 +0100
+++ freeciv-patched/server/unithand.c	2003-07-24 17:01:33.000000000 +0100
@@ -503,15 +503,9 @@
     break;
   case AB_NO_AQUEDUCT:
     notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT,
-		     _("Game: %s needs %s to grow, so you cannot add %s."),
-		     pcity->name, get_improvement_name(B_AQUEDUCT),
-		     unit_name);
-    break;
-  case AB_NO_SEWER:
-    notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT,
-		     _("Game: %s needs %s to grow, so you cannot add %s."),
-		     pcity->name, get_improvement_name(B_SEWER),
-		     unit_name);
+		     _("Game: %s needs an improvement to grow, so "
+		       "you cannot add %s."),
+		     pcity->name, unit_name);
     break;
   default:
     /* Shouldn't happen */
