Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2004:
[Freeciv-Dev] (PR#10201) PATCH: generator characteristics evolution, bes
Home

[Freeciv-Dev] (PR#10201) PATCH: generator characteristics evolution, bes

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#10201) PATCH: generator characteristics evolution, best handled temperature and relief.
From: "Marcelo Burda" <mburda@xxxxxxxxx>
Date: Mon, 25 Oct 2004 11:43:54 -0700
Reply-to: rt@xxxxxxxxxxx

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

 
diff -ruN -Xfreeciv/diff_ignore freeciv/common/map.h freeciv_/common/map.h
--- freeciv/common/map.h        2004-10-22 17:33:03.000000000 +0200
+++ freeciv_/common/map.h       2004-10-25 18:11:34.000000000 +0200
@@ -512,7 +512,30 @@
 #define circle_iterate_end                                                  \
     }                                                                       \
   } square_dxy_iterate_end;                                                 \
-}                                                                             
+}
+                                                                              
+/****************************************************************************
+  This iterator behaves like adjc_iterate or cardinal_adjc_iterate depending
+  on the value of card_only.
+****************************************************************************/
+#define variable_adjc_iterate(center_tile, itr_tile, card_only)                
    \
+{                                                                          \
+  enum direction8 *_dirlist;                                               \
+  int _total;                                                              \
+                                                                           \
+  if (card_only) {                                                         \
+    _dirlist = map.cardinal_dirs;                                          \
+    _total = map.num_cardinal_dirs;                                        \
+  } else {                                                                 \
+    _dirlist = map.valid_dirs;                                             \
+    _total = map.num_valid_dirs;                                           \
+  }                                                                        \
+                                                                           \
+  adjc_dirlist_iterate(center_tile, itr_tile, _dir, _dirlist, _total) {
+
+#define variable_adjc_iterate_end                                          \
+  } adjc_dirlist_iterate_end;                                              \
+}
 
 /* Iterate through all map positions adjacent to the given center map
  * position, with normalization.  The order of positions is unspecified. */
diff -ruN -Xfreeciv/diff_ignore freeciv/common/terrain.c 
freeciv_/common/terrain.c
--- freeciv/common/terrain.c    2004-09-29 07:50:48.000000000 +0200
+++ freeciv_/common/terrain.c   2004-10-25 18:11:34.000000000 +0200
@@ -131,30 +131,6 @@
 }
 
 /****************************************************************************
-  This iterator behaves like adjc_iterate or cardinal_adjc_iterate depending
-  on the value of card_only.
-****************************************************************************/
-#define variable_adjc_iterate(center_tile, itr_tile, card_only)                
    \
-{                                                                          \
-  enum direction8 *_dirlist;                                               \
-  int _total;                                                              \
-                                                                           \
-  if (card_only) {                                                         \
-    _dirlist = map.cardinal_dirs;                                          \
-    _total = map.num_cardinal_dirs;                                        \
-  } else {                                                                 \
-    _dirlist = map.valid_dirs;                                             \
-    _total = map.num_valid_dirs;                                           \
-  }                                                                        \
-                                                                           \
-  adjc_dirlist_iterate(center_tile, itr_tile, _dir, _dirlist, _total) {
-
-#define variable_adjc_iterate_end                                          \
-  } adjc_dirlist_iterate_end;                                              \
-}
-
-
-/****************************************************************************
   Returns TRUE iff any adjacent tile contains the given terrain.
 ****************************************************************************/
 bool is_terrain_near_tile(const struct tile *ptile, Terrain_type_id t)
