Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2004:
[Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator
Home

[Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up
From: "Marcelo Burda" <mburda@xxxxxxxxx>
Date: Sat, 4 Sep 2004 15:57:55 -0700
Reply-to: rt@xxxxxxxxxxx

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

Oups! the patch is there

diff -ruN -Xfreeciv/diff_ignore freeciv/server/mapgen.c freeciv_/server/mapgen.c
--- freeciv/server/mapgen.c     2004-09-04 11:59:41.632923032 +0200
+++ freeciv_/server/mapgen.c    2004-09-04 22:48:38.176668656 +0200
@@ -91,7 +91,10 @@
 static const int hmap_max_level = 1000;
 static int hmap_shore_level, hmap_mountain_level;
 
-static int forests=0;
+static int forests_to_be_placed = 0;
+static int deserts_to_be_placed = 0;
+static int plains_to_be_placed = 0;
+static int swamps_to_be_placed = 0;
 
 struct isledata {
   int goodies;
@@ -99,19 +102,61 @@
 };
 static struct isledata *islands;
 
-/* this is the maximal temperature at equators returned by map_latitude */
+/* this is the maximal temperature at equators returned by map_temperature */
 #define MAX_TEMP 1000
 
 /* An estimate of the linear (1-dimensional) size of the map. */
 #define SQSIZE MAX(1, sqrt(map.xsize * map.ysize / 1000))
 
+/* define the 5 region of a Earth like map
+   =========================================================
+    0-COLD_LV                cold region: 
+    COLD_LV-TREOPICAL_LV     temperate wet region: 
+    TROPICAL_LV-MAX_TEMP     tropical wet region:
+
+   and a dry region, this last one can ovelap others 
+   DRY_MIN_LEVEL- DRY_MAX_LEVEL
+ */
+#define COLD_LEVEL (10 * MAX_TEMP / 100)
+#define TROPICAL_LEVEL (70 * MAX_TEMP / 100)
+#define DRY_MIN_LEVEL (65 * MAX_TEMP / 100)
+#define DRY_MAX_LEVEL (80 * MAX_TEMP / 100)
+
 /* used to create the poles and for separating them.  In a
  * mercator projection map we don't want the poles to be too big. */
 #define ICE_BASE_LEVEL                                         \
   ((!topo_has_flag(TF_WRAPX) || !topo_has_flag(TF_WRAPY))      \
    /* 5% for little maps; 2% for big ones */                   \
    ? MAX_TEMP * (3 + 2 * SQSIZE) / (100 * SQSIZE)              \
-   : 5 * MAX_TEMP / 100  /* 5% for all maps */)
+   : COLD_LEVEL / 2  /* for all maps */)
+
+/*
+ * these are base units to define distances 
+ */
+#define T_UNIT MIN(1, (hmap_max_level - hmap_shore_level) / 100)
+#define H_UNIT (MAX_TEMP / (30 * SQSIZE) )
+
+/*
+ * conditions for allow a dessert to be placed
+ */
+#define map_pos_is_dry(x, y) ((map_temperature((x), (y)) <= DRY_MAX_LEVEL) && \
+                              (map_temperature((x), (y)) > DRY_MIN_LEVEL) && \
+                              (count_ocean_near_tile((x),(y),FALSE) <= 2))
+/*
+ * conditions for allow a swamp to be placed
+ */
+#define map_pos_is_low(x, y) ((hmap((x), (y)) - hmap_shore_level) * 100 \
+             <2 * map.swampsize * (hmap_mountain_level - hmap_shore_level))
+/*
+ * conditions for allow a jungle to be placed
+ */
+#define map_pos_is_tropical(x, y) (map_temperature((x), (y)) > TROPICAL_LEVEL)
+
+/*
+ * conditions for allow a arctic to be placed
+ */
+#define map_pos_is_frizzed(x, y) \
+             (map_temperature((x), (y)) <= 2 * ICE_BASE_LEVEL)
 
 /****************************************************************************
   Used to initialize an array 'a' of size 'size' with value 'val' in each
@@ -286,42 +331,62 @@
                     - 0.5 * (x * x * x + y * y * y) 
                     + 1.5 * (x * x + y * y));
 }
-
+/*
+ * contions used when searching randomly
+ */ 
+#define condition_id enum consitions
+enum consitions { C_NONE, C_DRY, C_NDRY, C_LOW, C_NFRIZZED, C_TROPICAL };
+
+static bool map_pos_test_confition(int x, int y, condition_id c)
+{
+    switch(c) {
+       case C_NONE:
+           return TRUE;
+       case C_DRY:
+           return map_pos_is_dry(x, y);
+       case C_NDRY:
+           return !map_pos_is_dry(x, y);
+       case C_LOW:
+           return map_pos_is_low(x, y);
+       case C_NFRIZZED:
+           return !map_pos_is_frizzed(x, y);
+       case C_TROPICAL:
+           return map_pos_is_tropical(x, y);
+       default:
+           assert(0);
+    }
+}
 struct DataFilter {
-  int T_min, T_max;
+  condition_id c1, c2;
 };
 
 /****************************************************************************
   A filter function to be passed to rand_map_pos_filtered().  See
   rand_map_pos_temperature for more explanation.
 ****************************************************************************/
