Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2004:
[Freeciv-Dev] Re: (PR#8624) New clima function to best handle terrain pl
Home

[Freeciv-Dev] Re: (PR#8624) New clima function to best handle terrain pl

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] Re: (PR#8624) New clima function to best handle terrain place, used to place poles.
From: "Marcelo Burda" <mburda@xxxxxxxxx>
Date: Thu, 27 May 2004 08:35:40 -0700
Reply-to: rt@xxxxxxxxxxx

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

Le jeu 27/05/2004 à 07:00, Jason Short a écrit :
> <URL: http://rt.freeciv.org/Ticket/Display.html?id=8624 >
> 
> > [mburda - Wed May 26 15:47:49 2004]:
> 
> > anything else?
> 
> - Why do you change the default separatepoles value?
> 
I set true as  default :-(

> - I think you can get rid of rand_map_pos_temperature.  Just pass the
> terrain to rand_map_pos_temperature_terrain and use T_UNKNOWN for any
> terrain.  (You may wish to rename the function.)
> 
done
I define after T_LAST a T_ANY (this no wroken savegmes) T_ANY is not a
valid Terrains types but as T_LAST a spetial flag for searching.
we can want searh for a T_UNKNOWN tiles! and T_LAST are ugly as arg for
a search.
>
....
> - You should replace 1000 with a MAX_TEMPERATURE define (or a const
> variable if you prefer).  And use this value where it's needed.  In
> several places you have code like if (myrand(200) > T).  Here the 200
> should be MAX_TEMP/5.
done, but was ugly, finaly 0 ot 1000 was best.
> 
> - Of course the polar code is quite ugly but this is probably
> unavoidable.  However the poles in topo5 are still 2 tiles wide.  Can
> this be improved (should be 1 tile)?
> 
kip as it, to alow to colonize a poles, one tile more is no so much
> I think that's all.
> 
> jason
!!! that's all ?!!!
-- 
 . /  .     '    ,    .      (*)   '        `     '      `    .    
  |    ,  |   `     ,     .      ,   '  Marcelo Julián Burda      .
 /  '     \     `     \@_     '      .        '      `        '    
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

diff -ruN -Xfreeciv/diff_ignore freeciv/common/map.c freeciv_/common/map.c
--- freeciv/common/map.c        2004-05-27 12:55:38.000000000 +0200
+++ freeciv_/common/map.c       2004-05-27 19:24:41.000000000 +0200
@@ -192,6 +192,7 @@
   map.generator             = MAP_DEFAULT_GENERATOR;
   map.tinyisles             = MAP_DEFAULT_TINYISLES;
   map.separatepoles         = MAP_DEFAULT_SEPARATE_POLES;
+  map.alltemperate          = MAP_DEFAULT_ALLTEMPERATE;
   map.tiles                 = NULL;
   map.num_continents        = 0;
   map.num_start_positions   = 0;
@@ -1546,3 +1547,23 @@
   map_distance_vector(&diff_x, &diff_y, start_x, start_y, end_x, end_y);
   return (diff_x == 0) || (diff_y == 0);
 }
+
+/****************************************************************************
+  A "SINGULAR position" is any map position that have a anormal number of
+ tiles in the radius of dist 
+ arg need to be normalized_map_pos
+****************************************************************************/
+bool is_singular_map_pos(int map_x, int map_y, int dist)
+{
+  CHECK_MAP_POS(map_x, map_y);
+  do_in_natural_pos(ntl_x, ntl_y, map_x, map_y) {
+    /* in natural coordinates dist from borders are  / 2 */
+    dist = topo_has_flag(TF_ISO) ? (2 * dist) : dist;
+
+    return  (!topo_has_flag(TF_WRAPX) 
+            && (ntl_x < dist || ntl_x >= NATURAL_WIDTH - dist))
+           || 
+           (!topo_has_flag(TF_WRAPY)
+            && (ntl_y < dist || ntl_y >= NATURAL_HEIGHT - dist));
+  } do_in_natural_pos_end;
+}
diff -ruN -Xfreeciv/diff_ignore freeciv/common/map.h freeciv_/common/map.h
--- freeciv/common/map.h        2004-05-27 12:55:38.000000000 +0200
+++ freeciv_/common/map.h       2004-05-27 19:24:41.000000000 +0200
@@ -131,6 +131,7 @@
   int generator;
   bool tinyisles;
   bool separatepoles;
+  bool alltemperate;
   int num_start_positions;
   bool have_specials;
   bool have_huts;
@@ -311,7 +312,7 @@
 bool contains_special(enum tile_special_type all,
                      enum tile_special_type to_test_for);
 
-
+bool is_singular_map_pos(int map_x, int map_y, int dist);
 bool normalize_map_pos(int *x, int *y);
 void nearest_real_pos(int *x, int *y);
 void map_distance_vector(int *dx, int *dy, int x0, int y0, int x1, int y1);
@@ -697,6 +698,10 @@
 #define MAP_MIN_SEPARATE_POLES       FALSE
 #define MAP_MAX_SEPARATE_POLES       TRUE
 
+#define MAP_DEFAULT_ALLTEMPERATE   FALSE
+#define MAP_MIN_ALLTEMPERATE       FALSE
+#define MAP_MAX_ALLTEMPERATE       TRUE
+
 
 /*
  * Inline function definitions.  These are at the bottom because they may use
@@ -733,4 +738,5 @@
   } do_in_native_pos_end;
 }
 
+
 #endif  /* FC__MAP_H */
diff -ruN -Xfreeciv/diff_ignore freeciv/common/terrain.h 
freeciv_/common/terrain.h
--- freeciv/common/terrain.h    2004-05-21 10:54:00.000000000 +0200
+++ freeciv_/common/terrain.h   2004-05-27 18:41:38.000000000 +0200
@@ -64,7 +64,8 @@
 enum tile_terrain_type {
   T_ARCTIC, T_DESERT, T_FOREST, T_GRASSLAND, T_HILLS, T_JUNGLE, 
   T_MOUNTAINS, T_OCEAN, T_PLAINS, T_UNUSED, T_SWAMP, T_TUNDRA, T_UNKNOWN,
-  T_LAST
+  T_LAST, /* last terrain type */
+  T_ANY   /* used as arg for search for any terrain type */
 };
 #define T_FIRST (T_ARCTIC)
 #define T_COUNT (T_UNKNOWN)
diff -ruN -Xfreeciv/diff_ignore freeciv/server/mapgen.c freeciv_/server/mapgen.c
--- freeciv/server/mapgen.c     2004-05-21 10:54:02.000000000 +0200
+++ freeciv_/server/mapgen.c    2004-05-27 19:24:41.000000000 +0200
@@ -77,7 +77,6 @@
 static int *height_map;
 static int maxval=0;
 static int forests=0;
-static bool has_poles;
 
 struct isledata {
   int goodies;
@@ -88,6 +87,182 @@
 /* this is used for generator>1 */
 #define MAP_NCONT 255
 
+/* **********************************************************************
+ * return 0 for the coolest map_x,map_y tile of the map
+ * and 1000 for the hotest one, this is proportional to area climatic zones
+ *************************************************************************/ 
+
+static int map_temperature(int map_x, int map_y)
+{
+  double x, y;
+  
+  if(map.alltemperate) { return   MAX_TEMP / 2; }
+  /* is a all temperate map */
+
+  do_in_natural_pos(ntl_x, ntl_y, map_x, map_y) {
+    /*
+     * Is a FLAT (unwraped) map 
+     * I asume this is a partial map of Earth, at top i place a polar zone 
+     * at bottom the ecuator one. this is a partial Earth map.
+     * flat as only one pole!
+     */
+    if (!topo_has_flag(TF_WRAPX) && !topo_has_flag(TF_WRAPY)) {
+      return MAX_TEMP * ntl_y / (NATURAL_HEIGHT - 1);
+    }
+
+    /*
+     * Is a global map
+     */
+
+     /* we fold the map to get the base symetries
+     ...... 
+     :c__c:
+     :____:
+     :____:
+     :c__c:
+     ......
+  
+
+     x, y vars form 0.0 to 1.0 map a folded representation of the map
+     were C are all corners
+     ...>x 
+     :C_
+     :__
+     V
+     y
+
+     */
+
+    x = ( ntl_x > (NATURAL_WIDTH / 2  - 1) 
+                 ? NATURAL_WIDTH  - 1.0 - (double)ntl_x 
+                 : (double)ntl_x) 
+       / ((NATURAL_WIDTH / 2 - 1));
+    y = ( ntl_y > (NATURAL_HEIGHT / 2 - 1) 
+                 ? NATURAL_HEIGHT - 1.0 - (double)ntl_y 
+                 : (double)ntl_y)
+       / (NATURAL_HEIGHT / 2 - 1);
+  } do_in_natural_pos_end;
+
+  /*
+   * classic topo 
+   * the polar zone are at N and S
+   */
+  if (topo_has_flag(TF_WRAPX) && !topo_has_flag(TF_WRAPY)) {
+    return MAX_TEMP * y;
+  }
+  
+  /* Uranus topo */
+  /* poles at E and W */
+  if (!topo_has_flag(TF_WRAPX) && topo_has_flag(TF_WRAPY)) {
+    return MAX_TEMP * x;
+  }
+
+  /*
+   * torus topo
+   * i make 2 circle polar zone (2 poles)
+   * Equatorial zone as the shape of a square in the map
+   */
+  
+  
+  /* generator 2 and 5 work best if the center of the map is free */
+  /* poles (N,S) and equator ( /,\)
+     ........
+     :\ NN /:
+     : \  / :
+     :S \/ S:
+     :S /\ S: .....
+     : /  \ :
+     :/ NN \:
+     ''''''''
+  */
+  x = 1.0 - x;
+  /* poles (N,S) and equator ( /,\)
+     ........
+     :N /\ N:
+     : /  \ :
+     :/ SS \:
+     :\ SS /: .....
+     : \  / :
+     :N \/ N:
+     ''''''''
+  */
+
+  /*
+    after the 4 fold
+    then we can fold it in diagonal:
+  */
+
+  if (x + y > 1.0) {
+      x = 1.0 - x;
+      y = 1.0 - y;
+  }
+
+  /* now the x and y variables work in 1/8 of the maps 
+     .....
+     :P /
+     : / 
+     :/
+     where P is N and S poles
+  */
+
+  /* 
+     these math make poles with a shapes of 1/4circle on "P"
+     and equator as shape of rifht line on "/"
+  */
+  return MAX_TEMP * (1.5 * (x * x * y + x * y * y) 
+      - 0.5 * (x * x * x + y * y * y) 
+      + 1.5 * (x * x + y * y));
+  
+}
+
+/* **************************************************************
+ * 
+ * return random map coordinates where climate is in selected range
+ * and were terrains choice exept it T_ANY
+ * return false if pos is not finded in a all temperate planet
+ * a false value can be used to make less of this type of terrains
+ * or to make a call of rand_map_pos
+ * **************************************************************/
+
+static bool temperature_filter(int map_x, int map_y, void *D_)
+{
+  
+  const int T = map_temperature( map_x, map_y);
+  return T >= ((int *)D_)[0] && T <= ((int *)D_)[1] 
+      && (T_ANY ==  ((int *)D_)[2] 
+         || map_get_terrain(map_x, map_y) == ((int *)D_)[2]) ;
+}
+
+static bool rand_map_pos_temperature( int *map_x, int *map_y,
+                                     int T_min, int T_max,int TT)
+{
+  int D_[3];
+
+  /* no poles, all temperate */
+  if(map.alltemperate 
+     && ( T_min > MAX_TEMP / 2 
+         || T_max < MAX_TEMP / 2)) {
+    return FALSE;
+  }
+
+  D_[0] = T_min;
+  D_[1] = T_max;
+  D_[2] = TT; 
+  return rand_map_pos_filtered( map_x, map_y, D_, temperature_filter);
+}
+
+
+/* ************************************************************
+ * Return TRUE if the map in a city radius is  singular 
+ * This need to be best defined in future topologies works
+ * This def is ok for generalised topologies
+ * ************************************************************/
+
+static bool near_singularity(int map_x, int map_y)
+{
+  return is_singular_map_pos(map_x, map_y, CITY_MAP_RADIUS) ;
+}
+
 /**************************************************************************
   make_mountains() will convert all squares that are higher than thill to
   mountains and hills. Notice that thill will be adjusted according to
@@ -113,9 +288,11 @@
   
   whole_map_iterate(x, y) {
     if (hmap(x, y) > thill && !is_ocean(map_get_terrain(x,y))) { 
-      if (myrand(100)>75) 
+      if (myrand(100)>75 
+         /* T_HILLS are too green for poles */
+         || map_temperature(x, y) <= MAX_TEMP / 10 ) 
        map_set_terrain(x, y, T_MOUNTAINS);
-      else if (myrand(100)>25) 
+      else  if (myrand(100)>25) 
        map_set_terrain(x, y, T_HILLS);
     }
   } whole_map_iterate_end;
@@ -123,70 +300,95 @@
 
 /**************************************************************************
  add arctic and tundra squares in the arctic zone. 
- (that is the top 10%, and low 10% of the map)
-**************************************************************************/
-static void make_polar(void)
-{
-  int xn, yn;
-
-  for (yn = 0; yn < map.ysize / 10; yn++) {
-    for (xn = 0; xn < map.xsize; xn++) {
-      if ((hnat(xn, yn) + (map.ysize / 10 - yn * 25) > myrand(maxval)
-          && nat_get_terrain(xn, yn) == T_GRASSLAND) || yn == 0) { 
-       if (yn < 2) {
-         nat_set_terrain(xn, yn, T_ARCTIC);
-       } else {
-         nat_set_terrain(xn, yn, T_TUNDRA);
-       }
-      } 
-    }
-  }
-  for (yn = map.ysize * 9 / 10; yn < map.ysize; yn++) {
-    for (xn = 0; xn < map.xsize; xn++) {
-      if (((hnat(xn, yn) + (map.ysize / 10 - (map.ysize - yn - 1) * 25)
-           > myrand(maxval))
-          && nat_get_terrain(xn, yn) == T_GRASSLAND)
-         || yn == map.ysize - 1) {
-       if (yn > map.ysize - 3) {
-         nat_set_terrain(xn, yn, T_ARCTIC);
-       } else {
-         nat_set_terrain(xn, yn, T_TUNDRA);
+ (that is the coolest 10% of the map)
+ if make_polar(TRUE) we texture the pole (tundra and mount)
+ (hmap not exist or flated to separate poles ))
+ if false we only make a basse terrains to be texture later
+**************************************************************************/
+#define SQSIZE MAX(1, sqrt( map.xsize * map.ysize / 1000))
+#define ICE_BASE_LEVEL (/* if poles are strips */ \
+      (!topo_has_flag(TF_WRAPX) || !topo_has_flag(TF_WRAPY)) \
+           /* 5% for litle maps 2% for bigs */ \
+      ? MAX_TEMP * (3 + 2 * SQSIZE) / ( 100 * SQSIZE) \
+      /* else */ \
+      : 5 * MAX_TEMP / 100  /* 5% for all maps */)
+static void make_polar(bool texture )
+{
+  struct tile *ptile;
+  int T;
+  if(texture) {
+    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 < ICE_BASE_LEVEL) { /* get the coldest part of the map */
+       if (ptile->terrain != T_MOUNTAINS)
+         ptile->terrain = T_ARCTIC;
+      } else if ((T <= 1.5 * ICE_BASE_LEVEL) 
+                && (ptile->terrain == T_OCEAN) ) {  
+       ptile->terrain = T_ARCTIC;
+      } else if (T <= 2 * ICE_BASE_LEVEL) {
+       if (ptile->terrain == T_OCEAN) {
+         if (myrand(10) > 5) {
+           ptile->terrain = T_ARCTIC;
+         } else if (myrand(10) > 6) {
+           ptile->terrain = T_TUNDRA;
+         }
+       } else if (myrand(10) > 0 && ptile->terrain != T_MOUNTAINS) {
+         ptile->terrain = T_TUNDRA;
        }
       }
-    }
-  }
-
-  /* only arctic and tundra allowed at the poles (first and last two lines,
-     as defined in make_passable() ), to be consistent with generator>1. 
-     turn every land tile on the second lines that is not arctic into tundra,
-     since the first lines has already been set to all arctic above. */
-  for (xn = 0; xn < map.xsize; xn++) {
-    if (nat_get_terrain(xn, 1) != T_ARCTIC
-       && !is_ocean(nat_get_terrain(xn, 1))) {
-      nat_set_terrain(xn, 1, T_TUNDRA);
-    }
-    if (nat_get_terrain(xn, map.ysize - 2) != T_ARCTIC
-       && !is_ocean(nat_get_terrain(xn, map.ysize - 2))) {
-      nat_set_terrain(xn, map.ysize - 2, T_TUNDRA);
-    }
+    } whole_map_iterate_end;
+  } else {
+      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) {
+         ptile->terrain = T_GRASSLAND;
+       } else if ((T <= 2 * ICE_BASE_LEVEL) && myrand(10) > 4 ) { 
+         ptile->terrain = T_GRASSLAND;
+       }
+      } whole_map_iterate_end;
   }
 }
+/*************************************************************************
+ create tundra and artic  in cold zones
+*************************************************************************/
+static void make_tundra(void)
+{
+  whole_map_iterate(x, y) {
+    int T = map_temperature(x, y);
+    if (map_get_terrain(x, y) == T_GRASSLAND && myrand(200) > T)
+      map_set_terrain(x, y, T_TUNDRA);
+  } whole_map_iterate_end;
+}
+static void make_arctic(void)
+{
+  whole_map_iterate(x, y) {
+    int T = map_temperature(x, y);
+    if (map_get_terrain(x, y) == T_GRASSLAND 
+       && myrand(15 * MAX_TEMP / 100) > T -  ICE_BASE_LEVEL 
+       && T <= 3 * ICE_BASE_LEVEL )
+      map_set_terrain(x, y, T_ARCTIC);
+  } whole_map_iterate_end;
+}
 
 /**************************************************************************
   recursively generate deserts, i use the heights of the map, to make the
   desert unregulary shaped, diff is the recursion stopper, and will be reduced
-  more if desert wants to grow in the y direction, so we end up with 
+  more if desert wants to grow in the N-S axes, so we end up with 
   "wide" deserts. 
 **************************************************************************/
-static void make_desert(int x, int y, int height, int diff) 
+static void make_desert(int x, int y, int height, int diff, int base_T) 
 {
-  if (abs(hmap(x, y)-height)<diff && map_get_terrain(x, y)==T_GRASSLAND) {
+  const int DeltaT = MAX_TEMP / (3 * SQSIZE);
+  if (abs(hmap(x, y) - height) < diff 
+      && map_get_terrain(x, y) == T_GRASSLAND) {
     map_set_terrain(x, y, T_DESERT);
     cartesian_adjacent_iterate(x, y, x1, y1) {
-      if (x != x1)
-       make_desert(x1, y1, height, diff-1);
-      else /* y != y1 */
-       make_desert(x1, y1, height, diff-3);
+      make_desert(x1, y1, height,
+                 diff - 1 - abs(map_temperature(x1, y1) - base_T) / DeltaT
+                 , base_T);
+     
     } cartesian_adjacent_iterate_end;
   }
 }
@@ -199,16 +401,13 @@
 **************************************************************************/
 static void make_forest(int map_x, int map_y, int height, int diff)
 {
-  int nat_x, nat_y;
+  int nat_x, nat_y,T;
 
   map_to_native_pos(&nat_x, &nat_y, map_x, map_y);
-  if (has_poles && (nat_y == 0 || nat_y == map.ysize - 1)) {
-    return;
-  }
-
+  T = map_temperature(map_x, map_y);
   if (map_get_terrain(map_x, map_y) == T_GRASSLAND) {
-    if (has_poles && nat_y > map.ysize * 42 / 100
-       && nat_y < map.ysize * 58 / 100 && myrand(100) > 50) {
+    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);
@@ -236,19 +435,24 @@
   forests = 0;
 
   do {
-    rand_map_pos(&x, &y);
-    if (map_get_terrain(x, y) == T_GRASSLAND) {
+    if( rand_map_pos_temperature(&x, &y,
+                                MAX_TEMP / 10, MAX_TEMP,
+                                T_GRASSLAND)) {
       make_forest(x, y, hmap(x, y), 25);
+    } else { 
+      break;/* if rand_map_pos_temperature is false this never will be true*/
     }
-    if (has_poles && myrand(100) > 75) {
-      int yn = myrand(map.ysize * 2 / 10) + map.ysize * 4 / 10;
-      int xn = myrand(map.xsize);
-
-      if (nat_get_terrain(xn, yn) == T_GRASSLAND) {
-       do_in_map_pos(x, y, xn, yn) {
-         make_forest(x, y, hmap(x, y), 25);
-       } do_in_map_pos_end;
-      }
+    /* some extra tropical forest */
+    if( rand_map_pos_temperature(&x, &y,
+                                7 *MAX_TEMP / 10, MAX_TEMP,
+                                T_GRASSLAND) ) {
+      make_forest(x, y, hmap(x, y), 25);
+    }
+    /* some extra cold forest */
+    if( rand_map_pos_temperature(&x, &y,
+                       1 *MAX_TEMP / 10, 3 * MAX_TEMP / 10,
+                       T_GRASSLAND) ) {
+      make_forest(x, y, hmap(x, y), 25);
     }
   } while (forests < forestsize);
 }
@@ -270,10 +474,11 @@
     if (map_get_terrain(x, y)==T_GRASSLAND && hmap(x, y)<(maxval*60)/100) {
       map_set_terrain(x, y, T_SWAMP);
       cartesian_adjacent_iterate(x, y, x1, y1) {
-       if (myrand(10) > 5 && !is_ocean(map_get_terrain(x1, y1))) { 
-         map_set_terrain(x1, y1, T_SWAMP);
+       if (myrand(10) > 5 && !is_ocean(map_get_terrain(x1, y1)) 
+           &&  map_get_terrain(x1, y1) != T_SWAMP ) { 
+         map_set_terrain(x1, y1, T_SWAMP);
+         swamps++;
        }
-       /* maybe this should increment i too? */
       } cartesian_adjacent_iterate_end;
       swamps++;
     }
@@ -286,33 +491,20 @@
 static void make_deserts(void)
 {
   int x,y,i,j;
-  i=map.deserts;
-  j=0;
+  i = map.deserts;
+  j = 0;
   while (i > 0 && j < 100 * map.deserts) {
     j++;
 
-    if (has_poles) {
-      /* Choose a random coordinate between 20 and 30 degrees north/south
-       * (deserts tend to be between 15 and 35; make_desert will expand
-       * them). */
-      int xn = myrand(map.xsize);
-      int yn = myrand(map.ysize * 10 / 180) + map.ysize * 60 / 180;
-
-      if (myrand(2) != 0) {
-       yn = map.ysize - 1 - yn;
-      }
-      native_to_map_pos(&x, &y, xn, yn);
-    } else {
-      /* If there are no poles we can pick any location to be a desert. */
-      rand_map_pos(&x, &y);
-    }
-
-    /* If it's a grassland square call make_desert here.  We loop repeatedly
-     * since we may not always find grassland. */
-    if (map_get_terrain(x, y)==T_GRASSLAND) {
-      make_desert(x,y, hmap(x, y), 50);
+    /* 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,
+                  T_GRASSLAND)){
+      make_desert(x,y, hmap(x, y), 50, map_temperature(x, y));
       i--;
-    }
+    } else { break; }
   }
 }
 
@@ -561,8 +753,12 @@
            x, y);
 
     /* Test if the river is done. */
-    if (adjacent_river_tiles4(x, y) != 0||
-       adjacent_ocean_tiles4(x, y) != 0) {
+    if (adjacent_river_tiles4(x, y) != 0 ||
+       adjacent_ocean_tiles4(x, y) != 0 ||
+                                   /*rivers end at poles */
+        (map_get_terrain(x, y) == T_ARCTIC 
+         && map_temperature(x, y) < 8 * MAX_TEMP / 100)) { 
+                
       freelog(LOG_DEBUG,
              "The river ended at (%d, %d).\n", x, y);
       return TRUE;
@@ -678,7 +874,7 @@
      * 1000 rather than the current 100 */
     10 *
     /* The size of the map (poles don't count). */
-    (map_num_tiles() - 2 * map.xsize) *
+    map_num_tiles() * (map.alltemperate ? 1.0 : 0.90) *
     /* Rivers need to be on land only. */
     map.landpercent /
     /* Adjustment value. Tested by me. Gives no rivers with 'set
@@ -798,41 +994,6 @@
       map_set_terrain(x, y, T_PLAINS);
   } whole_map_iterate_end;
 }
-
-/**************************************************************************
-  we want the map to be sailable east-west at least at north and south pole 
-  and make it a bit jagged at the edge as well.
-  So this procedure converts the second line and the second last line to
-  ocean, and 50% of the 3rd and 3rd last line to ocean. 
-**************************************************************************/
-static void make_passable(void)
-{
-  int x;
-  
-  for (x=0;x<map.xsize;x++) {
-    nat_set_terrain(x, 2, T_OCEAN);
-
-    /* Iso-maps need two lines of ocean. */
-    if (myrand(2) != 0 || topo_has_flag(TF_ISO)) {
-      nat_set_terrain(x, 1, T_OCEAN);
-    }
-
-    if (myrand(2) != 0) {
-      nat_set_terrain(x, 3, T_OCEAN);
-    }
-
-    nat_set_terrain(x, map.ysize - 3, T_OCEAN);
-
-    if (myrand(2) != 0 || topo_has_flag(TF_ISO)) {
-      nat_set_terrain(x, map.ysize - 2, T_OCEAN);
-    }
-    if (myrand(2) != 0) {
-      nat_set_terrain(x, map.ysize - 4, T_OCEAN);
-    }
-  } 
-  
-}
-
 /****************************************************************************
   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
@@ -901,17 +1062,15 @@
       tres*=9;
     tres/=10;
   } while (abs(total-count)> maxval/40);
-  if (map.separatepoles && has_poles) {
-    make_passable();
-  }
+  make_polar(map.separatepoles); /* make extra land at poles, add texture
+                                   if separated else make base land*/
   make_mountains(maxval*8/10);
+  make_arctic();
+  make_tundra();
   make_forests();
   make_swamps();
   make_deserts();
   make_plains();
-  if (has_poles) {
-    make_polar();
-  }
   make_fair();
   make_rivers();
 }
@@ -975,8 +1134,6 @@
 
 /**************************************************************************
  Assign continent numbers to all tiles.
- Numbers 1 and 2 are reserved for polar continents if
- map.generator != 0; otherwise are not special.
  Also sets map.num_continents (note 0 is ocean, and continents
  have numbers 1 to map.num_continents _inclusive_).
  Note this is not used by generators 2,3 or 4 at map creation
@@ -984,34 +1141,20 @@
 **************************************************************************/
 void assign_continent_numbers(void)
 {
-  int isle = 1;
-
+  map.num_continents = 0;
   whole_map_iterate(x, y) {
     map_set_continent(x, y, 0);
   } whole_map_iterate_end;
 
-  if (map.generator != 0 && has_poles) {
-    do_in_map_pos(x, y, 0, 0) {
-      assign_continent_flood(x, y, 1);
-    } do_in_map_pos_end;
-
-    do_in_map_pos(x, y, 0, map.ysize - 1) {
-      assign_continent_flood(x, y, 2);
-    } do_in_map_pos_end;
-    isle = 3;
-  }
-      
   whole_map_iterate(x, y) {
     if (map_get_continent(x, y) == 0 
         && !is_ocean(map_get_terrain(x, y))) {
-      assign_continent_flood(x, y, isle++);
+      assign_continent_flood(x, y, ++map.num_continents);
     }
   } whole_map_iterate_end;
-  map.num_continents = isle-1;
 
   freelog(LOG_VERBOSE, "Map has %d continents", map.num_continents);
 }
-
 /****************************************************************************
   Return an approximation of the goodness of a tile to a civilization.
 ****************************************************************************/
@@ -1060,20 +1203,13 @@
 static void setup_isledata(void)
 {
   int starters = 0;
-  int min, firstcont, i;
+  int min,  i;
   
   assert(map.num_continents > 0);
   
   /* allocate + 1 so can use continent number as index */
   islands = fc_calloc((map.num_continents + 1), sizeof(struct isledata));
-  
-  /* the arctic and the antarctic are continents 1 and 2 for generator > 0 */
-  if (map.generator > 0 && map.separatepoles && has_poles) {
-    firstcont = 3;
-  } else {
-    firstcont = 1;
-  }
-  
+
   /* add up all the resources of the map */
   whole_map_iterate(x, y) {
     /* number of different continents seen from (x,y) */
@@ -1087,8 +1223,9 @@
     map_city_radius_iterate(x, y, x1, y1) {
       /* (x1,y1) is possible location of a future city which will
        * be able to get benefit of the tile (x,y) */
-      if (map_get_continent(x1, y1) < firstcont) { 
-        /* (x1, y1) belongs to a non-startable continent */
+      if (map_get_continent(x1, y1) < 1 
+         || map_temperature(x1, y1) <= 2 * ICE_BASE_LEVEL) { 
+        /* (x1, y1) too cold*/
         continue;
       }
       for (j = 0; j < seen_conts; j++) {
@@ -1118,7 +1255,7 @@
   /* set minimum number of resources per starting position to be value of
    * the best continent */
   min = 0;
-  for (i = firstcont; i < map.num_continents + 1; i++) {
+  for (i = 1; i < map.num_continents + 1; i++) {
     if (min < islands[i].goodies) {
       min = islands[i].goodies;
     }
@@ -1130,7 +1267,7 @@
     int nextmin = 0;
     
     starters = 0;
-    for (i = firstcont; i <= map.num_continents; i++) {
+    for (i = 1; i <= map.num_continents; i++) {
       int value = islands[i].goodies;
       
       starters += value / min;
@@ -1159,7 +1296,7 @@
             "Please report this bug at " WEBSITE_URL);
     abort();
   } else {
-    for (i = firstcont; i <= map.num_continents; i++) {
+    for (i = 1; i <= map.num_continents; i++) {
       islands[i].starters = islands[i].goodies / min;
     }
   }
@@ -1294,13 +1431,6 @@
 
   mysrand(map.seed);
 
-  /* FIXME: currently the lack of poles is hard-coded for maps that wrap
-   * north-south.  In the future this could be a server option.  It also
-   * needs to control the temperature gradient between "poles" and
-   * "equator"; e.g., if there are no poles desert and tundra should be
-   * equally likely at either end. */
-  has_poles = !topo_has_flag(TF_WRAPY);
-
   /* don't generate tiles with mapgen==0 as we've loaded them from file */
   /* also, don't delete (the handcrafted!) tiny islands in a scenario */
   if (map.generator != 0) {
@@ -1364,6 +1494,10 @@
 {
   whole_map_iterate(x, y) {
     hmap(x, y) -= minval;
+    
+    if(near_singularity(x, y)) {
+      hmap(x, y) = 0;
+    }
   } whole_map_iterate_end;
 }
 
@@ -1374,6 +1508,7 @@
 {
   int i;
   int minval=5000000;
+  
   height_map=fc_malloc (sizeof(int)*map.xsize*map.ysize);
 
   whole_map_iterate(x, y) {
@@ -1384,7 +1519,17 @@
     int x, y;
 
     rand_map_pos(&x, &y);
-    hmap(x, y) += myrand(5000);
+    if(near_singularity(x, y) /* avoid land in singularities */
+       || (map.separatepoles 
+          && map_temperature(x, y) <= 2.5 * ICE_BASE_LEVEL)
+       /* separate poles */
+       || map_temperature(x, y) <=  ICE_BASE_LEVEL
+       /* avoid to much land at poles */
+       ) { 
+      hmap(x, y) -= myrand(5000);
+    } else { 
+      hmap(x, y) += myrand(5000);
+    }
     if ((i % 100) == 0) {
       smooth_map(); 
     }
@@ -1484,21 +1629,20 @@
 **************************************************************************/
 static void make_huts(int number)
 {
-  int x,y,l;
+  int x,y;
   int count=0;
-  while (number * map_num_tiles() >= 2000 && count++ < map_num_tiles() * 2) {
-    rand_map_pos(&x, &y);
-    l=myrand(6);
-    if (!is_ocean(map_get_terrain(x, y)) && 
-       ( map_get_terrain(x, y)!=T_ARCTIC || l<3 )
-       ) {
-      if (!is_hut_close(x,y)) {
+  while (number * map_num_tiles() >= 2000 && count++ < map_num_tiles() * 2) { 
+    if( rand_map_pos_temperature(&x, &y,
+                                2 * ICE_BASE_LEVEL, MAX_TEMP,
+                                T_ANY)
+       /* no hut in poles */
+       && !is_ocean(map_get_terrain(x, y) )/* not hut in oceans ! */
+       && !is_hut_close(x,y)) {
        number--;
        map_set_special(x, y, S_HUT);
        /* Don't add to islands[].goodies because islands[] not
           setup at this point, except for generator>1, but they
           have pre-set starters anyway. */
-      }
     }
   }
 }
@@ -1523,32 +1667,36 @@
   Add specials to the map with given probability.
 ****************************************************************************/
 static void add_specials(int prob)
-{
-  int xn, yn;
-  int ymin = has_poles ? 1 : 0, ymax = has_poles ? map.ysize - 1 : map.ysize;
+{ 
   enum tile_terrain_type ttype;
 
-  for (yn = ymin; yn < ymax; yn++) {
-    for (xn = 0; xn < map.xsize; xn++) {
-      do_in_map_pos(x, y, xn, yn) {
-       ttype = map_get_terrain(x, y);
-       if ((is_ocean(ttype) && near_safe_tiles(x,y)) 
-           || !is_ocean(ttype)) {
-         if (myrand(1000) < prob) {
-           if (!is_special_close(x, y)) {
-             if (tile_types[ttype].special_1_name[0] != '\0'
-                 && (tile_types[ttype].special_2_name[0] == '\0'
-                     || (myrand(100) < 50))) {
-               map_set_special(x, y, S_SPECIAL_1);
-             } else if (tile_types[ttype].special_2_name[0] != '\0') {
-               map_set_special(x, y, S_SPECIAL_2);
-             }
-           }
-         }
-       }
-      } do_in_map_pos_end;
+  whole_map_iterate(x, y)  {
+    ttype = map_get_terrain(x, y);
+    if ( !is_ocean(ttype) && !is_special_close(x, y) 
+       && myrand(1000) < prob ) {
+      if (tile_types[ttype].special_1_name[0] != '\0'
+         && (tile_types[ttype].special_2_name[0] == '\0'
+             || (myrand(100) < 50))) {
+       map_set_special(x, y, S_SPECIAL_1);
+      } else if (tile_types[ttype].special_2_name[0] != '\0') {
+       map_set_special(x, y, S_SPECIAL_2);
+      }
+    } 
+    /* we place spetials only very near land, then we make a litle more */
+    else if(is_ocean(ttype) && near_safe_tiles(x,y) 
+           && myrand(750) < prob && !is_special_close(x, y))
+    { /* in sea there are more wales near poles */
+      if (tile_types[ttype].special_1_name[0] != '\0'
+         && (tile_types[ttype].special_2_name[0] == '\0'
+             || (myrand(15 * MAX_TEMP / 10) 
+                 < 6 * MAX_TEMP / 10 +  map_temperature(x, y)))) {
+        map_set_special(x, y, S_SPECIAL_1);
+      } else if (tile_types[ttype].special_2_name[0] != '\0') {
+       map_set_special(x, y, S_SPECIAL_2);
+      }
     }
-  }
+  } whole_map_iterate_end;
+  
   map.have_specials = TRUE;
 }
 
@@ -1561,15 +1709,8 @@
 };
 
 static bool map_pos_is_cold(int x, int y)
-{
-  int xn, yn;
-
-  if (!has_poles) {
-    return FALSE;
-  }
-
-  map_to_native_pos(&xn, &yn, x, y);
-  return (yn * 5 < map.ysize || (map.ysize - 1 - yn) * 5 > map.ysize);
+{  
+  return map_temperature(x, y) <= 2 * MAX_TEMP/ 10;
 }
 
 /**************************************************************************
@@ -1829,7 +1970,8 @@
   while (i > 0 && tries-->0) {
     get_random_map_position_from_state(&x, &y, pstate);
     map_to_native_pos(&xn, &yn, x, y);
-    if (hmap(x, y) == 0 && count_card_adjc_elevated_tiles(x, y) > 0) {
+    if ((!near_singularity(x, y) || myrand(50) < 25 ) 
+      && hmap(x, y) == 0 && count_card_adjc_elevated_tiles(x, y) > 0) {
       hmap(x, y) = 1;
       i--;
       if (yn >= pstate->s - 1 && pstate->s < map.ysize - 2) {
@@ -1999,8 +2141,6 @@
 **************************************************************************/
 static void initworld(struct gen234_state *pstate)
 {
-  int xn;
-  
   height_map = fc_malloc(sizeof(int) * map.ysize * map.xsize);
   islands = fc_malloc((MAP_NCONT+1)*sizeof(struct isledata));
 
@@ -2010,32 +2150,9 @@
     map_clear_all_specials(x, y);
     map_set_owner(x, y, NULL);
   } whole_map_iterate_end;
-  if (has_poles) {
-    for (xn = 0; xn < map.xsize; xn++) {
-      do_in_map_pos(x, y, xn, 0) {
-       map_set_terrain(x, y, myrand(9) > 0 ? T_ARCTIC : T_TUNDRA);
-       map_set_continent(x, y, 1);
-      } do_in_map_pos_end;
-      if (myrand(9) == 0) {
-       do_in_map_pos(x, y, xn, 1) {
-         map_set_terrain(x, y, myrand(9) > 0 ? T_TUNDRA : T_ARCTIC);
-         map_set_continent(x, y, 1);
-       } do_in_map_pos_end;
-      }
-      do_in_map_pos(x, y, xn, map.ysize - 1) {
-       map_set_terrain(x, y, myrand(9) > 0 ? T_ARCTIC : T_TUNDRA);
-       map_set_continent(x, y, 2);
-      } do_in_map_pos_end;
-      if (myrand(9) == 0) {
-       do_in_map_pos(x, y, xn, map.ysize - 2) {
-         map_set_terrain(x, y, myrand(9) > 0 ? T_TUNDRA : T_ARCTIC);
-         map_set_continent(x, y, 2);
-       } do_in_map_pos_end;
-      }
-    }
-    map.num_continents = 2;
-  } else {
-    map.num_continents = 0;
+  if (!map.alltemperate) {
+    make_polar(TRUE);
+    assign_continent_numbers(); /* set poles numbers */
   }
   make_island(0, 0, pstate, 0);
   islands[2].starters = 0;
@@ -2315,29 +2432,31 @@
 
   /* set midpoints of sides to avg of side's vertices plus a random factor */
   /* unset points are zero, don't reset if set */
-  if (hnat((x0 + x1) / 2, y0) == 0) {
-    hnat((x0 + x1) / 2, y0)
-      = (val[0][0] + val[1][0]) / 2 + myrand(step) - step / 2;
-  }
-  if (hnat((x0 + x1) /2, y1wrap) == 0) {
-    hnat((x0 + x1) / 2, y1wrap)
-      = (val[0][1] + val[1][1]) / 2 + myrand(step) - step / 2;
-  }
-  if (hnat(x0, (y0 + y1) / 2) == 0) {
-    hnat(x0, (y0 + y1) / 2)
-      = (val[0][0] + val[0][1]) / 2 + myrand(step) - step / 2;
-  }
-  if (hnat(x1wrap, (y0 + y1) / 2) == 0) {
-    hnat(x1wrap, (y0 + y1) / 2)
-      = (val[1][0] + val[1][1]) / 2 + myrand(step) - step / 2;
-  }
+#define set_midpoints(X,Y,V)                                              \
+  do_in_map_pos(map_x, map_y, (X), (Y)) {                               \
+    if( !near_singularity( map_x, map_y) &&  \
+     (!map.separatepoles \
+      || map_temperature(map_x, map_y) > 2.5 * ICE_BASE_LEVEL) \
+       && map_temperature(map_x, map_y) >  ICE_BASE_LEVEL                 \
+        && hnat((X), (Y)) == 0 ) {       \
+      hnat((X), (Y)) = V; }                                               \
+  } do_in_map_pos_end;
+
+  set_midpoints((x0 + x1)/2, y0,
+               (val[0][0] + val[1][0])/2 + myrand(step) - step/2);
+  set_midpoints((x0 + x1)/2,  y1wrap,
+               (val[0][1] + val[1][1])/2 + myrand(step) - step/2);
+  set_midpoints(x0,  (y0 + y1)/2,
+               (val[0][0] + val[0][1])/2 + myrand(step) - step/2);  
+  set_midpoints(x1wrap,  (y0 + y1)/2,
+               (val[1][0] + val[1][1])/2 + myrand(step) - step/2);  
+
 
   /* set middle to average of midpoints plus a random factor, if not set */
-  if (hnat((x0 + x1) / 2, (y0 + y1) / 2) == 0) {
-    hnat((x0 + x1) / 2, (y0 + y1) / 2)
-      = (val[0][0] + val[0][1] + val[1][0] + val[1][1]) / 4
-        + myrand(step) - step / 2;
-  }
+   set_midpoints((x0 + x1)/2, (y0 + y1)/2,
+      (val[0][0] + val[0][1] + val[1][0] 
+       + val[1][1])/4 + myrand(step) - step/2);
+ 
 
   /* now call recursively on the four subrectangles */
   gen5rec(2 * step / 3, x0, y0, (x1 + x0) / 2, (y1 + y0) / 2);
@@ -2375,6 +2494,7 @@
   int xmax = map.xsize - (xnowrap ? 1 : 0);
   int ymax = map.ysize - (ynowrap ? 1 : 0);
   int xn, yn, minval;
+
   /* just need something > log(max(xsize, ysize)) for the recursion */
   int step = map.xsize + map.ysize; 
   /* edges are avoided more strongly as this increases */
@@ -2390,36 +2510,21 @@
   /* set initial points */
   for (xn = 0; xn < xdiv2; xn++) {
     for (yn = 0; yn < ydiv2; yn++) {
-      hnat(xn * xmax / xdiv, yn * ymax / ydiv)
-       =  myrand(2 * step) - (2 * step) / 2;
-    }
-  }
-
-  /* if we aren't wrapping stay away from edges to some extent, try
-     even harder to avoid the edges naturally if separatepoles is true */
-  if (xnowrap) {
-    for (yn = 0; yn < ydiv2; yn++) {
-      hnat(0, yn * ymax / ydiv) -= avoidedge;
-      hnat(xmax, yn * ymax / ydiv) -= avoidedge;
-      if (map.separatepoles && has_poles) {
-       hnat(2, yn * ymax / ydiv)
-         = hnat(0, yn * ymax / ydiv) - myrand(3*avoidedge);
-       hnat(xmax - 2, yn * ymax / ydiv) 
-         = hnat(xmax, yn * ymax / ydiv) - myrand(3 * avoidedge);
-      }
-    }
-  }
-
-  if (ynowrap) {
-    for (xn = 0; xn < xdiv2; xn++) {
-      hnat(xn * xmax / xdiv, 0) -= avoidedge;
-      hnat(xn * xmax / xdiv, ymax) -= avoidedge;
-      if (map.separatepoles && has_poles) {
-       hnat(xn * xmax / xdiv, 2)
-         = hnat(xn * xmax / xdiv, 0) - myrand(3 * avoidedge);
-       hnat(xn * xmax / xdiv, ymax - 2) 
-         = hnat(xn * xmax / xdiv, ymax) - myrand(3 * avoidedge);
-      }
+      do_in_map_pos(x, y, (xn * xmax / xdiv), (yn * ymax / ydiv)) {
+       /* set initial points */
+       hmap(x, y) =
+           myrand(2 * step) - (2 * step) / 2;
+       /* avoid edges (simplest topologicals singularities) */
+       if (near_singularity(x, y) )
+         hmap(x, y ) -= avoidedge;
+        /* separate poles || avoid too mach land at poles */
+       if ((map.separatepoles  
+            && map_temperature(x, y) <= 2 * ICE_BASE_LEVEL)
+           || map_temperature(x,  y) <= ICE_BASE_LEVEL 
+           ) {
+         hmap(x, y) -= myrand(4 * avoidedge);
+       }
+      } do_in_map_pos_end;
     }
   }
 
diff -ruN -Xfreeciv/diff_ignore freeciv/server/mapgen.h freeciv_/server/mapgen.h
--- freeciv/server/mapgen.h     2003-08-28 17:54:11.000000000 +0200
+++ freeciv_/server/mapgen.h    2004-05-27 19:22:46.000000000 +0200
@@ -17,4 +17,7 @@
 void map_fractal_generate(void);
 void create_start_positions(void);
 
+/* this is the maximal temperature at equators returned by map_temperature */
+#define MAX_TEMP 1000
+
 #endif  /* FC__MAPGEN_H */
diff -ruN -Xfreeciv/diff_ignore freeciv/server/stdinhand.c 
freeciv_/server/stdinhand.c
--- freeciv/server/stdinhand.c  2004-05-27 12:55:39.000000000 +0200
+++ freeciv_/server/stdinhand.c 2004-05-27 19:24:41.000000000 +0200
@@ -312,6 +312,12 @@
              "be separate"), NULL, 
           MAP_DEFAULT_SEPARATE_POLES)
 
+  GEN_BOOL("alltemperate", map.alltemperate, SSET_MAP_GEN, SSET_GEOLOGY,
+           SSET_TO_CLIENT,
+          N_("All the map is temperate, no poles"),
+          N_("0 = normal Earth like planet; 1 = all temperate planet "), NULL, 
+          MAP_DEFAULT_ALLTEMPERATE)
+
   GEN_INT("landmass", map.landpercent, SSET_MAP_GEN, SSET_GEOLOGY,
           SSET_TO_CLIENT,
          N_("Amount of land vs ocean"), "", NULL,

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