diff -ruN -Xfreeciv/diff_ignore freeciv/server/generator/characteristics.c 
freeciv_/server/generator/characteristics.c
--- freeciv/server/generator/characteristics.c  1970-01-01 01:00:00.000000000 
+0100
+++ freeciv_/server/generator/characteristics.c 2004-10-25 18:11:34.000000000 
+0200
@@ -0,0 +1,958 @@
+/********************************************************************** 
+   Copyright (C) 1996-2004  The Freeciv Project Team
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+#include "config.h"
+#include "log.h"
+#include "map.h"
+#include "rand.h"
+
+#include "utilities.h"
+#include "characteristics.h"
+#include "height_map.h"
+#include "mapgen_topology.h"
+
+#define RIVERS_MAXTRIES 32767
+enum river_map_type {RS_BLOCKED = 0, RS_RIVER = 1};
+
+static characteristic_type *characteristic_map;
+characteristic_type CM_OR, CM_AND, CM_NOT, CM_NOT_PLACED;
+characteristic_type CM_TRUE, CM_FALSE;
+characteristic_type CM_FLAT, CM_HILLY, CM_ABRUPT,
+                    CM_NFLAT;
+characteristic_type CM_FROZEN, CM_COLD, CM_TEMPERATE, CM_TROPICAL,
+                    CM_NFROZEN,  CM_ALL, CM_NHOT, CM_HOT;
+characteristic_type CM_OCEANIC,  CM_WET, CM_MEDIUM, CM_DRY,
+                    CM_NWET, CM_NDRY;
+characteristic_type CM_RIVER;
+
+
+void characteristics_initialize_shores(bool real);
+void characteristics_initialize_extra_polar_land(void);
+void characteristics_initialize_relief(void);
+void characteristics_initialize_temperature(bool real);
+void characteristics_initialize_wetness(void);
+
+#define MAX_PILE 8
+characteristic_type *pile[MAX_PILE];
+int pile_count = -1;
+
+/********************************************************************
+ push a pointer on pile
+*********************************************************************/
+static void push_pile(characteristic_type *p)
+{
+  assert(pile_count < MAX_PILE - 1);
+  pile[++pile_count] = p;
+}
+
+/********************************************************************
+ pop a pointer from pile
+*********************************************************************/
+static characteristic_type *pop_pile(void)
+{
+assert(pile_count >= 0);
+ return pile[pile_count--];
+}
+
+/********************************************************************
+ evaluate a condition in RPN
+*********************************************************************/
+bool characteristic_condition(const struct tile *ptile,
+                             characteristic_type **null_ended_array)
+{
+  bool arg1 = FALSE, arg2 = FALSE;
+  while (NULL != *null_ended_array) {
+    if (&CM_NOT == *null_ended_array) {
+      arg1 = is_characteristic(ptile, *pop_pile());
+      push_pile((!arg1)? &CM_TRUE: &CM_FALSE);
+    } else if (&CM_NOT_PLACED == *null_ended_array) {
+      push_pile(not_placed(ptile) ? &CM_TRUE: &CM_FALSE);
+    } else if (&CM_AND == *null_ended_array) {
+      arg1 = is_characteristic(ptile, *pop_pile());
+      arg2 = is_characteristic(ptile, *pop_pile());
+      push_pile((arg1 && arg2) ? &CM_TRUE: &CM_FALSE);
+    } else if (&CM_OR == *null_ended_array) {
+      arg1 = is_characteristic(ptile, *pop_pile());
+      arg2 = is_characteristic(ptile, *pop_pile());
+      push_pile((arg1 || arg2) ? &CM_TRUE: &CM_FALSE);
+    } else {
+      push_pile(*null_ended_array);
+    }
+    null_ended_array++;
+  }
+  assert(0 == pile_count);
+  pile_count--;
+  return is_characteristic(ptile, *pile[0]);
+}
+
+/********************************************************************
+ evaluate a condition in RPN
+*********************************************************************/
+bool filter_characteristic(const struct tile *ptile, const void *data)
+{
+  data_filter_chracteristic_type *pdata = 
+      (data_filter_chracteristic_type *) data;
+  return characteristic_condition(ptile, pdata->null_ended_array);
+}
+
+/**************************************************************************
+ return TRUE if initialized
+*************************************************************************/ 
+bool characteristics_are_initialized(void)
+{
+  return characteristic_map != NULL;
+}
+
+/****************************************************************************
+ create the map and initialize CM_XXX
+ call other inizialize methodes
+ if has_height_map is FALSE only initialize temperature with not height map
+ (hack for gen 2-4, and for loaded maps with not hut or spetials)
+****************************************************************************/
+void create_characteristics(bool has_height_map)                               
+{                                                          
+  assert( !characteristics_are_initialized());                              
+  characteristic_map = fc_malloc (sizeof(characteristic_type) * MAX_MAP_INDEX);
+  whole_map_iterate(i) {
+    BV_CLR_ALL(characteristic_map[i->index]);
+    BV_SET(characteristic_map[i->index], CB_TRUE);
+  }whole_map_iterate_end;
+
+  
+  BV_CLR_ALL(CM_TRUE);
+  BV_SET(CM_TRUE, CB_TRUE);
+  BV_CLR_ALL(CM_FALSE);
+
+  /* initialize constant values of relief */
+  BV_CLR_ALL(CM_FLAT);
+  BV_SET(CM_FLAT, CB_FLAT);
+  BV_CLR_ALL(CM_HILLY);
+  BV_SET(CM_HILLY, CB_HILLY);
+  BV_CLR_ALL(CM_ABRUPT);
+  BV_SET(CM_ABRUPT, CB_ABRUPT);
+  BV_CLR_ALL(CM_NFLAT);
+  BV_SET(CM_NFLAT, CB_HILLY);
+  BV_SET(CM_NFLAT, CB_ABRUPT);
+
+  /* inizialize constant value of temperature */
+  BV_CLR_ALL(CM_FROZEN);
+  BV_SET(CM_FROZEN, CB_FROZEN);
+  BV_CLR_ALL(CM_COLD);
+  BV_SET(CM_COLD, CB_COLD);
+  BV_CLR_ALL(CM_TEMPERATE);
+  BV_SET(CM_TEMPERATE, CB_TEMPERATE);
+  BV_CLR_ALL(CM_TROPICAL);
+  BV_SET(CM_TROPICAL, CB_TROPICAL);
+
+  BV_CLR_ALL(CM_NFROZEN);
+  BV_SET(CM_NFROZEN, CB_COLD);
+  BV_SET(CM_NFROZEN, CB_TEMPERATE);
+  BV_SET(CM_NFROZEN, CB_TROPICAL);
+
+  BV_CLR_ALL(CM_ALL);
+  BV_SET(CM_ALL, CB_FROZEN);
+  BV_SET(CM_ALL, CB_COLD);
+  BV_SET(CM_ALL, CB_TEMPERATE);
+  BV_SET(CM_ALL, CB_TROPICAL);
+
+  BV_CLR_ALL(CM_NHOT);
+  BV_SET(CM_NHOT, CB_FROZEN);
+  BV_SET(CM_NHOT, CB_COLD);
+ 
+  BV_CLR_ALL(CM_HOT);
+  BV_SET(CM_HOT, CB_TEMPERATE);
+  BV_SET(CM_HOT, CB_TROPICAL);
+
+  BV_CLR_ALL(CM_OCEANIC);
+  BV_SET(CM_OCEANIC, CB_OCEANIC);
+  BV_CLR_ALL(CM_WET);
+  BV_SET(CM_WET, CB_WET);
+  BV_CLR_ALL(CM_MEDIUM);
+  BV_SET(CM_MEDIUM, CB_MEDIUM);
+  BV_CLR_ALL(CM_DRY);
+  BV_SET(CM_DRY, CB_DRY);
+
+  BV_CLR_ALL(CM_NWET);
+  BV_SET(CM_NWET, CB_MEDIUM);
+  BV_SET(CM_NWET, CB_DRY);
+
+  BV_CLR_ALL(CM_NDRY);
+  BV_SET(CM_NDRY, CB_MEDIUM);
+  BV_SET(CM_NDRY, CB_WET);
+  
+  BV_CLR_ALL(CM_RIVER);
+  BV_SET(CM_RIVER, CB_RIVER);
+  
+
+  if (has_height_map) {
+    /* now initialize the oceanic tiles and the shore_level */
+    characteristics_initialize_shores(TRUE);
+    /* this is a hack to terrains-set with not frozen oceans*/
+    if (HAS_POLES) { 
+      characteristics_initialize_extra_polar_land();
+    }
+    /*
+      initialize the temperature and relief characteristics, these call
+      need, other the height map and colatitude, to known the oceanics
+      tiles and the shore_level
+    */ 
+    characteristics_initialize_relief();
+    characteristics_initialize_temperature(TRUE);
+    
+    /*
+      now initialize wetness, this call need other characteristics to be
+      initilaized.
+    */
+    characteristics_initialize_wetness(); /* and rivers */
+    
+  } else {
+      characteristics_initialize_shores(FALSE);
+      characteristics_initialize_temperature(FALSE);
+  }
+}
+
+/**************************************************************************** 
+  Free the map
+****************************************************************************/
+void destroy_characteristics(void)   
+{                              
+  assert(characteristics_are_initialized()); 
+  free(characteristic_map);            
+  characteristic_map = NULL;           
+}
+/***************************************************************************
+ Test the characteristic of a index position on map
+ ***************************************************************************/
+
+bool is_characteristic(const struct tile *ptile, characteristic_type mask )
+{
+  return BV_CHECK_MASK(characteristic_map[ptile->index], mask);
+}
+
+/******************************************************************
+ Return the number of tiles adjacent to the given place with the right
+ characteristic mask.
+ ******************************************************************/
+int count_characteristic_near(const struct tile *ptile, bool cardinal_only,
+                             bool percentage
+                             ,characteristic_type mask)
+{
+  int count = 0, total = 0;
+
+  variable_adjc_iterate(ptile, ptile1, cardinal_only) {
+    if (is_characteristic(ptile1, mask)) {
+      count++;
+    }
+    total++;
+  } variable_adjc_iterate_end;
+
+  if (percentage) {
+    count = count * 100 / total;
+  }
+  return count;
+}
+/**************************************************************************** 
+  set all tiles in placed_map when this has the right CM_XXX mask
+****************************************************************************/
+static void set_all_mask_placed(characteristic_type mask) 
+{                               
+  whole_map_iterate(i) {     
+    if (is_characteristic(i, mask)) { 
+      map_set_placed(i);     
+    }                           
+  } whole_map_iterate_end;      
+}
+
+/*************************************************************************
+ set CB_OCEANIC in thiles will be oceans
+ ************************************************************************/
+void characteristics_initialize_shores(bool real)
+{
+  if (real) {
+    if (HAS_POLES) {
+      normalize_hmap_poles();
+    }
+    hmap_shore_level = (hmap_max_level * (100 - map.landpercent)) / 100;
+    whole_map_iterate(i) {
+      if (height_map[i->index] < hmap_shore_level) {
+       BV_SET(characteristic_map[i->index], CB_OCEANIC);
+      }
+    }
+    whole_map_iterate_end;
+    if (HAS_POLES) {
+      renormalize_hmap_poles();
+    }
+  } else {
+    whole_map_iterate(ptile) {
+      if (is_ocean(map_get_terrain(ptile))) {
+       BV_SET(characteristic_map[ptile->index], CB_OCEANIC);
+      }
+    } whole_map_iterate_end;
+  }
+}
+
+/*************************************************************************
+ if separatepoles is set, return false if this tile has to keep ocean
+************************************************************************/
+static bool ok_for_separate_poles(const struct tile *ptile) 
+{
+  if (!map.separatepoles) {
+    return TRUE;
+  }
+  adjc_iterate(ptile, ptile1) {
+    if(!is_characteristic(ptile1, CM_OCEANIC) &&
+       (map_colatitude(ptile1) > 2 * ICE_BASE_LEVEL)) {
+      return FALSE;
+    }
+  } adjc_iterate_end;
+  return TRUE;
+}
+
+/****************************************************************************
+  Place untextured land at the poles.  This is used by generators 1 and 5
+  on tiles-sets with not forzen oceans
+****************************************************************************/
+void characteristics_initialize_extra_polar_land(void)
+{
+  whole_map_iterate(i) {
+    if ((map_colatitude(i) <=  2 * ICE_BASE_LEVEL) &&
+         ok_for_separate_poles(i)) {
+      BV_CLR(characteristic_map[i->index], CB_OCEANIC);
+    } 
+  } whole_map_iterate_end;
+}
+
+/**************************************************************************
+  we don't want huge flat areas, 
+  so we put in a hill here and there, where it gets too flat 
+
+  Return TRUE if the terrain at the given map position is too flat.  This
+  means that all the terrain for 2 squares around it are only flat.
+****************************************************************************/
+static bool map_is_too_flat(const struct tile *ptile,
+                               int thill, int my_height)
+{
+  int higher_than_me = 0;
+
+  square_iterate(ptile, 2, ptile1) {
+    if (hmap(ptile1) > thill) {
+      return FALSE;
+    }
+    if (hmap(ptile1) > my_height) {
+      if (map_distance(ptile, ptile1) == 1) {
+       return FALSE;
+      }
+      if (++higher_than_me > 2) {
+       return FALSE;
+      }
+    }
+  } square_iterate_end;
+
+  if ((thill - hmap_shore_level) * higher_than_me  > 
+      (my_height - hmap_shore_level) * 4) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**************************************************************************
+  we don't want huge areas of hill/mountains, 
+  so we put in a plains here and there, where it gets too heigh 
+
+  Return TRUE if the terrain at the given map position is too heigh.
+****************************************************************************/
+static bool map_is_too_high(const struct tile *ptile,
+                               int thill, int my_height)
+{
+  square_iterate(ptile, 1, ptile1) {
+    if (hmap(ptile1) + (hmap_max_level - hmap_mountain_level) / 5 < thill) {
+      return FALSE;
+    }
+  } square_iterate_end;
+  return TRUE;
+}
+
+/**************************************************************************
+  make_relief() will convert all squares that are higher than thill to
+  mountains and hills. Note that thill will be adjusted according to
+  the map.steepness value, so increasing map.steepness will result in
+  more hilly and abrupts maps.
+**************************************************************************/
+void characteristics_initialize_relief(void)
+{
+  /* Calculate the mountain level.  map.mountains specifies the percentage
+   * of land that is turned into hills and mountains. */
+  hmap_mountain_level = ((hmap_max_level - hmap_shore_level)
+                        * (100 - map.steepness)) / 100 + hmap_shore_level;
+
+  whole_map_iterate(i) {
+    if (!is_characteristic(i, CM_OCEANIC) &&
+       ((hmap_mountain_level < height_map[i->index] && 
+         (myrand(10) > 5 
+          || !map_is_too_high(i, hmap_mountain_level, height_map[i->index])))
+        || map_is_too_flat(i, hmap_mountain_level, height_map[i->index]))) {
+      /* Randomly place hills and mountains on "high" tiles. */
+      if (myrand(100) > 70) {
+       BV_SET(characteristic_map[i->index], CB_ABRUPT);
+      } else {
+       BV_SET(characteristic_map[i->index], CB_HILLY);
+      }
+    } else {
+       BV_SET(characteristic_map[i->index], CB_FLAT);
+    }
+  } whole_map_iterate_end;
+}
+
+/***************************************************************************
+ * create_tmap initialize the temperature_map
+ * if arg is FALSE, create a dumy tmap == map_colattitude
+ * to be used if hmap or oceans are not placed gen 2-4
+ ***************************************************************************/
+void characteristics_initialize_temperature(bool real)
+{
+  int temperature[MAX_MAP_INDEX];
+
+  whole_map_iterate(i) {
+  
+     /* the base temperature is equal to base map_colatitude */
+    int t = map_colatitude(i) ;
+    if (!real) {
+      temperature[i->index] =  t;
+    } else {
+      /* height land can be 30% collest */
+      float height = - 0.3 * MAX(0, height_map[i->index] - hmap_shore_level) 
+         / (hmap_max_level - hmap_shore_level); 
+      /* near ocean temperature can be 15 % more "temperate" */
+      float temperate = 0.15 * (map.temperature / 100 - t / MAX_COLATITUDE) * 
+         2 * MIN (50 ,
+                  count_characteristic_near(i, FALSE, TRUE, CM_OCEANIC)) /
+         100;
+      
+      temperature[i->index] = t * (1.0 + temperate) * (1.0 + height);
+    }
+  } whole_map_iterate_end;
+  /* adjust to get well sizes frequencies */
+  /* Notice: if colatitude is load from a scenario never call adjust has
+             scenario maybe has a odd colatitude ditribution and adjust will
+            brack it */
+  if (!map.alltemperate) {
+    adjust_int_map(temperature, MAX_COLATITUDE);
+  }
+  /* now simplify to 4 base values */ 
+  whole_map_iterate(i) {
+    int t = temperature[i->index];
+
+    /* first if is a hack to avoid some ugly effect,
+       TODO: think if there is a best way, veriffy off by one in colatitude */ 
+    if (map_colatitude(i) < 2 * ICE_BASE_LEVEL) {
+      BV_SET(characteristic_map[i->index], CB_FROZEN);
+    } 
+
+    else if (t >= TROPICAL_LEVEL ) {
+      BV_SET(characteristic_map[i->index], CB_TROPICAL);
+    } else if (t >= COLD_LEVEL) {
+      BV_SET(characteristic_map[i->index], CB_TEMPERATE);
+    } else if (t >= 2 * ICE_BASE_LEVEL) {
+      BV_SET(characteristic_map[i->index], CB_COLD);
+    } else {
+      BV_SET(characteristic_map[i->index], CB_FROZEN);
+    }
+  }  whole_map_iterate_end;
+}
+
+/*********************************************************************
+ Help function used in make_river(). See the help there.
+*********************************************************************/
+static int river_test_blocked(const struct tile *ptile, int *river_map)
+{
+  if (TEST_BIT(river_map[ptile->index], RS_BLOCKED))
+    return 1;
+
+  /* any un-blocked? */
+  cardinal_adjc_iterate(ptile, ptile1) {
+    if (!TEST_BIT(river_map[ptile1->index], RS_BLOCKED))
+      return 0;
+  } cardinal_adjc_iterate_end;
+
+  return 1; /* none non-blocked |- all blocked */
+}
+
+/*********************************************************************
+ Help function used in make_river(). See the help there.
+*********************************************************************/
+static int river_test_rivergrid(const struct tile *ptile, int *river_map)
+{
+  return (count_characteristic_near(ptile, TRUE, FALSE, CM_RIVER) 
+         > 1) ? 1 : 0;
+}
+
+/*********************************************************************
+ Help function used in make_river(). See the help there.
+*********************************************************************/
+static int river_test_highlands(const struct tile *ptile, int *river_map)
+{
+  return ((is_characteristic(ptile, CM_HILLY)  ? 1 : 0) +
+         (is_characteristic(ptile, CM_ABRUPT) ? 2 : 0));
+}
+
+/*********************************************************************
+ Help function used in make_river(). See the help there.
+*********************************************************************/
+static int river_test_adjacent_ocean(const struct tile *ptile, int *river_map)
+{
+  return 100 - count_characteristic_near(ptile, TRUE, TRUE, CM_OCEANIC);
+}
+
+/*********************************************************************
+ Help function used in make_river(). See the help there.
+*********************************************************************/
+static int river_test_adjacent_river(const struct tile *ptile, int *river_map)
+{
+  return 100 - count_characteristic_near(ptile, TRUE, TRUE, CM_RIVER);
+}
+
+/*********************************************************************
+ Help function used in make_river(). See the help there.
+*********************************************************************/
+static int river_test_adjacent_highlands(const struct tile *ptile,
+                                        int *river_map)
+{
+  return (count_characteristic_near(ptile, TRUE, TRUE, CM_HILLY)
+         + 2 * count_characteristic_near(ptile, TRUE, TRUE, CM_ABRUPT));
+}
+
+/*********************************************************************
+ Help function used in make_river(). See the help there.
+*********************************************************************/
+static int river_test_height_map(const struct tile *ptile, int *river_map)
+{
+  return height_map[ptile->index];
+}
+
+/*********************************************************************
+ Called from make_river. Marks all directions as blocked.  -Erik Sigra
+*********************************************************************/
+static void river_blockmark(const struct tile *ptile, int *river_map)
+{
+  freelog(LOG_DEBUG, "Blockmarking (%d) and adjacent tiles.",
+         ptile->index);
+
+  river_map[ptile->index] |= (1u << RS_BLOCKED);
+
+  cardinal_adjc_iterate(ptile, ptile1) {
+    river_map[ptile1->index] |= (1u << RS_BLOCKED);
+  } cardinal_adjc_iterate_end;
+}
+
+struct test_func {
+  int (*func)(const struct tile *, int*);
+  bool fatal;
+};
+
+#define NUM_TEST_FUNCTIONS 7
+static struct test_func test_funcs[NUM_TEST_FUNCTIONS] = {
+  {river_test_blocked,            TRUE},
+  {river_test_rivergrid,          TRUE},
+  {river_test_highlands,          FALSE},
+  {river_test_adjacent_ocean,     FALSE},
+  {river_test_adjacent_river,     FALSE},
+  {river_test_adjacent_highlands, FALSE},
+  {river_test_height_map,         FALSE}
+};
+
+/********************************************************************
+ Makes a river starting at (x, y). Returns 1 if it succeeds.
+ Return 0 if it fails. The river is stored in river_map.
+ 
+ How to make a river path look natural
+ =====================================
+ Rivers always flow down. Thus rivers are best implemented on maps
+ where every tile has an explicit height value. However, Freeciv has a
+ flat map. But there are certain things that help the user imagine
+ differences in height between tiles. The selection of direction for
+ rivers should confirm and even amplify the user's image of the map's
+ topology.
+ 
+ To decide which direction the river takes, the possible directions
+ are tested in a series of test until there is only 1 direction
+ left. Some tests are fatal. This means that they can sort away all
+ remaining directions. If they do so, the river is aborted. Here
+ follows a description of the test series.
+ 
+ * Falling into itself: fatal
+     (river_test_blocked)
+     This is tested by looking up in the river_map array if a tile or
+     every tile surrounding the tile is marked as blocked. A tile is
+     marked as blocked if it belongs to the current river or has been
+     evaluated in a previous iteration in the creation of the current
+     river.
+     
+     Possible values:
+     0: Is not falling into itself.
+     1: Is falling into itself.
+     
+ * Forming a 4-river-grid: optionally fatal
+     (river_test_rivergrid)
+     A minimal 4-river-grid is formed when an intersection in the map
+     grid is surrounded by 4 river tiles. There can be larger river
+     grids consisting of several overlapping minimal 4-river-grids.
+     
+     Possible values:
+     0: Is not forming a 4-river-grid.
+     1: Is forming a 4-river-grid.
+
+ * Highlands:
+     (river_test_highlands)
+     Rivers must not flow up in mountains or hills if there are
+     alternatives.
+     
+     Possible values:
+     0: Is not hills and not mountains.
+     1: Is hills.
+     2: Is mountains.
+
+ * Adjacent ocean:
+     (river_test_adjacent_ocean)
+     Rivers must flow down to coastal areas when possible:
+
+     Possible values: 0-100
+
+ * Adjacent river:
+     (river_test_adjacent_river)
+     Rivers must flow down to areas near other rivers when possible:
+
+     Possible values: 0-100
+                                       
+ * Adjacent highlands:
+     (river_test_adjacent_highlands)
+     Rivers must not flow towards highlands if there are alternatives. 
+     
+ * height_map:
+     (river_test_height_map)
+     Rivers must flow in the direction which takes it to the tile with
+     the lowest value on the height_map.
+     
+     Possible values:
+     n: height_map[...]
+     
+ If these rules haven't decided the direction, the random number
+ generator gets the desicion.                              -Erik Sigra
+*********************************************************************/
+static bool make_river(struct tile *ptile, int *river_map)
+{
+  /* Comparison value for each tile surrounding the current tile.  It is
+   * the suitability to continue a river to the tile in that direction;
+   * lower is better.  However rivers may only run in cardinal directions;
+   * the other directions are ignored entirely. */
+  int rd_comparison_val[8];
+
+  bool rd_direction_is_valid[8];
+  int num_valid_directions, func_num, direction;
+
+  while (TRUE) {
+    /* Mark the current tile as river. */
+    river_map[ptile->index] |= (1u << RS_RIVER);
+    freelog(LOG_DEBUG,
+           "The tile at (%d) has been marked as river in river_map.\n",
+           ptile->index);
+
+    /* Test if the river is done. */
+    /* We arbitrarily make rivers end at the poles. */
+    if (count_characteristic_near(ptile, TRUE, TRUE, CM_RIVER)
+       + count_characteristic_near(ptile, TRUE, TRUE, CM_OCEANIC) > 0
+        || (is_characteristic(ptile, CM_FROZEN) 
+           &&  is_characteristic(ptile, CM_FLAT))) { 
+
+      freelog(LOG_DEBUG,
+             "The river ended at (%d).\n", ptile->index);
+      return TRUE;
+    }
+
+    /* Else choose a direction to continue the river. */
+    freelog(LOG_DEBUG,
+           "The river did not end at (%d). Evaluating directions...\n",
+           ptile->index);
+
+    /* Mark all available cardinal directions as available. */
+    memset(rd_direction_is_valid, 0, sizeof(rd_direction_is_valid));
+    cardinal_adjc_dir_iterate(ptile, ptile1, dir) {
+      rd_direction_is_valid[dir] = TRUE;
+    } cardinal_adjc_dir_iterate_end;
+
+    /* Test series that selects a direction for the river. */
+    for (func_num = 0; func_num < NUM_TEST_FUNCTIONS; func_num++) {
+      int best_val = -1;
+
+      /* first get the tile values for the function */
+      cardinal_adjc_dir_iterate(ptile, ptile1, dir) {
+
+       if (rd_direction_is_valid[dir]) {
+         rd_comparison_val[dir] = 
+             (test_funcs[func_num].func) (ptile1 , river_map);
+         if (best_val == -1) {
+           best_val = rd_comparison_val[dir];
+         } else {
+           best_val = MIN(rd_comparison_val[dir], best_val);
+         }
+       }
+      } cardinal_adjc_dir_iterate_end;
+      assert(best_val != -1);
+
+      /* should we abort? */
+      if (best_val > 0 && test_funcs[func_num].fatal) {
+       return FALSE;
+      }
+
+      /* mark the less attractive directions as invalid */
+      cardinal_adjc_dir_iterate(ptile, ptile1, dir) {
+       if (rd_direction_is_valid[dir]) {
+         if (rd_comparison_val[dir] != best_val) {
+           rd_direction_is_valid[dir] = FALSE;
+         }
+       }
+      } cardinal_adjc_dir_iterate_end;
+    }
+
+    /* Directions evaluated with all functions. Now choose the best
+       direction before going to the next iteration of the while loop */
+    num_valid_directions = 0;
+    cardinal_adjc_dir_iterate(ptile, ptile1, dir) {
+      if (rd_direction_is_valid[dir]) {
+       num_valid_directions++;
+      }
+    } cardinal_adjc_dir_iterate_end;
+
+    if (num_valid_directions == 0) {
+      return FALSE; /* river aborted */
+    }
+
+    /* One or more valid directions: choose randomly. */
+    freelog(LOG_DEBUG, "mapgen.c: Had to let the random number"
+           " generator select a direction for a river.");
+    direction = myrand(num_valid_directions);
+    freelog(LOG_DEBUG, "mapgen.c: direction: %d", direction);
+
+    /* Find the direction that the random number generator selected. */
+    cardinal_adjc_dir_iterate(ptile, ptile1, dir) {
+      if (rd_direction_is_valid[dir]) {
+       if (direction > 0) {
+         direction--;
+       } else {
+         river_blockmark(ptile1, river_map);
+         ptile = ptile1;
+         break;
+       }
+      }
+    } cardinal_adjc_dir_iterate_end;
+    assert(direction == 0);
+  } /* end while; (Make a river.) */
+}
+
+/**************************************************************************
+  Calls make_river until there are enough river tiles on the map. It stops
+  when it has tried to create RIVERS_MAXTRIES rivers.           -Erik Sigra
+**************************************************************************/
+static void make_rivers(int *river_probability)
+{
+  int river_map[MAX_MAP_INDEX];
+  int polar = 2 * ICE_BASE_LEVEL * map.landpercent / MAX_COLATITUDE ;
+  /* magic math to evaluater river_pct  3 - 11 % */
+  int river_pct =  (100 - polar) * (3 + map.wetness / 12) / 100;
+
+  /* Formula to make the river density similar om different sized maps. Avoids
+     too few rivers on large maps and too many rivers on small maps. */
+  int desirable_riverlength =
+      
+    river_pct *
+      /* The size of the map (poles counted in river_pct). */
+      map_num_tiles() *
+      /* Rivers need to be on land only. */
+      map.landpercent /
+      /* Adjustment value. Tested by me. Gives no rivers with 'set
+        rivers 0', gives a reasonable amount of rivers with default
+        settings and as many rivers as possible with 'set rivers 100'. */
+      5325;
+
+  /* The number of river tiles that have been set. */
+  int current_riverlength = 0;
+
+  /* Counts the number of iterations (should increase with 1 during
+     every iteration of the main loop in this function).
+     Is needed to stop a potentially infinite loop. */
+  int iteration_counter = 0;
+
+  create_placed_map(); /* needed bu rand_map_characteristic */
+  set_all_mask_placed(CM_OCEANIC);
+
+  /* The main loop in this function. */
+  while (current_riverlength < desirable_riverlength
+        && iteration_counter < RIVERS_MAXTRIES) {
+    characteristic_type *condition[] = {&CM_NFROZEN, NULL};
+    data_filter_chracteristic_type data;
+    struct tile *ptile ;
+
+    data.null_ended_array = condition;
+    ptile = rand_map_pos_filtered((void *)&data, filter_characteristic);
+
+    if (NULL == ptile) {
+       break; /* mo more spring places */
+    }
+
+    /* Check if it is suitable to start a river on the current tile.
+     */
+    if ((myrand(100) < river_probability[ptile->index])
+       /* Don't start a river on a tile is surrounded by > 1 river +
+          ocean tile. */
+       && (count_characteristic_near(ptile, TRUE, FALSE, CM_RIVER)
+          + count_characteristic_near(ptile, TRUE, FALSE, CM_OCEANIC) <= 1)
+
+       /* Don't start a river on a tile that is surrounded by hills or
+          mountains unless it is hard to find somewhere else to start
+          it. */
+       && (count_characteristic_near(ptile, TRUE, TRUE, CM_ABRUPT)
+         + count_characteristic_near(ptile, TRUE, TRUE, CM_HILLY) < 90
+           || (iteration_counter > RIVERS_MAXTRIES / 10 * 5))
+
+       /* Don't start a river on hills unless it is hard to find
+          somewhere else to start it. */
+       && (!is_characteristic(ptile, CM_HILLY)
+           || (iteration_counter > RIVERS_MAXTRIES / 10 * 6))
+
+       /* Don't start a river on mountains unless it is hard to find
+          somewhere else to start it. */
+       && (!is_characteristic(ptile, CM_ABRUPT)
+           || (iteration_counter > RIVERS_MAXTRIES / 10 * 7))
+       ) {
+
+      /* Reset river_map before making a new river. */
+      whole_map_iterate(i) {
+       river_map[i->index] = 0;
+      } whole_map_iterate_end;
+
+      freelog(LOG_DEBUG,
+             "Found a suitable starting tile for a river at (%d)."
+             " Starting to make it.",
+             ptile->index);
+
+      /* Try to make a river. If it is OK, apply it to the map. */
+      if (make_river(ptile, river_map)) {
+       whole_map_iterate(ptile1) {
+         if (TEST_BIT(river_map[ptile1->index], RS_RIVER)) {
+           BV_SET(characteristic_map[ptile1->index], CB_RIVER);
+           current_riverlength++;
+           map_set_placed(ptile1);
+           /* reduce probability near a river */
+           circle_iterate(ptile1, 4, ptile2) {
+               river_probability[ptile2->index] *= 0.9;
+           } circle_iterate_end;
+           freelog(LOG_DEBUG, "Applied a river to (%d).",
+                   ptile1->index);
+         }
+       } whole_map_iterate_end;
+      }
+      else {
+       freelog(LOG_DEBUG,
+       "mapgen.c: A river failed. It might have gotten stuck in a helix.");
+      }
+    } /* end if; */
+    iteration_counter++;
+    freelog(LOG_DEBUG,
+    "current_riverlength: %d; desirable_riverlength: %d; iteration_counter: %d"
+           ,current_riverlength, desirable_riverlength, iteration_counter);
+  } /* end while; */
+
+  destroy_placed_map();
+}
+
+#define colatitude_is_dry(i)                           \
+  (map_colatitude((i)) <= DRY_MAX_LEVEL                        \
+   && map_colatitude((i)) > DRY_MIN_LEVEL)
+
+void characteristics_initialize_wetness()
+{
+  int wetness[MAX_MAP_INDEX];
+
+  /* there wetness[]  means the probability to start a river*/
+  whole_map_iterate(i) {
+    if (colatitude_is_dry(i)) {
+      wetness[i->index] = 70;
+    } else {
+      wetness[i->index] = 100;
+    }
+  } whole_map_iterate_end;
+
+  make_rivers(wetness);
+
+  /* now wetness[] means amount of water */
+  whole_map_iterate(i) {
+    float dry_bonus = colatitude_is_dry(i) ? 1 : 0;
+    float tropical_bonus = (map_colatitude(i) > TROPICAL_LEVEL) ? 1 : 0;
+    float height_bonus = MAX(0, (height_map[i->index] -  hmap_shore_level))
+                            / (hmap_max_level - hmap_shore_level);
+    float river_bonus = is_characteristic(i, CM_RIVER) ? 1 : 0;
+    float ocean_bonus = is_characteristic(i, CM_OCEANIC) ? 1 : 0;
+
+    wetness[i->index] = (100 - 10 * dry_bonus + 5 * tropical_bonus)
+       * (100 + 30 * river_bonus + 20 * ocean_bonus)
+       * (100 + 30 * height_bonus) / 100;
+  } whole_map_iterate_end;
+
+  smooth_int_map(wetness, FALSE);
+  {
+    data_filter_chracteristic_type data;
+    characteristic_type CM_AVOID;
+
+    BV_CLR_ALL(CM_AVOID);
+    BV_SET(CM_AVOID, CB_FROZEN);
+    BV_SET(CM_AVOID, CB_OCEANIC);
+    {
+      characteristic_type *condition[] 
+         = {&CM_OCEANIC, &CM_NOT, &CM_FROZEN, &CM_AND, NULL};
+      data.null_ended_array = condition;
+      adjust_int_map_filtered(wetness, 1000, (void *)&data,
+                             filter_characteristic);
+    } 
+    {
+      characteristic_type *condition[] 
+         = {&CM_AVOID, &CM_NOT, &CM_FLAT, &CM_AND, NULL};
+      data.null_ended_array = condition;
+      adjust_int_map_filtered(wetness, 1000, (void *)&data,
+                             filter_characteristic);
+    } 
+    {
+      characteristic_type *condition[] 
+         = {&CM_AVOID, &CM_NOT, &CM_HILLY, &CM_AND, NULL};
+      data.null_ended_array = condition;
+      adjust_int_map_filtered(wetness, 1000, (void *)&data,
+                             filter_characteristic);
+    } 
+    {
+      characteristic_type *condition[] 
+         = {&CM_AVOID, &CM_NOT, &CM_ABRUPT, &CM_AND, NULL};
+      data.null_ended_array = condition;
+      adjust_int_map_filtered(wetness, 1000, (void *)&data,
+                             filter_characteristic);
+    }
+  }
+  whole_map_iterate(i) {
+    if (is_characteristic(i, CM_OCEANIC)) {
+      continue;
+    }
+    if (wetness[i->index] < 300) {
+      BV_SET(characteristic_map[i->index], CB_DRY);
+    } else if(wetness[i->index] < 700){
+      BV_SET(characteristic_map[i->index], CB_MEDIUM);
+    } else  {
+      BV_SET(characteristic_map[i->index], CB_WET);
+    } 
+  } whole_map_iterate_end;
+}
diff -ruN -Xfreeciv/diff_ignore freeciv/server/generator/characteristics.h 
freeciv_/server/generator/characteristics.h
--- freeciv/server/generator/characteristics.h  1970-01-01 01:00:00.000000000 
+0100
+++ freeciv_/server/generator/characteristics.h 2004-10-25 18:11:34.000000000 
+0200
@@ -0,0 +1,63 @@
+/********************************************************************** 
+   Copyright (C) 1996-2004 - The Freeciv Project Team,
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+#ifndef FC__CHARACTERISTICS_H
+#define FC__CHARACTERISTICS_H
+
+BV_DEFINE(characteristic_type, 13);
+typedef enum  {CB_TRUE = 0, 
+              CB_RIVER,
+              CB_FROZEN , CB_COLD , CB_TEMPERATE, CB_TROPICAL,
+               CB_OCEANIC,  CB_WET , CB_MEDIUM , CB_DRY ,
+               CB_FLAT, CB_HILLY, CB_ABRUPT} characteristic_bits;
+/* operators, only pointer to these var are used */
+extern characteristic_type CM_OR, CM_AND, CM_NOT, CM_NOT_PLACED;
+/* test for CM_TRUE mask is all the time TRUE, 
+ * test for CM_FALSE mask is FALSE! 
+ */
+extern characteristic_type CM_TRUE, CM_FALSE;
+extern characteristic_type CM_FLAT, CM_HILLY, CM_ABRUPT,
+                           CM_NFLAT;
+extern characteristic_type CM_FROZEN, CM_COLD, CM_TEMPERATE, CM_TROPICAL,
+                           CM_NFROZEN,  CM_ALL, CM_NHOT, CM_HOT;
+/*
+ CM_NFROZEN == (CM_COLD | CM_TEMPERATE | CM_TROPICAL)
+ CM_ALL     == (CM_FROZEN | CM_NFROZEN)
+ CM_NHOT    == (CM_FROZEN | CM_COLD)
+ CM_HOT     == (CM_TEMPERATE, CM_TROPICAL)
+ */
+                          
+extern characteristic_type CM_OCEANIC,  CM_WET, CM_MEDIUM, CM_DRY,
+                           CM_NWET, CM_NDRY;
+extern characteristic_type CM_RIVER;
+
+typedef struct {
+  /*
+    the **null_ended_array point to a bolean expresion in RPN
+    sample: CM_FROZEN && !CM_OCEANIC is writed has
+    data.null_ended_array = &{&CM_FROZEN, &CM_OCEANIC, &CM_NOT, &CM_AND, NULL};
+  */
+  characteristic_type **null_ended_array;
+} data_filter_chracteristic_type;
+bool filter_characteristic(const struct tile *ptile, const void *data);
+bool characteristic_condition(const struct tile *ptile,
+                             characteristic_type **null_ended_array);
+
+bool characteristics_are_initialized(void);
+void create_characteristics(bool has_height_map);
+void destroy_characteristics(void);  
+
+bool is_characteristic(const struct tile *ptile, characteristic_type mask );
+int count_characteristic_near(const struct tile *ptile, bool cardinal_only,
+                             bool percentage, characteristic_type mask);
+
+#endif  /* FC__CHARACTERISTICS_H */
diff -ruN -Xfreeciv/diff_ignore freeciv/server/generator/height_map.c 
freeciv_/server/generator/height_map.c
--- freeciv/server/generator/height_map.c       2004-10-17 10:03:53.000000000 
+0200
+++ freeciv_/server/generator/height_map.c      2004-10-25 18:11:34.000000000 
+0200
@@ -191,20 +191,20 @@
   /* set initial points */
   for (xn = 0; xn < xdiv2; xn++) {
     for (yn = 0; yn < ydiv2; yn++) {
-      do_in_map_pos(ptile, (xn * xmax / xdiv), (yn * ymax / ydiv)) {
-       /* set initial points */
-       hmap(ptile) = myrand(2 * step) - (2 * step) / 2;
+      struct tile *ptile = native_pos_to_tile(xn * xmax / xdiv,
+                                             yn * ymax / ydiv);
+      /* set initial points */
+      hmap(ptile) = myrand(2 * step) - (2 * step) / 2;
+      
+      if (near_singularity(ptile)) {
+       /* avoid edges (topological singularities) */
+       hmap(ptile) -= avoidedge;
+      }
 
-       if (near_singularity(ptile)) {
-         /* avoid edges (topological singularities) */
-         hmap(ptile) -= avoidedge;
-       }
-
-       if (map_colatitude(ptile) <= ICE_BASE_LEVEL / 2 ) {
-         /* separate poles and avoid too much land at poles */
-         hmap(ptile) -= myrand(avoidedge);
-       }
-      } do_in_map_pos_end;
+      if (map_colatitude(ptile) <= ICE_BASE_LEVEL / 2 ) {
+        /* separate poles and avoid too much land at poles */
+        hmap(ptile) -= myrand(avoidedge);
+      }
     }
   }
 
diff -ruN -Xfreeciv/diff_ignore freeciv/server/generator/Makefile.am 
freeciv_/server/generator/Makefile.am
--- freeciv/server/generator/Makefile.am        2004-09-16 11:53:11.000000000 
+0200
+++ freeciv_/server/generator/Makefile.am       2004-10-25 18:11:34.000000000 
+0200
@@ -14,5 +14,5 @@
        height_map.h \
        startpos.c \
        startpos.h \
-       temperature_map.c \
-       temperature_map.h
+       characteristics.h \
+       characteristics.c
diff -ruN -Xfreeciv/diff_ignore freeciv/server/generator/mapgen.c 
freeciv_/server/generator/mapgen.c
--- freeciv/server/generator/mapgen.c   2004-10-15 19:16:54.000000000 +0200
+++ freeciv_/server/generator/mapgen.c  2004-10-25 18:20:20.000000000 +0200
@@ -35,9 +35,8 @@
 #include "mapgen.h"
 #include "mapgen_topology.h"
 #include "startpos.h"
-#include "temperature_map.h"
 #include "utilities.h"
-
+#include "characteristics.h"
 
 /* Old-style terrain enumeration: deprecated. */
 enum {
@@ -55,17 +54,6 @@
 static void mapgenerator4(void);
 static void adjust_terrain_param(void);
 
-#define RIVERS_MAXTRIES 32767
-enum river_map_type {RS_BLOCKED = 0, RS_RIVER = 1};
-
-/* Array needed to mark tiles as blocked to prevent a river from
-   falling into itself, and for storing rivers temporarly.
-   A value of 1 means blocked.
-   A value of 2 means river.                            -Erik Sigra */
-static int *river_map;
-
-#define HAS_POLES (map.temperature < 70 && !map.alltemperate  )
-
 /* These are the old parameters of terrains types in %
    TODO: they depend on the hardcoded terrains */
 static int forest_pct = 0;
@@ -75,272 +63,36 @@
 static int jungle_pct = 0;
 static int river_pct = 0;
  
-/****************************************************************************
- * Conditions used mainly in rand_map_pos_characteristic()
- ****************************************************************************/
-/* WETNESS */
-
-/* necessary condition of deserts placement */
-#define map_pos_is_dry(ptile)                                          \
-  (map_colatitude((ptile)) <= DRY_MAX_LEVEL                            \
-   && map_colatitude((ptile)) > DRY_MIN_LEVEL                          \
-   && count_ocean_near_tile((ptile), FALSE, TRUE) <= 35)
-typedef enum { WC_ALL = 200, WC_DRY, WC_NDRY } wetness_c;
-
-/* MISCELANEOUS (OTHER CONDITIONS) */
-
-/* necessary condition of swamp placement */
-static int hmap_low_level = 0;
-#define ini_hmap_low_level() \
-{ \
-hmap_low_level = (4 * swamp_pct  * \
-     (hmap_max_level - hmap_shore_level)) / 100 + hmap_shore_level; \
-}
-/* should be used after having hmap_low_level initialized */
-#define map_pos_is_low(ptile) ((hmap((ptile)) < hmap_low_level))
-
-typedef enum { MC_NONE, MC_LOW, MC_NLOW } miscellaneous_c;
-
-/***************************************************************************
- These functions test for conditions used in rand_map_pos_characteristic 
-***************************************************************************/
-
-/***************************************************************************
-  Checks if the given location satisfy some wetness condition
-***************************************************************************/
-static bool test_wetness(const struct tile *ptile, wetness_c c)
-{
-  switch(c) {
-  case WC_ALL:
-    return TRUE;
-  case WC_DRY:
-    return map_pos_is_dry(ptile);
-  case WC_NDRY:
-    return !map_pos_is_dry(ptile);
-  }
-  assert(0);
-  return FALSE;
-}
-
-/***************************************************************************
-  Checks if the given location satisfy some miscellaneous condition
-***************************************************************************/
-static bool test_miscellaneous(const struct tile *ptile, miscellaneous_c c)
-{
-  switch(c) {
-  case MC_NONE:
-    return TRUE;
-  case MC_LOW:
-    return map_pos_is_low(ptile);
-  case MC_NLOW:
-    return !map_pos_is_low(ptile);
-  }
-  assert(0);
-  return FALSE;
-}
-
-/***************************************************************************
-  Passed as data to rand_map_pos_filtered() by rand_map_pos_characteristic()
-***************************************************************************/
-struct DataFilter {
-  wetness_c wc;
-  temperature_type tc;
-  miscellaneous_c mc;
-};
-
-/****************************************************************************
-  A filter function to be passed to rand_map_pos_filtered().  See
-  rand_map_pos_characteristic for more explanation.
-****************************************************************************/
-static bool condition_filter(const struct tile *ptile, const void *data)
-{
-  const struct DataFilter *filter = data;
-
-  return  not_placed(ptile) 
-       && tmap_is(ptile, filter->tc) 
-       && test_wetness(ptile, filter->wc) 
-       && test_miscellaneous(ptile, filter->mc) ;
-}
-
-/****************************************************************************
-  Return random map coordinates which have some conditions and which are
-  not yet placed on pmap.
-  Returns FALSE if there is no such position.
-****************************************************************************/
-static struct tile *rand_map_pos_characteristic(wetness_c wc,
-                                               temperature_type tc,
-                                               miscellaneous_c mc )
-{
-  struct DataFilter filter;
-
-  filter.wc = wc;
-  filter.tc = tc;
-  filter.mc = mc;
-  return rand_map_pos_filtered(&filter, condition_filter);
-}
-
-/**************************************************************************
-  we don't want huge areas of grass/plains, 
-  so we put in a hill here and there, where it gets too 'clean' 
-
-  Return TRUE if the terrain at the given map position is "clean".  This
-  means that all the terrain for 2 squares around it is not mountain or hill.
-****************************************************************************/
-static bool terrain_is_too_flat(struct tile *ptile, 
-                               int thill, int my_height)
-{
-  int higher_than_me = 0;
-  square_iterate(ptile, 2, tile1) {
-    if (hmap(tile1) > thill) {
-      return FALSE;
-    }
-    if (hmap(tile1) > my_height) {
-      if (map_distance(ptile, tile1) == 1) {
-       return FALSE;
-      }
-      if (++higher_than_me > 2) {
-       return FALSE;
-      }
-    }
-  } square_iterate_end;
-
-  if ((thill - hmap_shore_level) * higher_than_me  > 
-      (my_height - hmap_shore_level) * 4) {
-    return FALSE;
-  }
-  return TRUE;
-}
-
-/**************************************************************************
-  we don't want huge areas of hill/mountains, 
-  so we put in a plains here and there, where it gets too 'heigh' 
-
-  Return TRUE if the terrain at the given map position is too heigh.
-****************************************************************************/
-static bool terrain_is_too_high(struct tile *ptile,
-                               int thill, int my_height)
-{
-  square_iterate(ptile, 1, tile1) {
-    if (hmap(tile1) + (hmap_max_level - hmap_mountain_level) / 5 < thill) {
-      return FALSE;
-    }
-  } square_iterate_end;
-  return TRUE;
-}
-
-/**************************************************************************
-  make_relief() will convert all squares that are higher than thill to
-  mountains and hills. Note that thill will be adjusted according to
-  the map.steepness value, so increasing map.mountains will result in
-  more hills and mountains.
-**************************************************************************/
-static void make_relief(void)
-{
-  /* Calculate the mountain level.  map.mountains specifies the percentage
-   * of land that is turned into hills and mountains. */
-  hmap_mountain_level = ((hmap_max_level - hmap_shore_level)
-                        * (100 - map.steepness)) / 100 + hmap_shore_level;
-
-  whole_map_iterate(ptile) {
-    if (not_placed(ptile) &&
-       ((hmap_mountain_level < hmap(ptile) && 
-         (myrand(10) > 5 
-          || !terrain_is_too_high(ptile, hmap_mountain_level, hmap(ptile))))
-        || terrain_is_too_flat(ptile, hmap_mountain_level, hmap(ptile)))) {
-      /* Randomly place hills and mountains on "high" tiles.  But don't
-       * put hills near the poles (they're too green). */
-      if (myrand(100) > 70 || tmap_is(ptile, TT_NHOT)) {
-       map_set_terrain(ptile, T_MOUNTAINS);
-       map_set_placed(ptile);
-      } else {
-       map_set_terrain(ptile, T_HILLS);
-       map_set_placed(ptile);
-      }
-    }
-  } whole_map_iterate_end;
-}
-
-/****************************************************************************
-  Add arctic and tundra squares in the arctic zone (that is, the coolest
-  10% of the map).  We also texture the pole (adding arctic, tundra, and
-  mountains).  This is used in generators 2-4.
-****************************************************************************/
-static void make_polar(void)
-{
-  whole_map_iterate(ptile) {  
-    if (tmap_is(ptile, TT_FROZEN)
-       || (tmap_is(ptile, TT_COLD)
-           && (myrand(10) > 7)
-           && is_temperature_type_near(ptile, TT_FROZEN))) { 
-      map_set_terrain(ptile, T_ARCTIC);
-    }
-  } whole_map_iterate_end;
-}
-
-/*************************************************************************
- if separatepoles is set, return false if this tile has to keep ocean
-************************************************************************/
-static bool ok_for_separate_poles(struct tile *ptile)
-{
-  if (!map.separatepoles) {
-    return TRUE;
-  }
-  adjc_iterate(ptile, tile1) {
-    if (!is_ocean(map_get_terrain(tile1)) && 
-        map_get_continent(tile1) != 0) {
-      return FALSE;
-    }
-  } adjc_iterate_end;
-  return TRUE;
-}
-
-/****************************************************************************
-  Place untextured land at the poles.  This is used by generators 1 and 5.
-****************************************************************************/
-static void make_polar_land(void)
-{
-  assign_continent_numbers(FALSE);
-  whole_map_iterate(ptile) {
-    if ((tmap_is(ptile, TT_FROZEN ) &&
-       ok_for_separate_poles(ptile))
-       ||
-       (tmap_is(ptile, TT_COLD ) &&
-        (myrand(10) > 7) &&
-        is_temperature_type_near(ptile, TT_FROZEN) &&
-        ok_for_separate_poles(ptile))) {
-      map_set_terrain(ptile, T_UNKNOWN);
-      map_set_continent(ptile, 0);
-    } 
-  } whole_map_iterate_end;
-}
 
 /**************************************************************************
   Recursively generate terrains.
 **************************************************************************/
 static void place_terrain(struct tile *ptile, int diff, 
-                           Terrain_type_id ter, int *to_be_placed,
-                          wetness_c        wc,
-                          temperature_type tc,
-                          miscellaneous_c  mc)
+                         Terrain_type_id ter, int *to_be_placed,
+                         characteristic_type **null_ended_array)
 {
   if (*to_be_placed <= 0) {
     return;
   }
   assert(not_placed(ptile));
   map_set_terrain(ptile, ter);
+  if (is_characteristic(ptile, CM_RIVER)) {
+    map_set_special(ptile, S_RIVER);
+  }
   map_set_placed(ptile);
   (*to_be_placed)--;
   
-  cardinal_adjc_iterate(ptile, tile1) {
-    int Delta = abs(map_colatitude(tile1) - map_colatitude(ptile)) / L_UNIT
-       + abs(hmap(tile1) - (hmap(ptile))) /  H_UNIT;
-    if (not_placed(tile1) 
-       && tmap_is(tile1, tc) 
-       && test_wetness(tile1, wc)
-       && test_miscellaneous(tile1, mc)
+  cardinal_adjc_iterate(ptile, ptile1) {
+    int Delta = abs(map_colatitude(ptile1) - map_colatitude(ptile)) / L_UNIT
+       + abs(hmap(ptile1) - (hmap(ptile))) /  H_UNIT;
+    if (not_placed(ptile1)
+       && characteristic_condition(ptile1, null_ended_array)
+       && (is_characteristic(ptile1, CM_RIVER) 
+           ? terrain_has_flag(ter, TER_CAN_HAVE_RIVER) : TRUE)
        && Delta < diff 
        && myrand(10) > 4) {
-       place_terrain(tile1, diff - 1 - Delta, ter, to_be_placed, wc, tc, mc);
+       place_terrain(ptile1, diff - 1 - Delta, ter,
+                     to_be_placed, null_ended_array);
     }
   } cardinal_adjc_iterate_end;
 }
@@ -351,10 +103,13 @@
 **************************************************************************/
 static void make_plain(struct tile *ptile, int *to_be_placed )
 {
+  if (!not_placed(ptile)) {
+    return;
+  }
   /* in cold place we get tundra instead */
-  if (tmap_is(ptile, TT_FROZEN)) {
+  if (is_characteristic(ptile, CM_FROZEN)) {
     map_set_terrain(ptile, T_ARCTIC); 
-  } else if (tmap_is(ptile, TT_COLD)) {
+  } else if (is_characteristic(ptile, CM_COLD)) {
     map_set_terrain(ptile, T_TUNDRA); 
   } else {
     if (myrand(100) > 50) {
@@ -363,6 +118,9 @@
       map_set_terrain(ptile, T_PLAINS);
     }
   }
+  if (is_characteristic(ptile, CM_RIVER)) {
+    map_set_special(ptile, S_RIVER);
+  }
   map_set_placed(ptile);
   (*to_be_placed)--;
 }
@@ -384,12 +142,15 @@
 /**************************************************************************
  This place randomly a cluster of terrains with some characteristics
  **************************************************************************/
-#define PLACE_ONE_TYPE(count, alternate, ter, wc, tc, mc, weight) \
+#define PLACE_ONE_TYPE(count, alternate, ter, null_ended_array, weight) \
   if((count) > 0) {                                       \
     struct tile *ptile;                                          \
+    data.null_ended_array = null_ended_array;             \
     /* Place some terrains */                             \
-    if ((ptile = rand_map_pos_characteristic((wc), (tc), (mc)))) {     \
-      place_terrain(ptile, (weight), (ter), &(count), (wc),(tc), (mc));   \
+    if (NULL !=                                           \
+       (ptile = rand_map_pos_filtered(&data, filter_characteristic))) {\
+      place_terrain(ptile, (weight), (ter), &(count), \
+                   (data).null_ended_array);   \
     } else {                                                             \
       /* If rand_map_pos_temperature returns FALSE we may as well stop*/ \
       /* looking for this time and go to alternate type. */              \
@@ -411,9 +172,30 @@
   int forests_count = 0;
   int jungles_count = 0;
   int deserts_count = 0;
-  int alt_deserts_count = 0;
   int plains_count = 0;
   int swamps_count = 0;
+  data_filter_chracteristic_type data;
+
+  create_placed_map();
+  whole_map_iterate(ptile) {
+    if (is_characteristic(ptile, CM_OCEANIC)) {
+      map_set_placed(ptile);
+      map_set_terrain(ptile, T_OCEAN);
+    } else {
+      if (is_characteristic(ptile, CM_HILLY)) {
+       map_set_placed(ptile);
+       map_set_terrain(ptile, T_HILLS);
+      /* hack for terrains-set, where hills are too green */
+       if (is_characteristic(ptile, CM_FROZEN)) {
+         map_set_placed(ptile);
+         map_set_terrain(ptile, T_MOUNTAINS);
+       }
+      } else  if (is_characteristic(ptile, CM_ABRUPT)) {
+       map_set_placed(ptile);
+       map_set_terrain(ptile, T_MOUNTAINS);
+      } 
+    }
+  } whole_map_iterate_end;
 
   whole_map_iterate(ptile) {
     if (not_placed(ptile)) {
@@ -433,24 +215,50 @@
 
   /* the placement loop */
   do {
-    
-    PLACE_ONE_TYPE(forests_count , plains_count, T_FOREST,
-                  WC_ALL, TT_NFROZEN, MC_NONE, 60);
-    PLACE_ONE_TYPE(jungles_count, forests_count , T_JUNGLE,
-                  WC_ALL, TT_TROPICAL, MC_NONE, 50);
-    PLACE_ONE_TYPE(swamps_count, forests_count , T_SWAMP,
-                  WC_NDRY, TT_HOT, MC_LOW, 50);
-    PLACE_ONE_TYPE(deserts_count, alt_deserts_count , T_DESERT,
-                  WC_DRY, TT_NFROZEN, MC_NLOW, 80);
-    PLACE_ONE_TYPE(alt_deserts_count, plains_count , T_DESERT,
-                  WC_ALL, TT_NFROZEN, MC_NLOW, 40);
- 
+    {
+      characteristic_type *null_ended_array[] = 
+         {&CM_NOT_PLACED, &CM_NDRY, &CM_AND,
+          &CM_NFROZEN, &CM_FLAT, &CM_AND,
+          &CM_AND, NULL};
+      PLACE_ONE_TYPE(forests_count , plains_count, T_FOREST,
+                    null_ended_array, 60);
+    }
+    {  
+      characteristic_type *null_ended_array[] = 
+         {&CM_NOT_PLACED, &CM_NDRY, &CM_AND,
+          &CM_TROPICAL, &CM_FLAT, &CM_AND,
+          &CM_AND, NULL};
+      PLACE_ONE_TYPE(jungles_count, forests_count , T_JUNGLE,
+                    null_ended_array, 50);
+   
+    }
+    {  
+      characteristic_type *null_ended_array[] =
+         {&CM_NOT_PLACED, &CM_WET, &CM_AND,
+          &CM_HOT, &CM_FLAT, &CM_AND,
+          &CM_AND, NULL}; 
+      PLACE_ONE_TYPE(swamps_count, jungles_count , T_SWAMP,
+                    null_ended_array, 30);
+
+    }
+    {  
+      characteristic_type *null_ended_array[] = 
+         {&CM_NOT_PLACED, &CM_DRY, &CM_AND,
+          &CM_HOT, &CM_FLAT, &CM_AND,
+          &CM_AND, NULL};
+      PLACE_ONE_TYPE(deserts_count, plains_count , T_DESERT,
+                    null_ended_array, 80);
+    }
   /* make the plains and tundras */
     if (plains_count > 0) {
       struct tile *ptile;
-
-      /* Don't use any restriction here ! */
-      if ((ptile = rand_map_pos_characteristic(WC_ALL, TT_ALL, MC_NONE))) {
+      /* Don't use any restriction here! */
+      data_filter_chracteristic_type data;
+      characteristic_type *condition[] = {&CM_NOT_PLACED, NULL};
+
+      data.null_ended_array = condition;
+      if (NULL != (ptile = rand_map_pos_filtered((void *)&data, 
+                                                filter_characteristic))) {
        make_plain(ptile, &plains_count);
       } else {
        /* If rand_map_pos_temperature returns FALSE we may as well stop
@@ -459,491 +267,10 @@
       }
     }
   } while (forests_count > 0 || jungles_count > 0 
-          || deserts_count > 0 || alt_deserts_count > 0 
+          || deserts_count > 0
           || plains_count > 0 || swamps_count > 0 );
-}
-
-/*********************************************************************
- Help function used in make_river(). See the help there.
-*********************************************************************/
-static int river_test_blocked(struct tile *ptile)
-{
-  if (TEST_BIT(rmap(ptile), RS_BLOCKED))
-    return 1;
-
-  /* any un-blocked? */
-  cardinal_adjc_iterate(ptile, tile1) {
-    if (!TEST_BIT(rmap(tile1), RS_BLOCKED))
-      return 0;
-  } cardinal_adjc_iterate_end;
-
-  return 1; /* none non-blocked |- all blocked */
-}
-
-/*********************************************************************
- Help function used in make_river(). See the help there.
-*********************************************************************/
-static int river_test_rivergrid(struct tile *ptile)
-{
-  return (count_special_near_tile(ptile, TRUE, FALSE, S_RIVER) > 1) ? 1 : 0;
-}
-
-/*********************************************************************
- Help function used in make_river(). See the help there.
-*********************************************************************/
-static int river_test_highlands(struct tile *ptile)
-{
-  return (((map_get_terrain(ptile) == T_HILLS) ? 1 : 0) +
-         ((map_get_terrain(ptile) == T_MOUNTAINS) ? 2 : 0));
-}
-
-/*********************************************************************
- Help function used in make_river(). See the help there.
-*********************************************************************/
-static int river_test_adjacent_ocean(struct tile *ptile)
-{
-  return 100 - count_ocean_near_tile(ptile, TRUE, TRUE);
-}
-
-/*********************************************************************
- Help function used in make_river(). See the help there.
-*********************************************************************/
-static int river_test_adjacent_river(struct tile *ptile)
-{
-  return 100 - count_special_near_tile(ptile, TRUE, TRUE, S_RIVER);
-}
 
-/*********************************************************************
- Help function used in make_river(). See the help there.
-*********************************************************************/
-static int river_test_adjacent_highlands(struct tile *ptile)
-{
-  return (count_terrain_near_tile(ptile, TRUE, TRUE, T_HILLS)
-         + 2 * count_terrain_near_tile(ptile, TRUE, TRUE, T_MOUNTAINS));
-}
-
-/*********************************************************************
- Help function used in make_river(). See the help there.
-*********************************************************************/
-static int river_test_swamp(struct tile *ptile)
-{
-  return (map_get_terrain(ptile) != T_SWAMP) ? 1 : 0;
-}
-
-/*********************************************************************
- Help function used in make_river(). See the help there.
-*********************************************************************/
-static int river_test_adjacent_swamp(struct tile *ptile)
-{
-  return 100 - count_terrain_near_tile(ptile, TRUE, TRUE, T_SWAMP);
-}
-
-/*********************************************************************
- Help function used in make_river(). See the help there.
-*********************************************************************/
-static int river_test_height_map(struct tile *ptile)
-{
-  return hmap(ptile);
-}
-
-/*********************************************************************
- Called from make_river. Marks all directions as blocked.  -Erik Sigra
-*********************************************************************/
-static void river_blockmark(struct tile *ptile)
-{
-  freelog(LOG_DEBUG, "Blockmarking (%d, %d) and adjacent tiles.",
-         ptile->x, ptile->y);
-
-  rmap(ptile) |= (1u << RS_BLOCKED);
-
-  cardinal_adjc_iterate(ptile, tile1) {
-    rmap(tile1) |= (1u << RS_BLOCKED);
-  } cardinal_adjc_iterate_end;
-}
-
-struct test_func {
-  int (*func)(struct tile *ptile);
-  bool fatal;
-};
-
-#define NUM_TEST_FUNCTIONS 9
-static struct test_func test_funcs[NUM_TEST_FUNCTIONS] = {
-  {river_test_blocked,            TRUE},
-  {river_test_rivergrid,          TRUE},
-  {river_test_highlands,          FALSE},
-  {river_test_adjacent_ocean,     FALSE},
-  {river_test_adjacent_river,     FALSE},
-  {river_test_adjacent_highlands, FALSE},
-  {river_test_swamp,              FALSE},
-  {river_test_adjacent_swamp,     FALSE},
-  {river_test_height_map,         FALSE}
-};
-
-/********************************************************************
- Makes a river starting at (x, y). Returns 1 if it succeeds.
- Return 0 if it fails. The river is stored in river_map.
- 
- How to make a river path look natural
- =====================================
- Rivers always flow down. Thus rivers are best implemented on maps
- where every tile has an explicit height value. However, Freeciv has a
- flat map. But there are certain things that help the user imagine
- differences in height between tiles. The selection of direction for
- rivers should confirm and even amplify the user's image of the map's
- topology.
- 
- To decide which direction the river takes, the possible directions
- are tested in a series of test until there is only 1 direction
- left. Some tests are fatal. This means that they can sort away all
- remaining directions. If they do so, the river is aborted. Here
- follows a description of the test series.
- 
- * Falling into itself: fatal
-     (river_test_blocked)
-     This is tested by looking up in the river_map array if a tile or
-     every tile surrounding the tile is marked as blocked. A tile is
-     marked as blocked if it belongs to the current river or has been
-     evaluated in a previous iteration in the creation of the current
-     river.
-     
-     Possible values:
-     0: Is not falling into itself.
-     1: Is falling into itself.
-     
- * Forming a 4-river-grid: optionally fatal
-     (river_test_rivergrid)
-     A minimal 4-river-grid is formed when an intersection in the map
-     grid is surrounded by 4 river tiles. There can be larger river
-     grids consisting of several overlapping minimal 4-river-grids.
-     
-     Possible values:
-     0: Is not forming a 4-river-grid.
-     1: Is forming a 4-river-grid.
-
- * Highlands:
-     (river_test_highlands)
-     Rivers must not flow up in mountains or hills if there are
-     alternatives.
-     
-     Possible values:
-     0: Is not hills and not mountains.
-     1: Is hills.
-     2: Is mountains.
-
- * Adjacent ocean:
-     (river_test_adjacent_ocean)
-     Rivers must flow down to coastal areas when possible:
-
-     Possible values: 0-100
-
- * Adjacent river:
-     (river_test_adjacent_river)
-     Rivers must flow down to areas near other rivers when possible:
-
-     Possible values: 0-100
-                                       
- * Adjacent highlands:
-     (river_test_adjacent_highlands)
-     Rivers must not flow towards highlands if there are alternatives. 
-     
- * Swamps:
-     (river_test_swamp)
-     Rivers must flow down in swamps when possible.
-     
-     Possible values:
-     0: Is swamps.
-     1: Is not swamps.
-     
- * Adjacent swamps:
-     (river_test_adjacent_swamp)
-     Rivers must flow towards swamps when possible.
-
- * height_map:
-     (river_test_height_map)
-     Rivers must flow in the direction which takes it to the tile with
-     the lowest value on the height_map.
-     
-     Possible values:
-     n: height_map[...]
-     
- If these rules haven't decided the direction, the random number
- generator gets the desicion.                              -Erik Sigra
-*********************************************************************/
-static bool make_river(struct tile *ptile)
-{
-  /* Comparison value for each tile surrounding the current tile.  It is
-   * the suitability to continue a river to the tile in that direction;
-   * lower is better.  However rivers may only run in cardinal directions;
-   * the other directions are ignored entirely. */
-  int rd_comparison_val[8];
-
-  bool rd_direction_is_valid[8];
-  int num_valid_directions, func_num, direction;
-
-  while (TRUE) {
-    /* Mark the current tile as river. */
-    rmap(ptile) |= (1u << RS_RIVER);
-    freelog(LOG_DEBUG,
-           "The tile at (%d, %d) has been marked as river in river_map.\n",
-           ptile->x, ptile->y);
-
-    /* Test if the river is done. */
-    /* We arbitrarily make rivers end at the poles. */
-    if (count_special_near_tile(ptile, TRUE, TRUE, S_RIVER) > 0
-       || count_ocean_near_tile(ptile, TRUE, TRUE) > 0
-        || (map_get_terrain(ptile) == T_ARCTIC 
-           && map_colatitude(ptile) < 0.8 * COLD_LEVEL)) { 
-
-      freelog(LOG_DEBUG,
-             "The river ended at (%d, %d).\n", ptile->x, ptile->y);
-      return TRUE;
-    }
-
-    /* Else choose a direction to continue the river. */
-    freelog(LOG_DEBUG,
-           "The river did not end at (%d, %d). Evaluating directions...\n",
-           ptile->x, ptile->y);
-
-    /* Mark all available cardinal directions as available. */
-    memset(rd_direction_is_valid, 0, sizeof(rd_direction_is_valid));
-    cardinal_adjc_dir_iterate(ptile, tile1, dir) {
-      rd_direction_is_valid[dir] = TRUE;
-    } cardinal_adjc_dir_iterate_end;
-
-    /* Test series that selects a direction for the river. */
-    for (func_num = 0; func_num < NUM_TEST_FUNCTIONS; func_num++) {
-      int best_val = -1;
-
-      /* first get the tile values for the function */
-      cardinal_adjc_dir_iterate(ptile, tile1, dir) {
-       if (rd_direction_is_valid[dir]) {
-         rd_comparison_val[dir] = (test_funcs[func_num].func) (tile1);
-         if (best_val == -1) {
-           best_val = rd_comparison_val[dir];
-         } else {
-           best_val = MIN(rd_comparison_val[dir], best_val);
-         }
-       }
-      } cardinal_adjc_dir_iterate_end;
-      assert(best_val != -1);
-
-      /* should we abort? */
-      if (best_val > 0 && test_funcs[func_num].fatal) {
-       return FALSE;
-      }
-
-      /* mark the less attractive directions as invalid */
-      cardinal_adjc_dir_iterate(ptile, tile1, dir) {
-       if (rd_direction_is_valid[dir]) {
-         if (rd_comparison_val[dir] != best_val) {
-           rd_direction_is_valid[dir] = FALSE;
-         }
-       }
-      } cardinal_adjc_dir_iterate_end;
-    }
-
-    /* Directions evaluated with all functions. Now choose the best
-       direction before going to the next iteration of the while loop */
-    num_valid_directions = 0;
-    cardinal_adjc_dir_iterate(ptile, tile1, dir) {
-      if (rd_direction_is_valid[dir]) {
-       num_valid_directions++;
-      }
-    } cardinal_adjc_dir_iterate_end;
-
-    if (num_valid_directions == 0) {
-      return FALSE; /* river aborted */
-    }
-
-    /* One or more valid directions: choose randomly. */
-    freelog(LOG_DEBUG, "mapgen.c: Had to let the random number"
-           " generator select a direction for a river.");
-    direction = myrand(num_valid_directions);
-    freelog(LOG_DEBUG, "mapgen.c: direction: %d", direction);
-
-    /* Find the direction that the random number generator selected. */
-    cardinal_adjc_dir_iterate(ptile, tile1, dir) {
-      if (rd_direction_is_valid[dir]) {
-       if (direction > 0) {
-         direction--;
-       } else {
-         river_blockmark(ptile);
-         ptile = tile1;
-         break;
-       }
-      }
-    } cardinal_adjc_dir_iterate_end;
-    assert(direction == 0);
-
-  } /* end while; (Make a river.) */
-}
-
-/**************************************************************************
-  Calls make_river until there are enough river tiles on the map. It stops
-  when it has tried to create RIVERS_MAXTRIES rivers.           -Erik Sigra
-**************************************************************************/
-static void make_rivers(void)
-{
-  struct tile *ptile;
-
-  /* Formula to make the river density similar om different sized maps. Avoids
-     too few rivers on large maps and too many rivers on small maps. */
-  int desirable_riverlength =
-    river_pct *
-      /* The size of the map (poles counted in river_pct). */
-      map_num_tiles() *
-      /* Rivers need to be on land only. */
-      map.landpercent /
-      /* Adjustment value. Tested by me. Gives no rivers with 'set
-        rivers 0', gives a reasonable amount of rivers with default
-        settings and as many rivers as possible with 'set rivers 100'. */
-      5325;
-
-  /* The number of river tiles that have been set. */
-  int current_riverlength = 0;
-
-  int i; /* Loop variable. */
-
-  /* Counts the number of iterations (should increase with 1 during
-     every iteration of the main loop in this function).
-     Is needed to stop a potentially infinite loop. */
-  int iteration_counter = 0;
-
-  create_placed_map(); /* needed bu rand_map_characteristic */
-  set_all_ocean_tiles_placed();
-
-  river_map = fc_malloc(sizeof(int) * MAX_MAP_INDEX);
-
-  /* The main loop in this function. */
-  while (current_riverlength < desirable_riverlength
-        && iteration_counter < RIVERS_MAXTRIES) {
-
-    if (!(ptile = rand_map_pos_characteristic(WC_ALL, TT_NFROZEN,
-                                             MC_NLOW))) {
-       break; /* mo more spring places */
-    }
-
-    /* Check if it is suitable to start a river on the current tile.
-     */
-    if (
-       /* Don't start a river on ocean. */
-       !is_ocean(map_get_terrain(ptile))
-
-       /* Don't start a river on river. */
-       && !map_has_special(ptile, S_RIVER)
-
-       /* Don't start a river on a tile is surrounded by > 1 river +
-          ocean tile. */
-       && (count_special_near_tile(ptile, TRUE, FALSE, S_RIVER)
-           + count_ocean_near_tile(ptile, TRUE, FALSE) <= 1)
-
-       /* Don't start a river on a tile that is surrounded by hills or
-          mountains unless it is hard to find somewhere else to start
-          it. */
-       && (count_terrain_near_tile(ptile, TRUE, TRUE, T_HILLS)
-           + count_terrain_near_tile(ptile, TRUE, TRUE, T_MOUNTAINS) < 90
-           || iteration_counter == RIVERS_MAXTRIES / 10 * 5)
-
-       /* Don't start a river on hills unless it is hard to find
-          somewhere else to start it. */
-       && (map_get_terrain(ptile) != T_HILLS
-           || iteration_counter == RIVERS_MAXTRIES / 10 * 6)
-
-       /* Don't start a river on mountains unless it is hard to find
-          somewhere else to start it. */
-       && (map_get_terrain(ptile) != T_MOUNTAINS
-           || iteration_counter == RIVERS_MAXTRIES / 10 * 7)
-
-       /* Don't start a river on arctic unless it is hard to find
-          somewhere else to start it. */
-       && (map_get_terrain(ptile) != T_ARCTIC
-           || iteration_counter == RIVERS_MAXTRIES / 10 * 8)
-
-       /* Don't start a river on desert unless it is hard to find
-          somewhere else to start it. */
-       && (map_get_terrain(ptile) != T_DESERT
-           || iteration_counter == RIVERS_MAXTRIES / 10 * 9)) {
-
-      /* Reset river_map before making a new river. */
-      for (i = 0; i < map.xsize * map.ysize; i++) {
-       river_map[i] = 0;
-      }
-
-      freelog(LOG_DEBUG,
-             "Found a suitable starting tile for a river at (%d, %d)."
-             " Starting to make it.",
-             ptile->x, ptile->y);
-
-      /* Try to make a river. If it is OK, apply it to the map. */
-      if (make_river(ptile)) {
-       whole_map_iterate(tile1) {
-         if (TEST_BIT(rmap(tile1), RS_RIVER)) {
-           Terrain_type_id t = map_get_terrain(tile1);
-
-           if (!terrain_has_flag(t, TER_CAN_HAVE_RIVER)) {
-             /* We have to change the terrain to put a river here. */
-             t = get_flag_terrain(TER_CAN_HAVE_RIVER);
-             map_set_terrain(tile1, t);
-           }
-           map_set_special(tile1, S_RIVER);
-           current_riverlength++;
-           map_set_placed(tile1);
-           freelog(LOG_DEBUG, "Applied a river to (%d, %d).",
-                   tile1->x, tile1->y);
-         }
-       } whole_map_iterate_end;
-      }
-      else {
-       freelog(LOG_DEBUG,
-               "mapgen.c: A river failed. It might have gotten stuck in a 
helix.");
-      }
-    } /* end if; */
-    iteration_counter++;
-    freelog(LOG_DEBUG,
-           "current_riverlength: %d; desirable_riverlength: %d; 
iteration_counter: %d",
-           current_riverlength, desirable_riverlength, iteration_counter);
-  } /* end while; */
-  free(river_map);
-  destroy_placed_map();
-  river_map = NULL;
-}
-
-/**************************************************************************
-  make land simply does it all based on a generated heightmap
-  1) with map.landpercent it generates a ocean/grassland map 
-  2) it then calls the above functions to generate the different terrains
-**************************************************************************/
-static void make_land(void)
-{
-  
-  if (HAS_POLES) {
-    normalize_hmap_poles();
-  }
-  hmap_shore_level = (hmap_max_level * (100 - map.landpercent)) / 100;
-  ini_hmap_low_level();
-  whole_map_iterate(ptile) {
-    map_set_terrain(ptile, T_UNKNOWN); /* set as oceans count is used */
-    if (hmap(ptile) < hmap_shore_level) {
-      map_set_terrain(ptile, T_OCEAN);
-    }
-  } whole_map_iterate_end;
-  if (HAS_POLES) {
-    renormalize_hmap_poles();
-  } 
-
-  create_tmap(TRUE); /* base temperature map, need hmap and oceans */
-  
-  if (HAS_POLES) { /* this is a hack to terrains set with not frizzed oceans*/
-    make_polar_land(); /* make extra land at poles*/
-  }
-
-  create_placed_map(); /* here it means land terrains to be placed */
-  set_all_ocean_tiles_placed();
-  make_relief(); /* base relief on map */
-  make_terrains(); /* place all exept mountains and hill */
   destroy_placed_map();
-
-  make_rivers(); /* use a new placed_map. destroy older before call */
 }
 
 /**************************************************************************
@@ -983,6 +310,32 @@
 }
 
 /**************************************************************************
+ Convert parameters from the server into terrains percents parameters for
+ the generators, this is primary used has a hack for gen 2-4
+**************************************************************************/
+static void adjust_terrain_param(void)
+{
+  int polar = 2 * ICE_BASE_LEVEL * map.landpercent / MAX_COLATITUDE ;
+  float factor = (100.0 - polar - map.steepness * 0.8 ) / 10000;
+
+
+  mountain_pct = factor * map.steepness * 90;
+
+  /* 40 % if wetness == 50 & */
+  forest_pct = factor * (map.wetness * 60 + 1000) ; 
+  jungle_pct = forest_pct * (MAX_COLATITUDE - TROPICAL_LEVEL) /
+               (MAX_COLATITUDE * 2);
+  forest_pct -= jungle_pct;
+
+  /* 3 - 11 % */
+  river_pct = (100 - polar) * (3 + map.wetness / 12) / 100;
+
+  /* 6 %  if wetness == 50 && temperature == 50 */
+  swamp_pct = factor * (map.wetness * 6 + map.temperature * 6);
+  desert_pct = factor * (map.temperature * 10 + (100 - map.wetness) * 10) ;
+}
+
+/**************************************************************************
   See stdinhand.c for information on map generation methods.
 
 FIXME: Some continent numbers are unused at the end of this function, fx
@@ -995,7 +348,7 @@
   based on the map.size server parameter and the specified topology.  If
   not map.xsize and map.ysize will be used.
 **************************************************************************/
-void map_fractal_generate(bool autosize)
+void map_generate(bool autosize)
 {
   /* save the current random state: */
   RANDOM_STATE rstate = get_myrand_state();
@@ -1043,22 +396,38 @@
       make_random_hmap(MAX(1, 1 + SQSIZE 
                           - (map.startpos ? game.nplayers / 4 : 0)));
     }
+    /* 
+     *   if height_map only generator make anything else 
+     */
+    if ((map.generator == 1) || (map.generator == 2)) {
 
-    /* if hmap only generator make anything else */
-    if (map.generator == 1 || map.generator == 2) {
-      make_land();
+    /************************************************************
+     * 2d step, Initialize generalized terrains characteristics *
+     ************************************************************/
+      create_characteristics(TRUE);
+
+     /****************************
+      * 3th step, place terrians *
+      ****************************/
+      make_terrains();         /* and rivers */
       free(height_map);
       height_map = NULL;
     }
+    /* best detroy there, the old remove_tiny_islands can't update */
+    destroy_characteristics(); 
     if (!map.tinyisles) {
       remove_tiny_islands();
     }
   }
-
-  if (!temperature_is_initialized()) {
-    create_tmap(FALSE);
-  }
-  
+  /*
+   * 4 Place specials and huts
+   */
+ 
+  /* initialize needed characteristics if not yet done, */
+  if (!characteristics_are_initialized()) {
+      create_characteristics(FALSE); 
+  } 
+ 
   /* some scenarios already provide specials */
   if (!map.have_specials) {
     add_specials(map.riches);
@@ -1068,9 +437,9 @@
     make_huts(map.huts); 
   }
 
+  destroy_characteristics();
   /* restore previous random state: */
   set_myrand_state(rstate);
-  destroy_tmap();
 
   /* We don't want random start positions in a scenario which already
    * provides them. */
@@ -1100,32 +469,6 @@
   assign_continent_numbers(FALSE);
 }
 
-/**************************************************************************
- Convert parameters from the server into terrains percents parameters for
- the generators
-**************************************************************************/
-static void adjust_terrain_param(void)
-{
-  int polar = 2 * ICE_BASE_LEVEL * map.landpercent / MAX_COLATITUDE ;
-  float factor = (100.0 - polar - map.steepness * 0.8 ) / 10000;
-
-
-  mountain_pct = factor * map.steepness * 90;
-
-  /* 40 % if wetness == 50 & */
-  forest_pct = factor * (map.wetness * 60 + 1000) ; 
-  jungle_pct = forest_pct * (MAX_COLATITUDE - TROPICAL_LEVEL) /
-               (MAX_COLATITUDE * 2);
-  forest_pct -= jungle_pct;
-
-  /* 3 - 11 % */
-  river_pct = (100 - polar) * (3 + map.wetness / 12) / 100;
-
-  /* 6 %  if wetness == 50 && temperature == 50 */
-  swamp_pct = factor * (map.wetness * 6 + map.temperature * 6);
-  desert_pct = factor * (map.temperature * 10 + (100 - map.wetness) * 10) ;
-}
-
 /****************************************************************************
   Return TRUE if a safe tile is in a radius of 1.  This function is used to
   test where to place specials on the sea.
@@ -1153,17 +496,21 @@
   create_placed_map(); /* here it means placed huts */
 
   while (number * map_num_tiles() >= 2000 && count++ < map_num_tiles() * 2) {
-
+    data_filter_chracteristic_type data;
+    characteristic_type *condition[] =
+       {&CM_NOT_PLACED, &CM_NFROZEN, &CM_AND,
+        &CM_OCEANIC, &CM_NOT, &CM_AND, NULL};
+    
+    data.null_ended_array = condition;
     /* Add a hut.  But not on a polar area, on an ocean, or too close to
      * another hut. */
-    if ((ptile = rand_map_pos_characteristic(WC_ALL, TT_NFROZEN, MC_NONE))) {
-      if (is_ocean(map_get_terrain(ptile))) {
-       map_set_placed(ptile); /* not good for a hut */
-      } else {
-       number--;
-       map_set_special(ptile, S_HUT);
-       set_placed_near_pos(ptile, 3);
-      }
+    if (NULL ==        (ptile = rand_map_pos_filtered((void *)&data, 
+                                              filter_characteristic))) {
+      map_set_placed(ptile); /* not good for a hut */
+    } else {
+      number--;
+      map_set_special(ptile, S_HUT);
+      set_placed_near_pos(ptile, 3);
     }
   }
   destroy_placed_map();
@@ -1219,6 +566,20 @@
   map.have_specials = TRUE;
 }
 
+/****************************************************************************
+  Add arctic and tundra squares in the arctic zone (that is, the coolest
+  10% of the map).  We also texture the pole (adding arctic, tundra, and
+  mountains).  This is used in generators 2-4.
+****************************************************************************/
+static void make_polar(void)
+{
+  whole_map_iterate(ptile) {  
+  if (is_characteristic(ptile, CM_FROZEN )) { 
+      map_set_terrain(ptile, T_ARCTIC);
+    }
+  } whole_map_iterate_end;
+}
+
 /**************************************************************************
   common variables for generator 2, 3 and 4
 **************************************************************************/
@@ -1651,7 +1012,7 @@
 {
   height_map = fc_malloc(sizeof(int) * map.ysize * map.xsize);
   create_placed_map(); /* land tiles which aren't placed yet */
-  create_tmap(FALSE);
+  create_characteristics(FALSE);
   
   whole_map_iterate(ptile) {
     map_set_terrain(ptile, T_OCEAN);
@@ -1711,7 +1072,7 @@
 
     if (placed_map_is_initialized()) {
       destroy_placed_map();
-      destroy_tmap();
+      destroy_characteristics();
     }
 
     initworld(pstate);
diff -ruN -Xfreeciv/diff_ignore freeciv/server/generator/mapgen.h 
freeciv_/server/generator/mapgen.h
--- freeciv/server/generator/mapgen.h   2004-09-16 11:53:11.000000000 +0200
+++ freeciv_/server/generator/mapgen.h  2004-10-25 18:11:34.000000000 +0200
@@ -13,6 +13,6 @@
 #ifndef FC__MAPGEN_H
 #define FC__MAPGEN_H
 
-void map_fractal_generate(bool autosize);
+void map_generate(bool autosize);
 
 #endif  /* FC__MAPGEN_H */
diff -ruN -Xfreeciv/diff_ignore freeciv/server/generator/mapgen_topology.c 
freeciv_/server/generator/mapgen_topology.c
--- freeciv/server/generator/mapgen_topology.c  2004-10-07 22:34:57.000000000 
+0200
+++ freeciv_/server/generator/mapgen_topology.c 2004-10-25 18:11:34.000000000 
+0200
@@ -277,15 +277,11 @@
       ice_base_colatitude =
          (MAX(0, 100 * COLD_LEVEL / 3 - 1 *  MAX_COLATITUDE) 
           + 1 *  MAX_COLATITUDE * SQSIZE) / (100 * SQSIZE);
-      /* correction for single pole 
-       * TODO uncomment it when generator 5 was well tuned 
-       *      sometime it can put too many land near pole 
-
+     
       if (topo_has_flag(TF_WRAPX) == topo_has_flag(TF_WRAPY)) {
        ice_base_colatitude /= 2;
       }
 
-      */
     } else {
       /* any way strip poles are not so playable has isle poles */
       ice_base_colatitude =
diff -ruN -Xfreeciv/diff_ignore freeciv/server/generator/mapgen_topology.h 
freeciv_/server/generator/mapgen_topology.h
--- freeciv/server/generator/mapgen_topology.h  2004-09-29 07:50:51.000000000 
+0200
+++ freeciv_/server/generator/mapgen_topology.h 2004-10-25 18:11:34.000000000 
+0200
@@ -45,6 +45,8 @@
 extern int ice_base_colatitude;
 #define ICE_BASE_LEVEL ice_base_colatitude
 
+#define HAS_POLES (map.temperature < 70 && !map.alltemperate)
+
 int map_colatitude(const struct tile *ptile);
 bool near_singularity(const struct tile *ptile);
 void generator_init_topology(bool autosize);
diff -ruN -Xfreeciv/diff_ignore freeciv/server/generator/temperature_map.c 
freeciv_/server/generator/temperature_map.c
--- freeciv/server/generator/temperature_map.c  2004-10-16 00:56:47.000000000 
+0200
+++ freeciv_/server/generator/temperature_map.c 1970-01-01 01:00:00.000000000 
+0100
@@ -1,123 +0,0 @@
-/********************************************************************** 
-   Copyright (C) 2004 - Marcelo J. Burda
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "map.h"
-
-#include "height_map.h"
-#include "temperature_map.h"
-#include "mapgen_topology.h"
-#include "utilities.h" 
-
-static int *temperature_map;
-
-#define tmap(ptile) (temperature_map[(ptile)->index])
-
-/**************************************************************
-  Return TRUE if temperateure_map is initialized
-**************************************************************/
-bool temperature_is_initialized(void)
-{
-  return temperature_map != NULL;
-}
-/*********************************************************
- return true if the tile has tt temperature type
-**********************************************************/
-bool tmap_is(const struct tile *ptile, temperature_type tt)
-{
-  return BOOL_VAL(tmap(ptile) & (tt));
-}
-
-/*****************************************************************
- return true if at last one tile has tt temperature type
-****************************************************************/
-bool is_temperature_type_near(const struct tile *ptile, temperature_type tt) 
-{
-  adjc_iterate(ptile, tile1) {
-    if (BOOL_VAL(tmap(tile1) & (tt))) {
-      return TRUE;
-    };
-  } adjc_iterate_end;
-  return FALSE;
-}
-
-/**************************************************************************** 
-   Free the tmap
- ****************************************************************************/
-void destroy_tmap(void)
-{
-  assert(temperature_map != NULL);
-  free(temperature_map);
-  temperature_map = NULL;
-}
-
-/***************************************************************************
- * create_tmap initialize the temperature_map
- * if arg is FALSE, create a dumy tmap == map_colattitude
- * to be used if hmap or oceans are not placed gen 2-4
- ***************************************************************************/
-void create_tmap(bool real)
-{
-  int i;
-
-  /* if map is defined this is not changed */
-  /* TO DO load if from scenario game with tmap */
-  assert(temperature_map == NULL); /* to debug, never load a this time */
-  if (temperature_map != NULL) {
-    return;
-  }
-
-  temperature_map = fc_malloc(sizeof(int) * MAX_MAP_INDEX);
-  whole_map_iterate(ptile) {
-  
-     /* the base temperature is equal to base map_colatitude */
-    int t = map_colatitude(ptile);
-    if (!real) {
-      tmap(ptile) = t;
-    } else {
-      /* height land can be 30% collest */
-      float height = - 0.3 * MAX(0, hmap(ptile) - hmap_shore_level) 
-         / (hmap_max_level - hmap_shore_level); 
-      /* near ocean temperature can be 15 % more "temperate" */
-      float temperate = 0.15 * (map.temperature / 100 - t / MAX_COLATITUDE) * 
-         2 * MIN (50 ,count_ocean_near_tile(ptile, FALSE, TRUE)) /
-         100;
-      
-      tmap(ptile) =  t * (1.0 + temperate) * (1.0 + height);
-    }
-  } whole_map_iterate_end;
-  /* adjust to get well sizes frequencies */
-  /* Notice: if colatitude is load from a scenario never call adjust has
-             scenario maybe has a odd colatitude ditribution and adjust will
-            brack it */
-  if (!map.alltemperate) {
-    adjust_int_map(temperature_map, MAX_COLATITUDE);
-  }
-  /* now simplify to 4 base values */ 
-  for (i = 0; i < MAX_MAP_INDEX; i++) {
-    int t = temperature_map[i];
-
-    if (t >= TROPICAL_LEVEL) {
-      temperature_map[i] = TT_TROPICAL;
-    } else if (t >= COLD_LEVEL) {
-      temperature_map[i] = TT_TEMPERATE;
-    } else if (t >= 2 * ICE_BASE_LEVEL) {
-      temperature_map[i] = TT_COLD;
-    } else {
-      temperature_map[i] = TT_FROZEN;
-    }
-  } 
-}
diff -ruN -Xfreeciv/diff_ignore freeciv/server/generator/temperature_map.h 
freeciv_/server/generator/temperature_map.h
--- freeciv/server/generator/temperature_map.h  2004-09-29 07:50:51.000000000 
+0200
+++ freeciv_/server/generator/temperature_map.h 1970-01-01 01:00:00.000000000 
+0100
@@ -1,40 +0,0 @@
-/********************************************************************** 
-   Copyright (C) 2004 - Marcelo J. Burda
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-***********************************************************************/
-#ifndef FC__TEMPERATURE_MAP_H
-#define FC__TEMPERATURE_MAP_H
-
-
-/*
- *  temperature_map[] stores the temperature of each tile
- *  values on tmap can get one of these 4 values
- *  there is 4 extra values as macros combining the 4 basics ones
- */
-typedef int temperature_type;
-
-#define  TT_FROZEN    1
-#define  TT_COLD      2
-#define  TT_TEMPERATE 4
-#define  TT_TROPICAL  8
-
-#define TT_NFROZEN (TT_COLD | TT_TEMPERATE | TT_TROPICAL)
-#define TT_ALL (TT_FROZEN | TT_NFROZEN)
-#define TT_NHOT (TT_FROZEN | TT_COLD)
-#define TT_HOT (TT_TEMPERATE | TT_TROPICAL)
-
-bool temperature_is_initialized(void);
-bool tmap_is(const struct tile *ptile, temperature_type tt);
-bool is_temperature_type_near(const struct tile *ptile, temperature_type tt);
-void destroy_tmap(void);
-void create_tmap(bool real);
-
-#endif  /* FC__TEMPERATURE_MAP_H */
diff -ruN -Xfreeciv/diff_ignore freeciv/server/generator/utilities.h 
freeciv_/server/generator/utilities.h
--- freeciv/server/generator/utilities.h        2004-10-15 19:16:54.000000000 
+0200
+++ freeciv_/server/generator/utilities.h       2004-10-25 18:11:43.000000000 
+0200
@@ -13,29 +13,13 @@
 #ifndef FC__UTILITIES_H
 #define FC__UTILITIES_H
 
-/* Provide a block to convert from native to map coordinates.  For instance
- *   do_in_map_pos(mx, my, xn, yn) {
- *     map_set_terrain(mx, my, T_OCEAN);
- *   } do_in_map_pos_end;
- * Note: that the map position is declared as const and can't be changed
- * inside the block.
- */
-#define do_in_map_pos(ptile, nat_x, nat_y)                                 \
-{                                                                           \
-  struct tile *ptile = native_pos_to_tile((nat_x), (nat_y));               \
-  {
-
-#define do_in_map_pos_end                                                   \
-  }                                                                         \
-}
-
 /***************************************************************************
  iterate axe iterate on selected axe ( x if Xaxe is TRUE) over a intervale
- of -dist to dist arround the tile indexed by index0
+ of -dist to dist arround the tile pointed.
  this iterator create 2 vars:
- index : the map index of the iterate pointed tile
+ iter_tile : the iterate pointed tile
  i : the position in the intervale of iteration (from -dist to dist)
- index0, dist, Xaxe are side effect safe.
+ the center_tile, dist and Xaxe args are side effect safe.
  ***************************************************************************/
 #define iterate_axe(iter_tile, i, center_tile, dist, Xaxe)             \
   {                                                                    \
diff -ruN -Xfreeciv/diff_ignore freeciv/server/srv_main.c 
freeciv_/server/srv_main.c
--- freeciv/server/srv_main.c   2004-10-22 17:33:19.000000000 +0200
+++ freeciv_/server/srv_main.c  2004-10-25 18:11:51.000000000 +0200
@@ -1798,7 +1798,7 @@
   /* If we have a tile map, and map.generator==0, call map_fractal_generate
    * anyway to make the specials, huts and continent numbers. */
   if (map_is_empty() || (map.generator == 0 && game.is_new_game)) {
-    map_fractal_generate(TRUE);
+    map_generate(TRUE);
   }
 
   gamelog_map();

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