diff -ur freeciv-1.14.0/common/map.h freeciv-1.14.0-stat/common/map.h
--- freeciv-1.14.0/common/map.h	Fri Oct 11 16:35:13 2002
+++ freeciv-1.14.0-stat/common/map.h	Wed Mar 26 01:50:50 2003
@@ -573,15 +573,15 @@
 #define MAP_MIN_HUTS             0
 #define MAP_MAX_HUTS             500
 
-#define MAP_DEFAULT_WIDTH        80
-#define MAP_MIN_WIDTH            40
-#define MAP_MAX_WIDTH            200
-
-#define MAP_DEFAULT_HEIGHT       50
-#define MAP_MIN_HEIGHT           25
-#define MAP_MAX_HEIGHT           100
+#define MAP_DEFAULT_WIDTH        40
+#define MAP_MIN_WIDTH            20
+#define MAP_MAX_WIDTH            255
+
+#define MAP_DEFAULT_HEIGHT       32
+#define MAP_MIN_HEIGHT           16
+#define MAP_MAX_HEIGHT           255
 
-#define MAP_DEFAULT_SEED         0
+#define MAP_DEFAULT_SEED         1
 #define MAP_MIN_SEED             0
 #define MAP_MAX_SEED             (MAX_UINT32 >> 1)
 
@@ -619,7 +619,7 @@
 
 #define MAP_DEFAULT_GENERATOR    1
 #define MAP_MIN_GENERATOR        1
-#define MAP_MAX_GENERATOR        5
+#define MAP_MAX_GENERATOR        7
 
 #define MAP_DEFAULT_TINYISLES    FALSE
 #define MAP_MIN_TINYISLES        FALSE
diff -ur freeciv-1.14.0/server/mapgen.c freeciv-1.14.0-stat/server/mapgen.c
--- freeciv-1.14.0/server/mapgen.c	Fri Oct 11 16:35:50 2002
+++ freeciv-1.14.0-stat/server/mapgen.c	Wed Mar 26 01:44:35 2003
@@ -19,6 +19,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <math.h> /* For the plate tectonic simulator */
 
 #include "fcintl.h"
 #include "game.h"
@@ -41,6 +42,8 @@
 static void mapgenerator3(void);
 static void mapgenerator4(void);
 static void mapgenerator5(void);
+static void mapgenerator6(void);
+static void mapgenerator_tectonic(void);
 static void smooth_map(void);
 static void adjust_map(int minval);
 
@@ -258,13 +261,23 @@
   while (i > 0 && j < 500) {
     j++;
 
-    y=myrand(map.ysize*10/180)+map.ysize*110/180;
+    if(map.ysize >= 18) {
+        y=myrand(map.ysize*10/180)+map.ysize*110/180;
+        }
+    else {
+        y = map.ysize*110/180;
+	}
     x=myrand(map.xsize);
     if (map_get_terrain(x, y)==T_GRASSLAND) {
       make_desert(x,y, hmap(x, y), 50);
       i--;
     }
-    y=myrand(map.ysize*10/180)+map.ysize*60/180;
+    if(map.ysize >= 18) {
+        y=myrand(map.ysize*10/180)+map.ysize*60/180;
+        }
+    else {
+        y = map.ysize*60/180;
+	}
     x=myrand(map.xsize);
     if (map_get_terrain(x, y)==T_GRASSLAND) {
       make_desert(x,y, hmap(x, y), 50);
@@ -823,7 +836,7 @@
   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)
+static void make_land(int window_size)
 {
   int tres=(maxval*map.landpercent)/100;
   int count=0;
@@ -846,7 +859,7 @@
     else
       tres*=9;
     tres/=10;
-  } while (abs(total-count)> maxval/40);
+  } while (abs(total-count)> window_size/40);
   if (map.separatepoles) {
     make_passable();
   }
@@ -941,8 +954,9 @@
  Allocate islands array and fill in values.
  Note this is only use for map.generator<=1, since others
  setups islands and starters explicitly.
+ Output: The number of good islands that this map has
 **************************************************************************/
-static void setup_isledata(void)
+int setup_isledata(void)
 {
   int x;
   int good, mingood, maxgood;
@@ -1104,6 +1118,28 @@
   }
   freelog(LOG_DEBUG, "The map has %i starting positions on %i isles.",
 	  starters, goodisles);
+  return goodisles;
+}
+
+/**************************************************************************
+ Comparison function that compares the goodness of two start points (how
+ good the island the two start points are on
+ *************************************************************************/
+
+static int compar_isle_goodness(const void *a,const void *b) 
+{
+   int ia, ib;
+   int x,y;
+   struct map_position *t;
+   t = (struct map_position *)a;
+   x=t->x;
+   y=t->y;
+   ia = islands[(int)map_get_continent(x, y)].goodies;
+   t = (struct map_position *)b;
+   x=t->x;
+   y=t->y;
+   ib = islands[(int)map_get_continent(x, y)].goodies;
+   return ib - ia;
 }
 
 /**************************************************************************
@@ -1113,23 +1149,106 @@
   FIXME: MAXTRIES used to be 1.000.000, but has been raised to 10.000.000
          because a set of values hit the limit. At some point we want to
          make a better solution.
+  Output: Whether this is a good map; 1 if yes, 0 if no
 **************************************************************************/
 #define MAXTRIES 10000000