-static bool temperature_filter(int map_x, int map_y, void *data)
+static bool condition_filter(int map_x, int map_y, void *data)
 {
   struct DataFilter *filter = data;
-  const int T = map_temperature(map_x, map_y);
 
-  return (T >= filter->T_min) && (T <= filter->T_max) 
-         && not_placed(map_x, map_y) ;
+  return  not_placed(map_x, map_y) 
+      &&  map_pos_test_confition(map_x, map_y, filter->c1) 
+      &&  map_pos_test_confition(map_x, map_y, filter->c2) ;
 }
 
 /****************************************************************************
-  Return random map coordinates which have temperature within the selected
-  range and which are not yet placed on pmap. Returns FALSE if there is no 
-  such position.
+  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 bool rand_map_pos_temperature(int *map_x, int *map_y,
-                                    int T_min, int T_max)
+static bool rand_map_pos_condition(int *map_x, int *map_y,
+                                     condition_id c1, condition_id c2 )
 {
   struct DataFilter filter;
 
-  /* We could short-circuit the logic here (for instance, for non-temperate
-   * requests on a temperate map).  However this is unnecessary and isn't
-   * extensible.  So instead we just go straight to the rand_map_pos_filtered
-   * call. */
-
-  filter.T_min = T_min;
-  filter.T_max = T_max;
-  return rand_map_pos_filtered(map_x, map_y, &filter, temperature_filter);
+ 
+  filter.c1 = c1;
+  filter.c2 = c2;
+  return rand_map_pos_filtered(map_x, map_y, &filter, condition_filter);
 }
 
 /****************************************************************************
@@ -334,12 +399,58 @@
 }
 
 /**************************************************************************
-  make_mountains() will convert all squares that are higher than thill to
+  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_to_flat(int map_x, int map_y,int thill, int my_high)
+{
+  int biger_me = 0;
+  square_iterate(map_x, map_y, 2, x1, y1) {
+    if (hmap(x1, y1) > thill) {
+      return FALSE;
+    }
+    if (hmap(x1, y1) > my_high){
+      if(map_distance(map_x, map_y, x1, y1) == 1) {
+       return FALSE;
+      }
+      if(++biger_me > 2) {
+       return FALSE;
+      };
+    }
+  } square_iterate_end;
+
+  if ((thill - hmap_shore_level) * (biger_me)  > (my_high - 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 'height' 
+
+  Return TRUE if the terrain at the given map position is to height.
+****************************************************************************/
+static bool terrain_is_to_height(int map_x, int map_y,int thill, int my_high)
+{
+  square_iterate(map_x, map_y, 1, x1, y1) {
+    if (hmap(x1, y1) +(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. Notice that thill will be adjusted according to
   the map.mountains value, so increase map.mountains and you'll get more 
   hills and mountains (and vice versa).
 **************************************************************************/
-static void make_mountains(void)
+static void make_relief(void)
 {
   /* Calculate the mountain level.  map.mountains specifies the percentage
    * of land that is turned into hills and mountains. */
@@ -347,15 +458,18 @@
                         * (100 - map.mountains)) / 100 + hmap_shore_level;
 
   whole_map_iterate(x, y) {
-    if (hmap(x, y) > hmap_mountain_level
-       && !is_ocean(map_get_terrain(x, y))) { 
+    if (not_placed(x,y) &&
+       ((hmap_mountain_level < hmap(x, y) && 
+         (myrand(10) > 5 
+          || !terrain_is_to_height(x, y, hmap_mountain_level, hmap(x, y))))
+        || terrain_is_to_flat(x, y, hmap_mountain_level, hmap(x, y)))) {
       /* Randomly place hills and mountains on "high" tiles.  But don't
        * put hills near the poles (they're too green). */
-      if (myrand(100) > 75 
-         || map_temperature(x, y) <= MAX_TEMP / 10) {
+      if (myrand(100) > 70 
+         || map_temperature(x, y) <= COLD_LEVEL) {
        map_set_terrain(x, y, T_MOUNTAINS);
        map_set_placed(x, y);
-      } else if (myrand(100) > 25) {
+      } else {
        map_set_terrain(x, y, T_HILLS);
        map_set_placed(x, y);
       }
@@ -395,12 +509,30 @@
          map_set_placed(map_x, map_y);
        }
       } else if (myrand(10) > 0 && ptile->terrain != T_MOUNTAINS) {
-       ptile->terrain = T_TUNDRA;
+       ptile->terrain = T_TUNDRA; 
        map_set_placed(map_x, map_y);
       }
     }
   } whole_map_iterate_end;
 }
+/*************************************************************************
+ if separatepoles is set, return false if this tile has to kip ocean
+************************************************************************/
+static bool ok_for_separate_poles(int x, int y) 
+{
+  if (!map.separatepoles) {
+    return TRUE;
+  }
+  adjc_iterate(x, y, x1, y1) {
+    if(!is_ocean(map_get_terrain(x1, y1))
+       && map_get_continent(x1, y1 ) != 0) {
+      return FALSE;
+    }
+  } adjc_iterate_end;
+  return TRUE;
+}
+
+
 
 /****************************************************************************
   Place untextured land at the poles.  This is used by generators 1 and 5.
@@ -411,33 +543,19 @@
   struct tile *ptile;
   int T;
 
+  assign_continent_numbers();
   whole_map_iterate(map_x, map_y) {
     T = map_temperature(map_x, map_y); /* temperature parameter */
     ptile = map_get_tile(map_x, map_y);
-    if (T < 1.5 * ICE_BASE_LEVEL) {
+    if (T < 1.5 * ICE_BASE_LEVEL && ok_for_separate_poles(map_x, map_y)) {
       ptile->terrain = T_UNKNOWN;
       map_unset_placed(map_x, map_y);
-    } else if ((T <= 2 * ICE_BASE_LEVEL) && myrand(10) > 4 ) { 
+      map_set_continent(map_x, map_y, 0);
+    } else if ((T <= 2 * ICE_BASE_LEVEL) 
+              && myrand(10) > 4 && ok_for_separate_poles(map_x, map_y)) { 
       ptile->terrain = T_UNKNOWN;
       map_unset_placed(map_x, map_y);
-    }
-  } whole_map_iterate_end;
-}
-
-/****************************************************************************
-  Create tundra in cold zones.  Used by generators 1 and 5.  This must be
-  called after make_arctic since it will fill all remaining untextured
-  areas (we don't want any grassland left on the poles).
-****************************************************************************/
-static void make_tundra(void)
-{
-  whole_map_iterate(x, y) {
-    int T = map_temperature(x, y);
-
-    if (not_placed(x,y) 
-       && (2 * ICE_BASE_LEVEL > T || myrand(MAX_TEMP/5) > T)) {
-      map_set_terrain(x, y, T_TUNDRA);
-      map_set_placed(x, y);
+      map_set_continent(map_x, map_y, 0);
     }
   } whole_map_iterate_end;
 }
@@ -450,8 +568,8 @@
   whole_map_iterate(x, y) {
     int T = map_temperature(x, y);
 
-    if (not_placed(x,y) 
-       && myrand(15 * MAX_TEMP / 100) > T -  ICE_BASE_LEVEL 
+    if (not_placed(x, y)
+       && myrand(1.5 * COLD_LEVEL) > T -  ICE_BASE_LEVEL 
        && T <= 3 * ICE_BASE_LEVEL) {
       map_set_terrain(x, y, T_ARCTIC);
       map_set_placed(x, y);
@@ -460,30 +578,29 @@
 }
 
 /**************************************************************************
-  Recursively generate deserts.
+  Recursively generate terrains.
 
-  Deserts tend to clump up so we recursively place deserts nearby as well.
-  "Diff" is the recursion stopper and is reduced when the recursive call
-  is made.  It is reduced more if the desert wants to grow in north or
-  south (so we end up with "wide" deserts).
-
-  base_T is the temperature of the original desert.
-**************************************************************************/
-static void make_desert(int x, int y, int height, int diff, int base_T)
-{
-  const int DeltaT = MAX_TEMP / (3 * SQSIZE);
-
-  if (abs(hmap(x, y) - height) < diff 
-      && not_placed(x,y)) {
-    map_set_terrain(x, y, T_DESERT);
-    map_set_placed(x, y);
-    cardinal_adjc_iterate(x, y, x1, y1) {
-      make_desert(x1, y1, height,
-                 diff - 1 - abs(map_temperature(x1, y1) - base_T) / DeltaT,
-                 base_T);
-     
-    } cardinal_adjc_iterate_end;
-  }
+**************************************************************************/
+static void place_terrain(int x, int y, int diff, 
+                        enum tile_terrain_type ter, int *to_be_placed,
+                       condition_id c1, condition_id c2)
+{
+  if(*to_be_placed <= 0) { return; }
+  assert(not_placed(x, y) && map_pos_test_confition(x, y, c1) );
+  
+  map_set_terrain(x, y, ter);
+  map_set_placed(x, y);
+  (*to_be_placed)--;
+  cardinal_adjc_iterate(x, y, x1, y1) {
+    int Delta = abs(map_temperature(x1, y1) - map_temperature(x, y)) / T_UNIT
+       + abs(hmap(x1, y1) - (hmap(x, y))) /  H_UNIT;
+    if (not_placed(x1, y1) 
+       && map_pos_test_confition(x1, y1, c1)
+       && map_pos_test_confition(x1, y1, c2) && 
+       Delta < diff ) {
+      place_terrain(x1, y1, diff - 1 - Delta, ter, to_be_placed, c1, c2);
+    }
+  } cardinal_adjc_iterate_end;
 }
 
 /**************************************************************************
@@ -492,127 +609,154 @@
   enough forest has been planted. diff is again the block function.
   if we're close to equator it will with 50% chance generate jungle instead
 **************************************************************************/
-static void make_forest(int map_x, int map_y, int height, int diff)
+static void make_forest(int x, int y, int diff)
 {
-  int T = map_temperature(map_x, map_y);
-  if (not_placed(map_x, map_y)) {
-    if (T > 8 * MAX_TEMP / 10 
-       && myrand(1000) > 500 - 300 * (T * 1000 / MAX_TEMP - 800)) {
-      map_set_terrain(map_x, map_y, T_JUNGLE);
-    } else {
-      map_set_terrain(map_x, map_y, T_FOREST);
-    }
-    map_set_placed(map_x, map_y);
-    if (abs(hmap(map_x, map_y) - height) < diff) {
-      cardinal_adjc_iterate(map_x, map_y, x1, y1) {
-       if (myrand(10) > 5) {
-         make_forest(x1, y1, height, diff - 5);
-       }
-      } cardinal_adjc_iterate_end;
-    }
-    forests++;
+  if(forests_to_be_placed <= 0) { return; }
+  assert(not_placed(x, y));
+  if (map_pos_is_tropical(x, y)
+    && (myrand(100) >  50)) {
+      map_set_terrain(x, y, T_JUNGLE);
+  } else {
+    map_set_terrain(x, y, T_FOREST);
   }
+  map_set_placed(x, y);
+  forests_to_be_placed--;
+  
+  cardinal_adjc_iterate(x, y, x1, y1) {
+    int Delta = abs(hmap(x1, y1) - (hmap(x, y))) /  H_UNIT;
+    if (not_placed(x, y) && (myrand(10) > 5) && (Delta < diff) ) {
+       make_forest(x1, y1, diff - 1 - Delta);
+    }
+  } cardinal_adjc_iterate_end;
 }
 
+
 /**************************************************************************
-  makeforest calls make_forest with random unplaced locations until there
-  has been made enough forests. (the map.forestsize value controls this) 
+  a simple function that adds plains (,grassland or tundra) to the 
+  current location.
 **************************************************************************/
-static void make_forests(void)
+static void make_plain(int x, int y)
 {
-  int x, y;
-  int forestsize = (map_num_tiles() * map.forestsize) / 1000;
-
-  forests = 0;
-
-  do {
-    /* Place one forest clump anywhere. */
-    if (rand_map_pos_temperature(&x, &y,
-                                MAX_TEMP / 10, MAX_TEMP)) {
-      make_forest(x, y, hmap(x, y), 25);
-    } else { 
-      /* If rand_map_pos_temperature returns FALSE we may as well stop
-       * looking. */
-      break;
-    }
-
-    /* Now add another tropical forest clump (70-100% temperature). */
-    if (rand_map_pos_temperature(&x, &y,
-                                7 *MAX_TEMP / 10, MAX_TEMP)) {
-      make_forest(x, y, hmap(x, y), 25);
+  int T = map_temperature(x, y);
+  /* in cold place we get tundra instead */
+  if((COLD_LEVEL > T)) {
+    map_set_terrain(x, y, T_TUNDRA); 
+  } else {
+    if(myrand(100) > 50) {
+      map_set_terrain(x, y, T_GRASSLAND);
+    } else {
+      map_set_terrain(x, y, T_PLAINS);
     }
+  }
+  map_set_placed(x, y);
+  plains_to_be_placed--;
+}
 
-    /* And add a cold forest clump (10%-30% temperature). */
-    if (rand_map_pos_temperature(&x, &y,
-                1 * MAX_TEMP / 10, 3 * MAX_TEMP / 10)) {
-      make_forest(x, y, hmap(x, y), 25);
+/**************************************************************************
+  make_plains converts all not yet placed terrains to plains (tundra, grass) 
+  used by generators 2-4
+**************************************************************************/
+static void make_plains(void)
+{
+  whole_map_iterate(x, y) {
+    if (not_placed(x, y)) {
+      make_plain(x, y);
     }
-  } while (forests < forestsize);
+  } whole_map_iterate_end;
 }
 
 /**************************************************************************
-  swamps, is placed on low lying locations, that will typically be close to
-  the shoreline. They're put at random (where there is grassland)
-  and with 50% chance each of it's neighbour squares will be converted to
-  swamp aswell
+  make_terrains calls make_forest, make_dessert,etc  with random free 
+  locations until there  has been made enough.
+ Comment: funtions as make_swamp, etc. has to have a non 0 probability
+ to place one terrains in called position. Else make_terrains will get
+ in a infinite loop!
 **************************************************************************/
-static void make_swamps(void)
+static void make_terrains(void)
 {
-  int x, y, swamps;
-  int forever = 0;
-  const int swamps_to_be_placed 
-      = MAX_MAP_INDEX *  map.swampsize * map.landpercent / 10000;
-  const int hmap_swamp_level = ((hmap_max_level - hmap_shore_level)
-                         * 2 * map.swampsize) / 100 + hmap_shore_level;
+  int x, y;
+  int total = 0;
+  whole_map_iterate(x, y) {
+    if(not_placed(x,y)) {
+     total++;
+    }
+  } whole_map_iterate_end;
 
-  for (swamps = 0; swamps < swamps_to_be_placed; ) {
-    forever++;
-    if (forever > 1000) {
-      return;
+  forests_to_be_placed = total * map.forestsize
+       / ( map.forestsize + map.deserts + map.grasssize +  map.swampsize );
+  deserts_to_be_placed = total * map.deserts
+       / ( map.forestsize + map.deserts + map.grasssize +  map.swampsize);
+  swamps_to_be_placed = total * map.swampsize
+       / ( map.forestsize + map.deserts + map.grasssize +  map.swampsize);
+
+  /* grassland, tundra and plains is counted in map.grasssize */
+  plains_to_be_placed = total - forests_to_be_placed - deserts_to_be_placed
+                       - swamps_to_be_placed;
+  /* the plasing loop */
+  do {
+    if(forests_to_be_placed > 0) {
+      /* Place one forest clump between Very Cold level and MAX_TEMP. */
+      if (rand_map_pos_condition(&x, &y, C_NONE, C_NONE)) {
+       make_forest(x, y, 25);
+      } else { 
+        /* If rand_map_pos_temperature returns FALSE we may as well stop
+         * looking for forest. */
+       plains_to_be_placed += forests_to_be_placed;
+       forests_to_be_placed = 0;
+      }
     }
-    rand_map_pos(&x, &y);
-    if (not_placed(x, y)
-       && hmap(x, y) < hmap_swamp_level) {
-      map_set_terrain(x, y, T_SWAMP);
-      map_set_placed(x, y);
-      cardinal_adjc_iterate(x, y, x1, y1) {
-       if (myrand(10) > 5 && not_placed(x1, y1)) { 
-         map_set_terrain(x1, y1, T_SWAMP);
-         map_set_placed(x1, y1);
-         swamps++;
-       }
-      } cardinal_adjc_iterate_end;
-      swamps++;
-      forever = 0;
+
+    if(swamps_to_be_placed > 0) {
+      /* Place one swamp clump in wet tiles */
+      if (rand_map_pos_condition(&x, &y, C_LOW, C_NDRY)) {
+         place_terrain(x, y, 40, 
+                      T_SWAMP, &swamps_to_be_placed, C_NDRY, C_LOW);
+      } else { 
+        /* If rand_map_pos_temperature returns FALSE we may as well stop
+         * looking for swamp. */
+       forests_to_be_placed += swamps_to_be_placed;
+       swamps_to_be_placed = 0;
+      }
     }
-  }
-}
 
-/*************************************************************************
-  Make deserts until we have enough of them.
-**************************************************************************/
-static void make_deserts(void)
-{
-  int x, y, i = map.deserts, j = 0;
+    if(deserts_to_be_placed > 0) {
+      /* Choose a random coordinate in dry zone;
+        make_desert will expand them). */
+      if (rand_map_pos_condition(&x, &y, C_DRY, C_NONE)){
+       place_terrain(x, y, 80, 
+                      T_DESERT, &deserts_to_be_placed, C_DRY, C_NONE);
+         /* if not posible try lower latitude */
+      } else if (rand_map_pos_condition(&x, &y, C_NONE, C_NONE)){
+       place_terrain(x, y, 40, 
+                     T_DESERT, &deserts_to_be_placed, C_NONE, C_NONE);
+      } else {
+       /* If rand_map_pos_temperature returns FALSE we may as well stop
+        * looking for dessert. (convert to plains) */
+       plains_to_be_placed += deserts_to_be_placed;
+       deserts_to_be_placed = 0;
+      }
+    }
 
-  /* "i" is the number of desert clumps made; "j" is the number of tries. */
-  /* TODO: j is no longer needed */
-  while (i > 0 && j < 100 * map.deserts) {
-    j++;
-
-    /* Choose a random coordinate between 20 and 30 degrees north/south
-     * (deserts tend to be between 15 and 35; make_desert will expand
-     * them). */
-    if (rand_map_pos_temperature(&x, &y,
-          65 * MAX_TEMP / 100, 80 * MAX_TEMP / 100)){
-      make_desert(x, y, hmap(x, y), 50, map_temperature(x, y));
-      i--;
-    } else {
-      /* If rand_map_pos_temperature returns FALSE we may as well stop
-       * looking. */
-      break;
+    /* there is very important: this place all terrains when there
+       is not posibe for other types kip the 0, MAX_TEMP range. */
+    /* make the plains and tundras */
+    if(plains_to_be_placed > 0) {
+     if (rand_map_pos_condition(&x, &y, C_NONE, C_NONE)){
+       make_plain(x,y);
+      } else {
+       /* If rand_map_pos_temperature returns FALSE we may as well stop
+        * looking for plains. */
+       plains_to_be_placed = 0;
+      }
     }
-  }
+
+  } while (forests_to_be_placed > 0 || deserts_to_be_placed > 0 
+          || plains_to_be_placed > 0 || swamps_to_be_placed > 0 );
+
+  /* final test */
+  whole_map_iterate(x, y) {
+    assert(!not_placed(x,y));
+  } whole_map_iterate_end;
 }
 
 /*********************************************************************
@@ -853,7 +997,7 @@
     if (count_special_near_tile(x, y, TRUE, S_RIVER) != 0
        || count_ocean_near_tile(x, y, TRUE) != 0
         || (map_get_terrain(x, y) == T_ARCTIC 
-           && map_temperature(x, y) < 8 * MAX_TEMP / 100)) { 
+           && map_temperature(x, y) < 0.8 * COLD_LEVEL)) { 
 
       freelog(LOG_DEBUG,
              "The river ended at (%d, %d).\n", x, y);
@@ -957,7 +1101,8 @@
      * 1000 rather than the current 100 */
     10 *
     /* The size of the map (poles don't count). */
-    map_num_tiles() * (map.alltemperate ? 1.0 : 0.90) *
+    map_num_tiles() 
+      * (map.alltemperate ? 1.0 : 2.0 * ICE_BASE_LEVEL/MAX_TEMP) *
     /* Rivers need to be on land only. */
     map.landpercent /
     /* Adjustment value. Tested by me. Gives no rivers with 'set
@@ -1065,62 +1210,6 @@
   river_map = NULL;
 }
 
-/**************************************************************************
-  make_plains converts 50% of the remaining terrains to plains and 50%
-  grassland,
-**************************************************************************/
-static void make_plains(void)
-{
-  whole_map_iterate(x, y) {
-    if (not_placed(x, y)) {
-      if(myrand(100) > 50) {
-         map_set_terrain(x, y, T_GRASSLAND);
-      } else {
-         map_set_terrain(x, y, T_PLAINS);
-      }
-      map_set_placed(x, y);
-    }
-  } whole_map_iterate_end;
-}
-/****************************************************************************
-  Return TRUE if the terrain at the given map position is "clean".  This
-  means that all the terrain for 2 squares around it is either grassland or
-  plains.
-****************************************************************************/
-static bool terrain_is_clean(int map_x, int map_y)
-{
-  square_iterate(map_x, map_y, 2, x1, y1) {
-    if (map_get_terrain(x1, y1) != T_GRASSLAND
-       && map_get_terrain(x1, y1) != T_PLAINS) {
-      return FALSE;
-    }
-  } square_iterate_end;
-
-  return TRUE;
-}
-
-/**************************************************************************
-  we don't want huge areas of grass/plains, 
- so we put in a hill here and there, where it gets too 'clean' 
-**************************************************************************/
-static void make_fair(void)
-{
-  whole_map_iterate(map_x, map_y) {
-    if (terrain_is_clean(map_x, map_y)) {
-      if (!map_has_special(map_x, map_y, S_RIVER)) {
-       map_set_terrain(map_x, map_y, T_HILLS);
-      }
-      cardinal_adjc_iterate(map_x, map_y, x1, y1) {
-       if (myrand(100) > 66
-           && !is_ocean(map_get_terrain(x1, y1))
-           && !map_has_special(x1, y1, S_RIVER)) {
-         map_set_terrain(x1, y1, T_HILLS);
-       }
-      } cardinal_adjc_iterate_end;
-    }
-  } whole_map_iterate_end;
-}
-
 /****************************************************************************
   Lower the land near the polar region to avoid too much land there.
 
@@ -1171,7 +1260,9 @@
 {
   create_placed_map(); /* here it means land terrains to be placed */
   adjust_hmap();
-  normalize_hmap_poles();
+  if(!map.alltemperate) {
+    normalize_hmap_poles();
+  }
   hmap_shore_level = (hmap_max_level * (100 - map.landpercent)) / 100;
   whole_map_iterate(x, y) {
     map_set_terrain(x, y, T_UNKNOWN); /* set as oceans count is used */
@@ -1180,17 +1271,13 @@
       map_set_placed(x, y); /* placed, not a land target */
     }
   } whole_map_iterate_end;
-
-  renormalize_hmap_poles();
-  make_polar_land(); /* make extra land at poles */
-  make_mountains();
-  make_arctic();
-  make_tundra();
-  make_swamps();
-  make_forests();
-  make_deserts();
-  make_plains();
-  make_fair();
+  if(!map.alltemperate) {
+    renormalize_hmap_poles(); 
+    make_polar_land(); /* make extra land at poles*/
+  }
+  make_relief(); /* base relief on map */
+  make_arctic(); 
+  make_terrains();/* place forest/dessert/swamp/grass/tundra and plains */
   make_rivers();
   remove_placed_map();
   assign_continent_numbers();
@@ -1645,9 +1732,9 @@
 static void adjust_terrain_param(void)
 {
   int total;
-  int polar = 5; /* FIXME: convert to a server option */
+  int polar = ICE_BASE_LEVEL * 100 / MAX_TEMP;
 
-  total = map.mountains + map.deserts + map.forestsize + map.swampsize 
+  total = map.mountains + map.deserts + map.forestsize + map.swampsize
     + map.grasssize;
 
   if (total != 100 - polar) {
@@ -1820,8 +1907,7 @@
 
     /* Add a hut.  But not on a polar area, on an ocean, or too close to
      * another hut. */
-    if (rand_map_pos_temperature(&x, &y,
-                                2 * ICE_BASE_LEVEL, MAX_TEMP)) {
+    if (rand_map_pos_condition(&x, &y, C_NFRIZZED, C_NONE)) {
       if (is_ocean(map_get_terrain(x, y))) {
        map_set_placed(x, y); /* not good for a hut */
       } else {
@@ -2346,12 +2432,11 @@
     map_clear_all_specials(x, y);
     map_set_owner(x, y, NULL);
   } whole_map_iterate_end;
-  if (!map.alltemperate) {
-    make_polar();
+  if (!map.alltemperate) { make_polar(); }
     /* Set poles numbers.  After the map is generated continents will 
      * be renumbered. */
     assign_continent_numbers(); 
-  }
+
   make_island(0, 0, pstate, 0);
   for(i = 0; i <= map.num_continents; i++ ) {
       islands[i].starters = 0;
diff -ruN -Xfreeciv/diff_ignore freeciv/server/stdinhand_info.h 
freeciv_/server/stdinhand_info.h
--- freeciv/server/stdinhand_info.h     2004-08-29 21:08:59.000000000 +0200
+++ freeciv_/server/stdinhand_info.h    2004-09-04 11:47:31.219962680 +0200
@@ -268,7 +268,7 @@
 
   GEN_INT("grass", map.grasssize,
          SSET_MAP_GEN, SSET_ECOLOGY, SSET_SITUATIONAL, SSET_TO_CLIENT,
-         N_("Amount of grass squares"), "", NULL,
+         N_("Amount of grass/plains and tundra squares"), "", NULL,
          MAP_MIN_GRASS, MAP_MAX_GRASS, MAP_DEFAULT_GRASS)
 
   GEN_INT("forests", map.forestsize,

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