Index: common/nation.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/nation.h,v
retrieving revision 1.6
diff -u -3 -p -r1.6 nation.h
--- common/nation.h	2001/10/12 12:22:18	1.6
+++ common/nation.h	2001/11/11 22:32:15
@@ -37,6 +37,10 @@ struct nation_type {
   int  leader_is_male[MAX_NUM_LEADERS];
   int city_style;
   char **default_city_names;
+  char **default_rcity_names;    /* river city names */
+  char **default_crcity_names;   /* coastal-river city names */
+  char **default_ccity_names;    /* coastal city names */
+  char **default_tcity_names[T_COUNT];  /* terrain-specific city names */
   struct Sprite *flag_sprite;
 
   /* untranslated copies: */
Index: server/cityhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/cityhand.c,v
retrieving revision 1.104
diff -u -3 -p -r1.104 cityhand.c
--- server/cityhand.c	2001/10/04 20:23:36	1.104
+++ server/cityhand.c	2001/11/11 22:32:15
@@ -47,13 +47,21 @@ void handle_city_name_suggest_req(struct
 				  struct packet_generic_integer *packet)
 {
   struct packet_city_name_suggestion reply;
+  struct unit *punit;
+
+  punit = player_find_unit_by_id(pconn->player, packet->value);
+
   if (!pconn->player) {
     freelog(LOG_ERROR, "City-name suggestion request from non-player %s",
 	    conn_description(pconn));
     return;
   }
+
+  freelog(LOG_VERBOSE, "Handle_city_name_suggest_req (%d,%d)",
+	  punit->x, punit->y);
+
   reply.id = packet->value;
-  sz_strlcpy(reply.name, city_name_suggestion(pconn->player));
+  sz_strlcpy(reply.name, city_name_suggestion(pconn->player, punit->x, punit->y));
   send_packet_city_name_suggestion(pconn, &reply);
 }
 
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.146
diff -u -3 -p -r1.146 citytools.c
--- server/citytools.c	2001/10/06 21:02:02	1.146
+++ server/citytools.c	2001/11/11 22:32:16
@@ -67,7 +67,7 @@ Returned pointer points into internal da
 buffer etc, and should be considered read-only (and not freed)
 by caller.
 *****************************************************************/
-char *city_name_suggestion(struct player *pplayer)
+char *city_name_suggestion(struct player *pplayer, int x, int y)
 {
   char **nptr;
   int i, j;
@@ -75,13 +75,49 @@ char *city_name_suggestion(struct player
 
   static const int num_tiles = MAP_MAX_WIDTH * MAP_MAX_HEIGHT; 
 
-  freelog(LOG_VERBOSE, "Suggesting city name for %s", pplayer->name);
+  freelog(LOG_VERBOSE, "Suggesting city name for %s (%d,%d)", pplayer->name, x, y);
   
-  for(nptr=get_nation_by_plr(pplayer)->default_city_names; *nptr; nptr++) {
+  /* tile has a river, is coastal, or has a terrain type; use a good name. */ 
+  assert(is_real_tile(x, y));
+
+  /* deal with rivers */
+  if(map_get_special(x, y) & S_RIVER) {
+
+    if(is_terrain_near_tile(x, y, T_OCEAN)) {
+      /* coastal river */
+      for(nptr=get_nation_by_plr(pplayer)->default_crcity_names; *nptr; nptr++){
+	if(!game_find_city_by_name(*nptr))
+	  return *nptr;
+      }
+    } else {
+      /* non-coastal river */
+      for(nptr=get_nation_by_plr(pplayer)->default_rcity_names; *nptr; nptr++){
+	if(!game_find_city_by_name(*nptr))
+	  return *nptr;
+      }
+    }
+  }
+  
+  /* coastal */
+  if(is_terrain_near_tile(x, y, T_OCEAN)){
+    for(nptr=get_nation_by_plr(pplayer)->default_ccity_names; *nptr; nptr++){
+      if(!game_find_city_by_name(*nptr))
+	return *nptr;
+    }
+  }
+  
+  /* check terrain type */
+  for(nptr=get_nation_by_plr(pplayer)->default_tcity_names[map_get_terrain(x, y)]; *nptr; nptr++){
     if(!game_find_city_by_name(*nptr))
       return *nptr;
   }
 
+  /* we haven't found a name: it's a normal tile or they're all used */
+  for(nptr=get_nation_by_plr(pplayer)->default_city_names; *nptr; nptr++) {
+    if(!game_find_city_by_name(*nptr))
+      return *nptr;
+  }
+  
   if (num_misc_city_names > 0) {
     j = myrand(num_misc_city_names);
   
Index: server/citytools.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.h,v
retrieving revision 1.32
diff -u -3 -p -r1.32 citytools.h
--- server/citytools.h	2001/08/30 13:00:15	1.32
+++ server/citytools.h	2001/11/11 22:32:16
@@ -80,7 +80,7 @@ void building_lost(struct city *pcity, i
 void change_build_target(struct player *pplayer, struct city *pcity, 
 			 int target, int is_unit, int event);
 
-char *city_name_suggestion(struct player *pplayer);
+char *city_name_suggestion(struct player *pplayer, int x, int y);
 extern char **misc_city_names; 
 extern int num_misc_city_names;
 
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.82
diff -u -3 -p -r1.82 ruleset.c
--- server/ruleset.c	2001/10/26 07:33:23	1.82
+++ server/ruleset.c	2001/11/11 22:32:17
@@ -1802,6 +1802,7 @@ static void load_ruleset_nations(struct 
   char temp_name[MAX_LEN_NAME];
   char **cities, **techs, **leaders, **sec;
   const char *filename = secfile_filename(file);
+  enum tile_terrain_type type;
 
   datafile_options = check_ruleset_capabilities(file, "+1.9", filename);
 
@@ -2021,6 +2022,60 @@ static void load_ruleset_nations(struct 
       }
     }
     if(cities) free(cities);
+    
+    /* read river city names */
+    cities = secfile_lookup_str_vec(file, &dim, "%s.river_cities", sec[i]);
+    pl->default_rcity_names = fc_calloc(dim+1, sizeof(char*));
+    pl->default_rcity_names[dim] = NULL;
+    for (j = 0; j < dim; j++) {
+      pl->default_rcity_names[j] = mystrdup(cities[j]);
+      if (check_name(cities[j])) {
+	pl->default_rcity_names[j][MAX_LEN_NAME - 1] = 0;
+      }
+    }
+    if(cities) free(cities);
+
+    /* read coastal-river city names */
+    cities = secfile_lookup_str_vec(file, &dim, "%s.coastal_river_cities", sec[i]);
+    pl->default_crcity_names = fc_calloc(dim+1, sizeof(char*));
+    pl->default_crcity_names[dim] = NULL;
+    for (j = 0; j < dim; j++) {
+      pl->default_crcity_names[j] = mystrdup(cities[j]);
+      if (check_name(cities[j])) {
+	pl->default_crcity_names[j][MAX_LEN_NAME - 1] = 0;
+      }
+    }
+    if(cities) free(cities);
+
+    /* read coastal city names */
+    cities = secfile_lookup_str_vec(file, &dim, "%s.coastal_cities", sec[i]);
+    pl->default_ccity_names = fc_calloc(dim+1, sizeof(char*));
+    pl->default_ccity_names[dim] = NULL;
+    for (j = 0; j < dim; j++) {
+      pl->default_ccity_names[j] = mystrdup(cities[j]);
+      if (check_name(cities[j])) {
+	pl->default_ccity_names[j][MAX_LEN_NAME - 1] = 0;
+      }
+    }
+    if(cities) free(cities);
+    
+    for(type=T_FIRST; type<T_COUNT; type++)
+      {
+	/* read terrain-specific city names.
+	 * note that we can't use terrain_name for this because
+	 * it is translated. */
+	cities = secfile_lookup_str_vec(file, &dim, "%s.%s_cities", sec[i], 
+					tile_types[type].graphic_str);
+	pl->default_tcity_names[type] = fc_calloc(dim+1, sizeof(char*));
+	pl->default_tcity_names[type][dim] = NULL;
+	for (j = 0; j < dim; j++) {
+	  pl->default_tcity_names[type][j] = mystrdup(cities[j]);
+	  if (check_name(cities[j])) {
+	    pl->default_tcity_names[type][j][MAX_LEN_NAME - 1] = 0;
+	  }
+	}
+	if(cities) free(cities);
+      }
   }
 
   /* read miscellaneous city names */
@@ -2569,7 +2624,7 @@ void load_rulesets(void)
   load_ruleset_cities(&cityfile);
   load_ruleset_governments(&govfile);
   load_ruleset_units(&unitfile);
-  load_ruleset_terrain(&terrfile);
+  load_ruleset_terrain(&terrfile);    /* terrain must precede nations */
   load_ruleset_buildings(&buildfile);
   load_ruleset_nations(&nationfile);
   load_ruleset_game(game.ruleset.game);
Index: server/settlers.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/settlers.c,v
retrieving revision 1.113
diff -u -3 -p -r1.113 settlers.c
--- server/settlers.c	2001/11/11 15:49:20	1.113
+++ server/settlers.c	2001/11/11 22:32:18
@@ -58,8 +58,8 @@ static int ai_do_build_city(struct playe
   struct packet_unit_request req;
   struct city *pcity;
   req.unit_id=punit->id;
-  sz_strlcpy(req.name, city_name_suggestion(pplayer));
   x = punit->x; y = punit->y; /* Trevor Pering points out that punit gets freed */
+  sz_strlcpy(req.name, city_name_suggestion(pplayer, x, y));
   handle_unit_build_city(pplayer, &req);        
   pcity=map_get_city(x, y); /* so we need to cache x and y for a very short time */
   if (!pcity)
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.144
diff -u -3 -p -r1.144 unittools.c
--- server/unittools.c	2001/11/11 15:49:20	1.144
+++ server/unittools.c	2001/11/11 22:32:19
@@ -2389,7 +2389,7 @@ static void hut_get_city(struct unit *pu
   struct player *pplayer = unit_owner(punit);
   
   if (is_ok_city_spot(punit->x, punit->y)) {
-    create_city(pplayer, punit->x, punit->y, city_name_suggestion(pplayer));
+    create_city(pplayer, punit->x, punit->y, city_name_suggestion(pplayer, punit->x, punit->y));
   } else {
     notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT,
 		     _("Game: Friendly nomads are impressed by you,"