-void create_start_positions(void)
+int create_start_positions(void)
 {
   int nr=0;
   int dist=40;
-  int x, y, j=0, k, sum;
+  int x, y, i, j=0, k, sum;
   int counter = 0;
+  int isles;
+  int xz, yz, pxz;
+
+  isles = 10000; /* Big number so this passes the "own island" test */
 
   if (!islands)		/* already setup for generators 2,3, and 4 */
-    setup_isledata();
+    isles = setup_isledata();
+
+  /*if(map.seed == 8675309 && map.xsize == 40 && map.ysize == 32 &&
+     map.generator == 1) { isles = 10000;
+     } *//* Cristalia */
+
+  yz = map.ysize - 2;
+  xz = pxz = map.xsize;
+
+  for(x=0;x<map.xsize;x++) {
+       for(y=1;y<map.ysize - 1;y++) {
+           if(map_get_terrain(x, y) != T_OCEAN) {
+               xz--;
+               break;
+               }
+           }
+       }
+
+  for(x=0;x<map.xsize;x++) {
+       for(y=2;y<map.ysize - 2;y++) {
+           if(map_get_terrain(x, y) != T_OCEAN) {
+               pxz--;
+               break;
+               }
+           }
+       }
+
+  for(y=0;y<map.ysize;y++) {
+       for(x=0;x<map.ysize;x++) {
+           if(map_get_terrain(x, y) != T_OCEAN) {
+               yz--;
+               break;
+               }
+           }
+       }
+
+  printf("seed: %d islands: %d good: %d xz: %d pxz: %d yz: %d ",map.seed,
+         map.num_continents,isles,xz,pxz,yz);
+  fflush(stdout);
+
+  for(i=1; i<=map.num_continents; i++) {
+      printf("(%d %d) ",i,islands[i].goodies);
+      }
+  printf("\n");
+
+  isles = 0; /* Just running stats */
+
+  if(isles < game.nplayers) { /* Each player gets their own island */
+      /*if(map.seed % 100 == 0) { printf("Trying map %d\n",map.seed); }*/
+      if(map.generator > 6) {
+          Tec_Cleanup();
+	  }
+      map.seed++; 
+      free(islands);
+      free(height_map);
+      free(river_map);
+      islands = NULL;
+      height_map = NULL;
+      river_map = NULL;
+      maxval = 0;
+      forests = 0;
+      free(map.tiles);
+      map.tiles = NULL;
+      map.num_continents = 0;
+      map.num_start_positions = 0;
+      map.have_specials = FALSE;
+      map.have_huts = FALSE;
+      /* Initializing the next two may not be necessary */
+      map.fixed_start_positions = FALSE;
+      map.have_rivers_overlay = FALSE;
+      return 0;
+      }
+
+  printf("Using seed %d\n",map.seed);
 
   if(dist>= map.xsize/2)
     dist= map.xsize/2;
   if(dist>= map.ysize/2)
     dist= map.ysize/2;
 
+  /* If we make distance really big here (and do the check to make sure each
+     player gets their own island), we can 100% ensure that each player
+     gets their own island; dist is the minimum distance that two players
+     can be from one another on the same island */
+
   sum=0;
   for (k=0; k<=map.num_continents; k++) {
     sum += islands[k].starters;
@@ -1167,8 +1286,19 @@
   }
   map.num_start_positions = game.nplayers;
 
+  /* Sort the array so that the lowered numbered starting positions are
+     always on the best isles; this is used in conjunction with code in
+     gamehand.c to make sure that the humans get the best islands; the
+     code works best when each player gets their own island (otherwise
+     all of the humans will share the best islands and all of the AIs will
+     share the worse islands) */
+
+  qsort(map.start_positions,map.num_start_positions,
+        sizeof(struct map_position),compar_isle_goodness);
+
   free(islands);
   islands = NULL;
+  return 1; /* Good map */
 }
 
 /**************************************************************************
@@ -1196,6 +1326,10 @@
     map_allocate();
     /* if one mapgenerator fails, it will choose another mapgenerator */
     /* with a lower number to try again */
+    if (map.generator == 6 )
+      mapgenerator6();
+    if (map.generator == 7 || map.generator == 8)
+      mapgenerator_tectonic();
     if (map.generator == 5 )
       mapgenerator5();
     if (map.generator == 4 )
@@ -1245,7 +1379,7 @@
   /*!PS: I don't have the time to have several test runs */
   /* to find a mapping from percents to generator 1 settings. */
 
-  if(map.generator==1){
+  if(map.generator==1 || map.generator==7){
     /*map.riverlength*= 10; */
     /*I leave this out, people will get too upset 
       if they have to change all their scripts */
@@ -1289,7 +1423,7 @@
 
 /**************************************************************************
   since the generated map will always have a positive number as minimum height
-  i reduce the height so the lowest height is zero, this makes calculations
+  reduce the height so the lowest height is zero, this makes calculations
   easier
 **************************************************************************/
 static void adjust_map(int minval)
@@ -1338,7 +1472,867 @@
   maxval-=minval;
   adjust_map(minval);
 
-  make_land();
+  make_land(maxval);
+  free(height_map);
+  height_map = NULL;
+}
+
+/**************************************************************************
+ The following code was written by Mark Isaak in 1988 and converted in to
+ a freeciv-compatible form 2003 by Sam Trenholme
+ *************************************************************************/
+
+/*
+ * A program to simulate tectonics.
+ *
+ * Copyright 1988 by Mark Isaak.
+ * Copyright 2003 Sam Trenholme; with Mark Isaak's permission, I have
+ * relicensed this under the GPL.
+ *
+ * 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.
+ *
+ *
+ * Wish list (from 1988):
+ *      Do it on a sphere, not a square torus (not wanted for FreeCiv)
+ *	Give plates angular momentum
+ *	Make some constants variable
+ *	Horsts and grabens
+ *	Let 2 plates fuse together and/or 1 plate split apart sometimes
+ *	Astroblemes
+ *	Take density of rock into account
+ */
+
+/*
+ * ---------- Structures -----------------------------------------------------
+ */
+
+/*
+ * ---------- Defined parameters ---------------------------------------------
+ *
+ * Some notes on Earth for comparison:
+ *   Mean elevation of land = 840 m.
+ *   Kilamanjaro = 5895 m.
+ *   Everest = 8848 m.
+ *   Dead Sea = -400 m.
+ *   Gread Rift Valley = -150 m.
+ *   Andes = 6950 m.
+ *   Marianas Trench = -11000 m.
+ *   Mean depth of sea = -3810 m.
+ */
+
+struct tectonic_data {
+
+  int   xsize; /* Size of map along x axis */
+  int   ysize; /* Size of map along y axis */
+  int   nplates;	/* # of plates in world at genesis */
+  int   maxplates;	/* maximum # of plates we can have */
+  int   ncontinents;	/* # of plates which are continental */
+  int   nhotspots;	/* # of hot spots */
+
+  int   landelev;	/* starting elevation of land */
+  int   oceanelev;	/* starting elevation of oceans */
+
+  int   epochmove;	/* max movement during one epoch */
+
+  float foldfactor;	/* how much to increase ht. of folds */
+  int   riftelev;	/* elevation for rifts */
+  int   subsumeheight; 	/* elevation change for coastal ranges */
+  int   trenchheight;	/* elev. change for trench by coastal range */
+  int   hotspotheight; 	/* average ht. growth of hot spots */
+
+  int   riftminerals; 	/* minerals in rifts */
+  int   subsumeminerals; 	/* minerals in costal ranges */
+  int   archipminerals; 	/* minerals in archipelagos */
+  int   hotspotminerals; 	/* minerals in underwater hot spots */
+ 
+  float erodefactor; 	/* how much of a height to erode */
+  float submergefactor; 	/* how being underwater slows erosion */
+  int   skyelev;		/* no erosion above this */
+  int   waveaction; 	/* erosion due entirely to waves */
+  int   subsidefactor; 	/* how fast ocean floor sinks */
+  int   basinelev; 	/* how far ocean floor can sink */
+
+};
+
+static struct tectonic_data tectonic;
+
+void init_tec_data() {
+  tectonic.xsize = map.xsize; /* Width of map */
+  tectonic.ysize = map.ysize; /* Height of map */
+
+  tectonic.nplates = 20; /* # of plates in world at genesis */
+  tectonic.maxplates = 27; /* maximum # of plates we can have */
+  tectonic.ncontinents = 5; /* # of plates which are continental */
+  tectonic.nhotspots = 10; /* # of hot spots */
+
+  tectonic.landelev = 800; /* starting elevation of land */
+  tectonic.oceanelev = -1000; /* starting elevation of oceans */
+
+  tectonic.epochmove = 5; /* max movement during one epoch */
+
+  tectonic.foldfactor = 1.2; /* how much to increase ht. of folds */
+  tectonic.riftelev = -400; /* elevation for rifts */
+  tectonic.subsumeheight = 1200; /* elevation change for coastal ranges */
+  tectonic.trenchheight = -500; /* elev. change for trench by coastal range */
+  tectonic.hotspotheight = 600; /* average ht. growth of hot spots */
+
+  tectonic.riftminerals = 7; /* minerals in rifts */
+  tectonic.subsumeminerals = 3; /* minerals in costal ranges */
+  tectonic.archipminerals = 5; /* minerals in archipelagos */
+  tectonic.hotspotminerals = 2; /* minerals in underwater hot spots */
+
+  tectonic.erodefactor = 0.023; /* how much of a height to erode */
+  tectonic.submergefactor = 0.2; /* how being underwater slows erosion */
+  tectonic.skyelev = 10000; /* no erosion above this */
+  tectonic.waveaction = 400; /* erosion due entirely to waves */
+  tectonic.subsidefactor = 0.05; /* how fast ocean floor sinks */
+  tectonic.basinelev = -9000; /* how far ocean floor can sink */
+  }
+
+/*
+ * Tectonic plate
+ */
+typedef struct {
+    float	xvec, yvec;	/* direction of plate movement */
+    short	dx, dy;		/* how far do move plate per age */
+    bool	continent;	/* whether initially continent or ocean */
+} Plate_t;
+
+/*
+ * Hot spot
+ */
+typedef struct {
+    short	x, y;		/* location of hot spot */
+    short	howhot;		/* how much it spews forth */
+} Hotspot_t;
+
+/*
+ * A piece of land which moves around
+ */
+typedef struct rock_s {
+    short	elev;		/* elevation */
+    short	elevchange;	/* change in elevation due to erosion */
+    Plate_t	*plate;		/* which plate it belongs to */
+    bool	moved;		/* whether we've moved this iteration */
+    long	minerals;	/* how many minerals */
+    struct rock_s *next;	/* next in linked list */
+} Rock_t;
+
+/*
+ * ---------- Global variables -----------------------------------------------
+ */
+Rock_t	*surface[1024][1024];	/* surface of planet */
+Plate_t	plates[1024];		/* descriptions of plates */
+Hotspot_t	hotspots[1024];	/* descriptions of hot spots */
+
+int	nplates;			/* # of tectonic plates */
+Rock_t	*freeRockList;			/* ptr to list of unused rocks */
+short	maxelev, minelev;		/* elevation extremes */
+
+/*
+ * ---------- Utilities ------------------------------------------------------
+ */
+/*
+ * Return a random number from 0 to n-1.
+ */
+  int
+Rnd(n)
+  int n;
+{
+    return myrand(n); /* Freeciv's RNG */
+}
+
+/*
+ * Wraparound from one side of the world to the other.
+ */
+  int
+Wrap_x(val)
+  register int val;	/* x coordinate */
+{
+    if (val < 0)
+        val += tectonic.xsize;
+    else if (val >= tectonic.xsize)
+        val -= tectonic.xsize;
+    return (val);
+}
+
+  int
+Wrap_y(val)
+  register int val;	/* y coordinate */
+{
+    if (val < 0)
+        val += tectonic.ysize;
+    else if (val >= tectonic.ysize)
+        val -= tectonic.ysize;
+    return (val);
+}
+
+/*
+ * Allocate a rock.
+ */
+  Rock_t *
+AllocRock(pl)
+  Plate_t	*pl;	/* which plate it goes on */
+{
+    Rock_t	*rp;	/* ptr to rock */
+
+    if (freeRockList) {
+        rp = freeRockList;
+        freeRockList = rp->next;
+    } else
+        rp = (Rock_t *)malloc(sizeof(Rock_t));
+    rp->plate = pl;
+    rp->elev = (pl->continent ? tectonic.landelev : tectonic.oceanelev);
+    rp->elevchange = 0;
+    rp->moved = FALSE;
+    rp->minerals = 0;
+    rp->next = NULL;
+    return (rp);
+}
+
+/*
+ * ---------- Initialization -------------------------------------------------
+ */
+
+/*
+ * Put plates at random spots on the planet.
+ * Make tectonic.ncontinents of them land, the rest ocean.
+ */
+int SeedPlates()
+{
+    register int i;
+    register Plate_t *pl;	/* ptr to plates */
+
+    pl = &plates[0];
+    for (i = 0; i < tectonic.nplates; ++i, ++pl) {
+        pl->dx = Rnd(tectonic.xsize);
+        pl->dy = Rnd(tectonic.ysize);
+        /*
+         * Check if this spot is already taken.
+         */
+        if (surface[pl->dx][pl->dy]) {
+            --pl;
+            --i;
+            continue;	/* try again */
+        }
+        surface[pl->dx][pl->dy] = (Rock_t *)pl;
+        pl->xvec = 0.0;
+        pl->yvec = 0.0;
+        pl->continent = (i < tectonic.ncontinents);
+    }
+    return 0;
+}
+
+/*
+ * Initialize the surface.  Allocate a rock for each spot on the surface
+ * and assign it to the nearest plate.
+ */
+int InitSurface()
+{
+    register short	dx, dy;		/* x, y distance */
+    register long	dist;		/* distance */
+    register short	x, y;		/* location on surface */
+    register Plate_t	*pl;		/* plate pointer */
+    register Plate_t	*bestpl;	/* closest plate */
+    register long	bestdist;	/* distance of closest plate */
+    register int	i;		/* plate counter */
+
+    bestpl = NULL;
+
+    for (x = 0; x < tectonic.xsize; ++x) {
+        for (y = 0; y < tectonic.ysize; ++y) {
+            bestdist = 2 * tectonic.xsize * tectonic.ysize;
+            for (pl = &plates[0], i = 0; i < tectonic.nplates; ++i, ++pl) {
+                dx = pl->dx - x;
+                if (dx < 0)
+                    dx = -dx;
+                if (dx > tectonic.xsize/2)
+                    dx = tectonic.xsize - dx;
+                dy = pl->dy - y;
+                if (dy < 0)
+                    dy = -dy;
+                if (dy > tectonic.ysize/2)
+                    dy = tectonic.ysize - dy;
+                dist = dx * dx + dy * dy;
+                if (dist < bestdist) {
+                    bestdist = dist;
+                    bestpl = pl;
+                }
+            }
+            surface[x][y] = AllocRock(bestpl);
+        }
+    }
+    return 0;
+}
+
+/*
+ * Place some hot spots randomly.
+ */
+int SeedHotSpots()
+{
+    register int	i;	/* hot spot counter */
+    register Hotspot_t	*hsp;	/* hot spot pointer */
+
+    for (hsp = &hotspots[0], i = 0; i < tectonic.nhotspots; ++i, ++hsp) {
+        hsp->x = Rnd(tectonic.xsize);
+        hsp->y = Rnd(tectonic.ysize);
+        hsp->howhot = (Rnd(tectonic.hotspotheight) + Rnd(tectonic.hotspotheight) +
+          Rnd(tectonic.hotspotheight) + Rnd(tectonic.hotspotheight) + 2) >> 1;
+    }
+    return 0;
+}
+
+/*
+ * All initialization.
+ */
+int Tec_Init()
+{
+    nplates = tectonic.nplates;
+    SeedPlates();
+    InitSurface();
+    SeedHotSpots();
+    return 0;
+}
+
+/* 
+ * Cleanup of memory allocated by tectonic code 
+ */
+
+int Tec_Cleanup()
+{
+    int x,y;
+    Rock_t *tofree,*tmp;
+
+    /* Start up with the freeRockList */
+    tofree = freeRockList;
+    while(tofree != NULL) {
+        tmp = tofree->next;
+        free(tofree);
+        tofree = tmp;
+	}
+    freeRockList = NULL;
+    for (x = 0; x < tectonic.xsize; ++x) {
+        for (y = 0; y < tectonic.ysize; ++y) {
+            tofree = surface[x][y];
+            while(tofree != NULL) {
+	        tmp = tofree->next;
+		free(tofree);
+		tofree = tmp;
+		}
+            surface[x][y] = NULL;
+            }
+       }
+    return 0;
+}
+
+/*
+ * ---------- Land movement --------------------------------------------------
+ */
+/*
+ * Assign each of the plates a direction and distance (velocity) to move.
+ * Velocity is added to previous value, but isn't allowed to exceed
+ * tectonic.epochmove in any direction.
+ */
+int AssignDirections()
+{
+    register int	i;	/* plate counter */
+    register Plate_t	*pl;	/* ptr to plates */
+    float		dist;	/* magnitude of vector */
+    register int	dir;	/* direction of vector */
+#define DEGtoRAD	(3.1415926 / 180.0)
+
+    for (pl = &plates[0], i = 0; i < nplates; ++i, ++pl) {
+        dir = Rnd(360);
+        dist = (float)(Rnd(101) + Rnd(101) + Rnd(101) - 150) *
+          (float)tectonic.epochmove/150.0;
+        pl->xvec += dist * cos(dir * DEGtoRAD);
+        pl->yvec += dist * sin(dir * DEGtoRAD);
+        if ((dist = hypot(pl->xvec, pl->yvec)) > (float)tectonic.epochmove) {
+            dist = (float)tectonic.epochmove / dist;
+            pl->xvec *= dist;
+            pl->yvec *= dist;
+        }
+    }
+    return 0;
+}
+
+/*
+ * Set plates' dx,dy to the vector given by (i+1)*v/tectonic.epochmove - i*v/tectonic.epochmove,
+ * where v = plate's (xvec,yvec) vector.  This arrangement makes the sum of
+ * (dx,dy) over an epoch equal to (xvec,yvec).
+ */
+int SetMovementVectors(iter)
+  int iter;	/* which iteration */
+{
+    register int	i;	/* plate counter */
+    register Plate_t	*pl;	/* ptr to plates */
+
+    for (pl = &plates[0], i = 0; i < nplates; ++i, ++pl) {
+        pl->dx = (short)((iter + 1) * pl->xvec / tectonic.epochmove) -
+          (short)(iter * pl->xvec / tectonic.epochmove);
+        pl->dy = (short)((iter + 1) * pl->yvec / tectonic.epochmove) -
+          (short)(iter * pl->yvec / tectonic.epochmove);
+    }
+    return 0;
+}
+
+/*
+ * Move each rock according to its plate's movement vector.
+ * Use the rock's 'next' field to keep track of rocks that pile up.
+ */
+int MovePlates()
+{
+    register int	x, y;		/* where in the world */
+    register int	newx, newy;	/* rock's new home */
+    register Rock_t	*rp;		/* rock pointer */
+    register Rock_t	*prevrp;	/* rock before rp */
+    register Rock_t	*nextrp;	/* rock after rp */
+
+    for (x = 0; x < tectonic.xsize; ++x) {
+        for (y = 0; y < tectonic.ysize; ++y) {
+            prevrp = NULL;
+            for (rp = surface[x][y]; rp; prevrp = rp, rp = nextrp) {
+                nextrp = rp->next;
+                if (rp->moved)
+                    continue;
+                /*
+                 * Figure out where to move rock.
+                 */
+                rp->moved = TRUE;
+                if ((rp->plate->dx == 0) && (rp->plate->dy == 0))
+                    continue;
+                newx = Wrap_x(x + rp->plate->dx);
+                newy = Wrap_y(y + rp->plate->dy);
+                /*
+                 * Move rock.
+                 */
+                if (prevrp == NULL)
+                    surface[x][y] = rp->next;
+                else
+                    prevrp->next = rp->next;
+                rp->next = surface[newx][newy];
+                surface[newx][newy] = rp;
+            }
+        }
+    }
+    return 0;
+}
+
+/*
+ * ---------- Mountain building and the like ---------------------------------
+ */
+
+/*
+ * Create land where plates have spread apart.
+ */
+int Rift(x, y)
+  int x, y;
+{
+    register Plate_t	*pl;	/* which plate new land goes with */
+    register int	px, py;	/* offset at which to look for plate */
+    register long	tries;	/* # of failures to find plate */
+    register Rock_t	*rp;	/* new rock */
+    Rock_t *tofree, *tmp; /* For freeing memory */
+
+    pl = NULL;
+
+    /*
+     * Find a plate to go with.
+     */
+    for (tries = 0; tries < 30; ++tries) {
+        px = Wrap_x(x + Rnd(3) - 1);
+        py = Wrap_y(y + Rnd(3) - 1);
+        if ((rp = surface[px][py]) != NULL) {
+            pl = rp->plate;
+            break;
+        }
+    }
+    /*
+     * Can't find a plate; start a new one.
+     */
+    if (pl == NULL) {
+        if (nplates < tectonic.maxplates)
+            ++nplates;
+        pl = &plates[nplates - 1];
+        pl->xvec = pl->yvec = 0.0;
+        pl->dx = pl->dy = 0;
+        pl->continent = FALSE;
+    }
+    /*
+     * Make rock.
+     */
+    rp = AllocRock(pl);
+    rp->elev = tectonic.riftelev;
+    rp->minerals = tectonic.riftminerals;	/* should distinguish between ocean and continental rifts!!! */
+    tofree = surface[x][y];
+    while(tofree != NULL) {
+        tmp = tofree->next;
+	free(tofree);
+	tofree = tmp;
+        }
+    surface[x][y] = rp;
+    return 0;
+}
+
+/*
+ * Raise (or lower) land near x,y by height.
+ * Determine direction from x,y by rp's plate's vector.
+ */
+int ElevNearby(x, y, rp, height)
+  int x, y;
+  Rock_t *rp;
+  short height;
+{
+    float	h;	/* hypotenuse of rp->plate->vec */
+    int		x2, y2;	/* rock to raise */
+
+    h = hypot(rp->plate->xvec, rp->plate->yvec);
+    if (h < 0.01) {
+        x2 = x;
+        y2 = y;
+    } else {
+        x2 = Wrap_x(x + (int)(rp->plate->xvec / h + 1.5) - 1);
+        y2 = Wrap_y(y + (int)(rp->plate->yvec / h + 1.5) - 1);
+    }
+    if (surface[x2][y2])
+        surface[x2][y2]->elev += height;
+    return 0;
+}
+
+/*
+ * Continent hits continent; mountains are pushed up.
+ * New height = taller + 0.5 * shorter.  The leftover height is
+ * distributed to other rocks in the area.
+ */
+int Fold(x, y)
+  int x, y;
+{
+    register Rock_t	*rp0;		/* first rock on list */
+    register Rock_t	*rp1;		/* short rock */
+    register Rock_t	*rp2;		/* tall rock */
+    register short	halfshort;	/* half the short elevation */
+
+    rp0 = surface[x][y];
+    if (rp0->next->elev > rp0->elev) {
+        rp1 = rp0;
+        rp2 = rp1->next;
+    } else {
+        rp2 = rp0;
+        rp1 = rp2->next;
+    }
+    halfshort = (rp1->elev >> 1) * tectonic.foldfactor;
+    ElevNearby(x, y, rp1, (halfshort + 1) >> 1);
+    ElevNearby(x, y, rp2, halfshort >> 1);
+    /*
+     * Combine rocks and free a rock structure.
+     */
+    rp0->elev = rp2->elev + halfshort;
+    rp0->minerals = (rp1->minerals + rp2->minerals + 1) >> 1;
+    rp0->plate = Rnd(2) ? rp1->plate : rp2->plate;
+
+    rp1 = rp0->next;
+    rp0->next = rp1->next;
+    rp1->next = freeRockList;
+    freeRockList = rp1;
+    return 0;
+}
+
+/*
+ * Create a costal range where oceanic plate is subsumed by continental
+ * plate.  Simply add a constant height and minerals to the continent.
+ */
+int Subsume(x, y)
+  int x, y;
+{
+    register Rock_t	*rp0;		/* first rock on list */
+    register Rock_t	*rp1;		/* underwater rock */
+    register Rock_t	*rp2;		/* higher rock */
+
+    rp0 = surface[x][y];
+    if (rp0->next->elev > rp0->elev) {
+        rp1 = rp0;
+        rp2 = rp1->next;
+    } else {
+        rp2 = rp0;
+        rp1 = rp2->next;
+    }
+    ElevNearby(x, y, rp2, tectonic.trenchheight);
+    if (rp2->elev < 0)
+        rp0->minerals = rp2->minerals + tectonic.archipminerals;
+    else
+        rp0->minerals = rp2->minerals + tectonic.subsumeminerals;
+    rp0->elev = rp2->elev + tectonic.subsumeheight;
+    rp0->plate = rp2->plate;
+
+    rp1 = rp0->next;
+    rp0->next = rp1->next;
+    rp1->next = freeRockList;
+    freeRockList = rp1;
+    return 0;
+}
+
+/*
+ * For each spot on the surface, combine rocks which were piled on top of
+ * each other in MovePlates() into mountains,
+ * and create rifts where plates have spread apart leaving nothing.
+ */
+int MountainBuild()
+{
+    register int	x, y;		/* where in the world */
+    register Rock_t	*rp;		/* rock pointer */
+    register Rock_t	*rp2;		/* another rock pointer */
+
+    for (x = 0; x < tectonic.xsize; ++x) {
+        for (y = 0; y < tectonic.ysize; ++y) {
+            rp = surface[x][y];
+            if (rp == NULL)
+                Rift(x, y);
+            else while ((rp2 = rp->next) != NULL) {
+                if ((rp->elev > 0) && (rp2->elev > 0))
+                    Fold(x, y);		/* land + land */
+                else
+                    Subsume(x, y);	/* land or ocean + ocean */
+            }
+        }
+    }
+    return 0;
+}
+
+/*
+ * Increase elevation of hot spots.  If underwater, increase minerals.
+ */
+int EruptHotSpots()
+{
+    register int	i;	/* hot spot counter */
+    register Hotspot_t	*hsp;	/* hot spot pointer */
+    register Rock_t	*rp;	/* rock pointer */
+
+    for (hsp = &hotspots[0], i = 0; i < tectonic.nhotspots; ++i, ++hsp) {
+        rp = surface[hsp->x][hsp->y];
+        if (rp->elev <= 0)
+            rp->minerals += tectonic.hotspotminerals;
+        rp->elev += hsp->howhot;
+    }
+    return 0;
+}
+
+/*
+ * Wear down mountains.  Amount of wear is proportional to the average
+ * difference in height between a rock and the surrounding rocks,
+ * except very tall mountains don't erode much (no weather),
+ * there's more erosion around seashores (waves), and underwater
+ * mountains don't erode much.
+ * Also lower sea floors.
+ * Mark everything unmoved.
+ */
+int Erode()
+{
+    register int	x, y;		/* where in the world */
+    register Rock_t	*rp0;		/* rock pointer */
+    register Rock_t	*rp1;		/* pointer to nearby rock */
+    register short	elev0, elev1;	/* elevation of rp0, rp1 */
+    register int	i, j;		/* indices to nearby rocks */
+    register short	diff;		/* difference in height, roughly */
+    register long	depth;		/* average height of area */
+    int			diffplates;	/* nearby rocks belonging to other plates */
+    int			deepplates;	/* # of nearby rocks under water */
+
+    rp1 = NULL;
+
+    for (x = 0; x < tectonic.xsize; ++x) {
+        for (y = 0; y < tectonic.ysize; ++y) {
+            rp0 = surface[x][y];
+            elev0 = rp0->elev;
+            depth = elev0;
+            if (elev0 < 0)
+                elev0 = elev0 * tectonic.submergefactor;
+            else if (elev0 > tectonic.skyelev)
+                elev0 = tectonic.skyelev;
+            diffplates = 0;
+            deepplates = 0;
+            for (i = -1; i <= 1; ++i) {
+                for (j = -1; j <= 1; ++j) {	/* for each surrounding rock */
+                    if ((i == 0) && (j == 0))
+                        continue;
+                    rp1 = surface[Wrap_x(x + i)][Wrap_y(y + j)];
+                    elev1 = rp1->elev;
+                    if (rp1->plate != rp0->plate)
+                        ++diffplates;
+                    depth += elev1;
+                    if (elev1 < 0) {
+                        ++deepplates;
+                        elev1 = elev1 * tectonic.submergefactor;
+                    } else if (elev1 > tectonic.skyelev)
+                        elev1 = tectonic.skyelev;
+                    /*
+                     * Erode according to diff between elev0, elev1.
+                     */
+                    diff = elev0 - elev1;
+                    if ((elev0 <= 0 && elev1 >= 0) ||
+                      (elev0 >= 0 && elev1 <= 0)) {
+                        diff += tectonic.waveaction;
+                    }
+                    diff = tectonic.erodefactor * diff + 0.5;
+                    rp0->elevchange -= diff;
+                    rp1->elevchange += diff;
+                }
+            }
+            /*
+             * If 7/8 of the rocks surrounding us belong to different
+             * plates, join the crowd.
+             */
+            if (diffplates >= 7) {
+                do {
+                    i = Rnd(3) - 2;
+                    j = Rnd(3) - 2;
+                    if (i == 0 && j == 0)
+                        continue;
+                    rp1 = surface[Wrap_x(x + i)][Wrap_y(y + j)];
+                } while (rp1->plate == rp0->plate);
+                rp0->plate = rp1->plate;
+            }
+            /*
+             * Compute subsidence of ocean basins.
+             */
+            if (deepplates >= (rp0->elev >= 0 ? 8 : 6)) {
+                rp0->elevchange -= tectonic.subsidefactor * (depth/9 - tectonic.basinelev);
+            }
+        }
+    }
+    /*
+     * Incorporate elevchange; mark things moved.
+     */
+    for (x = 0; x < tectonic.xsize; ++x) {
+        for (y = 0; y < tectonic.ysize; ++y) {
+            rp0 = surface[x][y];
+            rp0->moved = FALSE;
+            rp0->elev += rp0->elevchange;
+            rp0->elevchange = 0;
+        }
+    }
+    return 0;
+}
+
+/*
+ * Give all the plates directions, move them, and see what happens.
+ * They may move a maximum of tectonic.epochmove cells per epoch.
+ */
+int Epoch()
+{
+    register int i;
+
+    AssignDirections();
+    for (i = 0; i < tectonic.epochmove; ++i) {
+        SetMovementVectors(i);
+        MovePlates();
+        MountainBuild();
+        EruptHotSpots();
+        Erode();
+    }
+    return 0;
+}
+
+/*************************************************************************
+ This ends Mark's plate tectonic code 
+ *************************************************************************/
+
+/**************************************************************************
+  mapgenerator_tectonic: Use Mark Isaak's plate tectonic simulation code 
+                         to generate a realistic world.
+**************************************************************************/
+static void mapgenerator_tectonic(void)
+{
+  int i;
+  int minval=5000000;
+  height_map=fc_malloc (sizeof(int)*map.xsize*map.ysize);
+
+  adjust_terrain_param();
+ 
+  /* Now, call Mark's teconic simulator to create a height map */
+
+  init_tec_data();
+  Tec_Init();
+  for(i=0;i<45;i++)
+      Epoch();
+
+  /* Convert the tectonically-synthsized map in to a freeciv height field */
+
+  whole_map_iterate(x, y) {
+    hmap(x, y) = surface[x][y]->elev;
+  } whole_map_iterate_end;
+
+  /* Mark's code generates negative values; adjust
+     To do: Add code which uses Mark's idea of what should be land
+            and water to determine where the oceans go; modify Mark's
+	    code to use map.landpercent */
+  minval = 600000;
+
+  whole_map_iterate(x, y) {
+
+    /* Hackish code to discard some more extreme values */
+    if (hmap(x, y) < -400) {
+      hmap(x, y) = -400;
+      }
+    if (hmap(x, y) > 10000) {
+      hmap(x, y) = 10000;
+      }
+
+    if (hmap(x, y) < minval) {
+      minval = hmap(x, y);
+      }
+  } whole_map_iterate_end;
+
+  if(minval < 0) {
+      whole_map_iterate(x, y) {
+          hmap(x, y) -= minval;
+	  } whole_map_iterate_end;
+      }
+
+  /* If we are using map generator eight, make the pure plate tectonic
+     land more lumpy.  We do this because the plate tectonic code simulates
+     the Earth's processes too well to make a traditional FreeCiv game: It
+     makes large stretches of land and water instead of the FreeCiv 
+     model of having many islands.  
+
+     The alleviates this by adding some lumpyness to the generated land;
+     this makes the continents smaller and the islands more numerous */
+
+  if(map.generator == 8) {
+      for (i=0;i<(map.xsize*map.ysize)/2;i++) {
+          int x,y;
+	  rand_map_pos(&x, &y);
+	  hmap(x, y) += myrand(4000);
+	  }
+
+      /* Smooth things out just a tad */
+      smooth_map();
+      smooth_map();
+      }
+
+  /* Find the minval and maxval now that we have made a plate tectonic
+     simulated map */
+
+  whole_map_iterate(x, y) {
+    if (hmap(x, y) > maxval)
+      maxval = hmap(x, y);
+    if (hmap(x, y) < minval)
+      minval = hmap(x, y);
+  } whole_map_iterate_end;
+
+  maxval-=minval;
+  adjust_map(minval);
+
+  /* based on map.landpercent, separate land from water */
+  make_land(maxval / 5);
+
   free(height_map);
   height_map = NULL;
 }
@@ -2208,7 +3202,271 @@
   maxval -= minval;
   adjust_map(minval);
   
-  make_land();
+  make_land(maxval);
   free(height_map);
   height_map = NULL;
 }
+
+static int is_ocean(int l)
+{
+  return (l == T_OCEAN);
+}
+
+static int land_terrain(int x, int y)
+{
+  return !is_ocean(map_get_terrain(x,y));
+}
+
+static int border_score(int x, int y)
+{
+  int adj_score = 2;
+  int diag_score = 1;
+  int score = 0;
+  score += land_terrain(x-1,y) ? adj_score : 0;
+  score += land_terrain(x+1,y) ? adj_score : 0;
+  score += land_terrain(x,y-1) ? adj_score : 0;
+  score += land_terrain(x,y+1) ? adj_score : 0;
+  score += land_terrain(x-1,y-1) ? diag_score : 0;
+  score += land_terrain(x+1,y-1) ? diag_score : 0;
+  score += land_terrain(x-1,y+1) ? diag_score : 0;
+  score += land_terrain(x+1,y+1) ? diag_score : 0;
+  return score;
+}
+
+static int random_new_land(int x, int y)
+{
+  int score;
+  int random;
+  if(land_terrain(x, y)) {
+    return T_PLAINS;
+  }
+  score = border_score(x, y);
+  random = myrand(4*2+4*1);
+  return random + 1 > score  ? T_OCEAN : T_GRASSLAND;
+  
+}
+
+/* Creates a peninsula and put the player's starting position
+   on it; this is used by map generator 6 */
+static void create_peninsula(int x, int y,int player_number,
+			     int width, int height,int direction,
+			     int remaining_count)
+{
+  int cx, cy;
+
+  cx = x+width/2;
+  for(cy = y; cy != y + (height + 1)*direction; 
+      cy += direction) {
+    map_set_terrain(cx, cy, T_GRASSLAND);
+    map_set_continent(cx, cy, 1);
+  }
+  remaining_count -= height; /* account for the already added strip */
+  cy = y;
+  for(cx = x + width/2 - 2; cx <= x + width/2 + 2; cx ++) {
+    map_set_terrain(cx, cy, T_GRASSLAND);
+    map_set_continent(cx, cy, 1);    
+  }
+  remaining_count -= 4; /* account for extra 4 (not 5 because that would 
+			double count the one already done by height strip.*/
+  
+  while (remaining_count > 0) {
+    for(cx = x; cx < x+width; cx++) {
+      for(cy = y; cy != y + (height + 1)*direction; cy += direction) {
+	int new_terrain = random_new_land(cx, cy);
+	if(new_terrain == T_GRASSLAND){
+	  remaining_count--;
+	  map_set_terrain(cx, cy, T_GRASSLAND);
+	  map_set_continent(cx, cy, 1);
+	  hmap(cx, cy) = 20 * (cx - x) * (width - (cx - x)) + myrand(80) - 40;
+	}
+	if(remaining_count <= 0) {
+	  goto done_with_peninsula;
+	}
+      }
+    }
+  }
+
+ done_with_peninsula:
+
+  map.start_positions[player_number].x = x+width/2;
+  map.start_positions[player_number].y = y;
+}
+
+/* This generator creates a map with one penisula for each 
+   player and an isthmus between.  It creates a central
+   ocean and puts the peninsulas around the edges.  It is 
+   intented for quicker games. Should look something like this:
+   *****************************
+   **  *****  *****  *****    ** 
+   *    ***    ***    ***      *
+   *                           *
+   *                           *
+   *    ***    ***             *
+   **  *****  *****           **
+   *****************************
+ */
+static void mapgenerator6(void)
+{
+  int peninsulas = game.nplayers;
+  int peninsulas_on_one_side = (peninsulas + 1)/2;
+  int isthmus_width = 10;
+  int peninsula_separation = 5;
+  int peninsula_width = 
+    (map.xsize - isthmus_width - peninsula_separation)
+      /(peninsulas_on_one_side) - peninsula_separation;
+  /* if landpercent <= 50, then make shorter peninsulas */
+  int peninsula_height = (map.landpercent <= 50) 
+    ? map.ysize/3
+      : (map.ysize*2)/5;
+  int continent_percent = (map.landpercent <= 50) 
+    ? (map.landpercent * 3)/2 
+      : (map.landpercent * 5)/4;
+  int i, x, y;
+  int polar_height = 3;
+  int remaining_count = 
+    MIN(isthmus_width * (map.ysize - polar_height*2),
+	((isthmus_width+peninsula_separation) * (map.ysize - polar_height*2) 
+	 * continent_percent)/100);
+ 
+  height_map = fc_malloc(sizeof(int) * map.xsize * map.ysize);
+
+  /* initialize everything to ocean */
+  for (y = 0 ; y < map.ysize ; y++) 
+    for (x = 0 ; x < map.xsize ; x++) {
+      map_set_terrain(x, y, T_OCEAN);
+      map_set_continent(x, y, 0);
+      hmap(x, y) = 0;
+    }
+
+  /* create polar regions */
+  for (x = 0 ; x < map.xsize; x++) {
+    for (y = 0; y < polar_height; y++) {
+      int rand_num = myrand(9);
+      map_set_terrain(x, y, rand_num > 7 ? T_ARCTIC :
+		      (rand_num < 2 ? T_MOUNTAINS : T_TUNDRA));
+      map_set_continent(x, y, 1);
+      rand_num = myrand(9);
+      map_set_terrain(x, map.ysize-1-y, rand_num > 7 ? T_ARCTIC :
+		      (rand_num < 2 ? T_MOUNTAINS : T_TUNDRA));
+      map_set_continent(x, map.ysize-1-y, 1);
+    }
+  }
+  
+  /* build polar regions road */
+  for (x = 0 ; x < map.xsize; x++) {
+	  y = polar_height-1;
+	  if(map_build_road_time(x,y-1) < map_build_road_time(x,y))
+	  {
+		  map_set_special(x,y-1,S_ROAD);
+	  } else {
+		  map_set_special(x,y,S_ROAD);
+	  }
+	  y = map.ysize-polar_height;
+	  if(map_build_road_time(x,y+1) < map_build_road_time(x,y))
+	  {
+		  map_set_special(x,y+1,S_ROAD);
+	  } else {
+		  map_set_special(x,y,S_ROAD);
+	  }
+  }
+
+  map.num_continents = 1;
+
+  /* create isthmus centeral strip */
+  x = isthmus_width/2;
+  for (y = polar_height; y < map.ysize - polar_height; y++) {
+    map_set_terrain(x, y, T_GRASSLAND);
+    map_set_continent(x, y, 1);
+    hmap(x, y) = 100 * x * (isthmus_width - x) + (myrand(400) - 200);
+  }
+
+  remaining_count -= (map.ysize - 2*polar_height) * 1;
+
+  /* add additional isthmus area randomly */
+  while(remaining_count > 0) {
+    for (y = polar_height; y < map.ysize/2; y++) {
+      for (x = 0; x < isthmus_width; x++) {
+	int new_terrain = random_new_land(x, y);
+	if(new_terrain == T_GRASSLAND){
+	  remaining_count--;
+	  map_set_terrain(x, y, T_GRASSLAND);
+	  map_set_continent(x, y, 1);
+	  hmap(x, y) = 100 * x * (isthmus_width - x) + (myrand(400) - 200);
+	}
+	if(remaining_count <= 0) {
+	  goto done_with_isthmus;
+	}
+      }
+    }
+    
+    for (y = map.ysize - polar_height - 1; y >= map.ysize/2; y--) {
+      for (x = 0; x < isthmus_width; x++) {
+	int new_terrain = random_new_land(x, y);
+	if(new_terrain == T_GRASSLAND){
+	  remaining_count--;
+	  map_set_terrain(x, y, T_GRASSLAND);
+	  map_set_continent(x, y, 1);
+	  hmap(x, y) = 100 * x * (isthmus_width - x) + (myrand(400) - 200);
+	}
+	if(remaining_count <= 0) {
+	  goto done_with_isthmus;
+	}
+      }
+    }
+  }
+ done_with_isthmus:
+  
+  /* setup peninsulas */
+  for(i = 0; i < game.nplayers; i++) {
+    /* direction is the direction to increment from the x and y location */
+    int direction = (i < peninsulas_on_one_side) ? -1 : 1;
+    int index = (direction == -1) ? i : i - peninsulas_on_one_side;
+    int width = (continent_percent < 95) 
+      ? peninsula_width
+	: peninsula_width + peninsula_separation - 1;/*Give more room */
+    int height = peninsula_height-polar_height;
+    int peninsula_remaining_count = 
+      MIN(width*height,
+	  ((width+peninsula_separation)*height*continent_percent)/100);
+    x = index * (peninsula_width + peninsula_separation) 
+      + isthmus_width + peninsula_separation;
+    y = (direction == -1) 
+      ? peninsula_height 
+	: map.ysize - 1 - peninsula_height;
+    create_peninsula(x,y,i,width,height,direction,peninsula_remaining_count);
+  }
+
+  map.num_start_positions = game.nplayers;
+  
+  /* setup terrain */
+  make_mountains(1600);
+  make_swamps();
+  make_forests();
+  make_deserts();
+  make_plains();
+  make_fair();
+  make_rivers();
+
+  /* create isthmus road */
+  {
+    int last_x, middle_x = isthmus_width/2;
+    last_x = middle_x;
+    for (y = polar_height - 1; y < map.ysize - polar_height + 1; y++) {
+      int best_x = middle_x;
+      int min_build = 100;
+      for(x = MAX(last_x - 1, middle_x - 1);
+	  x != MIN(last_x + 1,middle_x + 1) + 1; x++) {
+	if(land_terrain(x,y) && map_build_road_time(x,y) < min_build) {
+	  best_x = x;
+	  min_build = map_build_road_time(x,y);
+	}
+      }
+      map_set_special(best_x,y,S_ROAD);
+      last_x = best_x;
+    }
+  }
+  
+
+  free(height_map);
+	
+}
Only in freeciv-1.14.0-stat/server: mapgen.c.rej
diff -ur freeciv-1.14.0/server/mapgen.h freeciv-1.14.0-stat/server/mapgen.h
--- freeciv-1.14.0/server/mapgen.h	Tue Feb  5 11:05:51 2002
+++ freeciv-1.14.0-stat/server/mapgen.h	Wed Mar 26 01:55:50 2003
@@ -15,7 +15,6 @@
 
 void assign_continent_numbers(void);
 void map_fractal_generate(void);
-void create_start_positions(void);
 void adjust_terrain_param(void);
 
 #endif  /* FC__MAPGEN_H */
Only in freeciv-1.14.0-stat/server: mapgen.h.orig
Only in freeciv-1.14.0-stat/server: mapgen.h.rej
diff -ur freeciv-1.14.0/server/srv_main.c freeciv-1.14.0-stat/server/srv_main.c
--- freeciv-1.14.0/server/srv_main.c	Fri Oct 11 16:35:50 2002
+++ freeciv-1.14.0-stat/server/srv_main.c	Wed Mar 26 01:55:50 2003
@@ -1798,6 +1798,7 @@
 void srv_main(void)
 {
   int i;
+  int is_good_map;
 
   /* make sure it's initialized */
   if (!has_been_srv_init) {
@@ -1943,7 +1944,11 @@
     
   if(game.is_new_game)
     generate_ai_players();
-   
+ 
+  /* This is a loop which will recreate the map in case the map
+     generator decides the generated map is not good enough */
+  do {
+
   /* if we have a tile map, and map.generator==0, call map_fractal_generate
      anyway, to make the specials and huts */
   if(map_is_empty() || (map.generator == 0 && game.is_new_game))
@@ -1972,13 +1977,23 @@
     } players_iterate_end;
     game.max_players=game.nplayers;
 
+    is_good_map = 1;
     /* we don't want random start positions in a scenario which already
        provides them.  -- Gudy */
     if(map.num_start_positions==0) {
-      create_start_positions();
+      is_good_map = create_start_positions();
     }
   }
 
+  /* Save the whales, free the mallocs */
+  if(is_good_map == 0) {
+      players_iterate(pplayer) {
+          free(pplayer->private_map);
+          } players_iterate_end;
+      }
+
+  } while(is_good_map == 0);
+
   initialize_move_costs(); /* this may be the wrong place to do this */
   generate_minimap(); /* for city_desire; saves a lot of calculations */
 
diff -ur freeciv-1.14.0/server/stdinhand.c freeciv-1.14.0-stat/server/stdinhand.c
--- freeciv-1.14.0/server/stdinhand.c	Fri Nov 15 19:14:22 2002
+++ freeciv-1.14.0-stat/server/stdinhand.c	Wed Mar 26 01:43:41 2003
@@ -3224,7 +3224,7 @@
 	}
       } players_iterate_end;
 
-      if (plrs<game.min_players) {
+      if (plrs<game.min_players && 1==2) {
         cmd_reply(cmd,caller, C_FAIL,
 		  _("Not enough players, game will not start."));
       } else {
Only in freeciv-1.14.0-stat/server: stdinhand.c.orig
Only in freeciv-1.14.0-stat: stamp-h
