[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: |
Sun, 22 Aug 2004 12:27:00 -0700 |
Reply-to: |
rt@xxxxxxxxxxx |
<URL: http://rt.freeciv.org/Ticket/Display.html?id=9627 >
LAST CHANGES
adjust_map has be rewrie to do a linear distribution of values from 0 to
maxval. this allow to handle map very easy
sample:
(hmap < 0.33 * maxval) handel the 33% lowerest part of the map
this is used in make_land and make_relief to avoid some loops
Marcelo
diff -ruN -Xfreeciv/diff_ignore freeciv/common/map.h freeciv_/common/map.h
--- freeciv/common/map.h 2004-08-13 17:59:12.000000000 +0200
+++ freeciv_/common/map.h 2004-08-22 15:10:44.757331104 +0200
@@ -621,7 +621,7 @@
#define MAP_MIN_SEED 0
#define MAP_MAX_SEED (MAX_UINT32 >> 1)
-#define MAP_DEFAULT_LANDMASS 30
+#define MAP_DEFAULT_LANDMASS 35
#define MAP_MIN_LANDMASS 15
#define MAP_MAX_LANDMASS 85
@@ -629,11 +629,11 @@
#define MAP_MIN_RICHES 0
#define MAP_MAX_RICHES 1000
-#define MAP_DEFAULT_MOUNTAINS 30
-#define MAP_MIN_MOUNTAINS 10
+#define MAP_DEFAULT_MOUNTAINS 10
+#define MAP_MIN_MOUNTAINS 5
#define MAP_MAX_MOUNTAINS 100
-#define MAP_DEFAULT_GRASS 35
+#define MAP_DEFAULT_GRASS 55
#define MAP_MIN_GRASS 20
#define MAP_MAX_GRASS 100
@@ -649,7 +649,7 @@
#define MAP_MIN_RIVERS 0
#define MAP_MAX_RIVERS 100
-#define MAP_DEFAULT_FORESTS 20
+#define MAP_DEFAULT_FORESTS 12
#define MAP_MIN_FORESTS 0
#define MAP_MAX_FORESTS 100
diff -ruN -Xfreeciv/diff_ignore freeciv/server/mapgen.c freeciv_/server/mapgen.c
--- freeciv/server/mapgen.c 2004-08-19 09:34:25.000000000 +0200
+++ freeciv_/server/mapgen.c 2004-08-22 19:17:29.377686712 +0200
@@ -25,6 +25,7 @@
#include "game.h"
#include "log.h"
#include "map.h"
+#include "maphand.h" /* assign_continent_numberd(),MASS_SIZE(), MAP_NCONT */
#include "mem.h"
#include "rand.h"
#include "shared.h"
@@ -75,8 +76,13 @@
static int *river_map;
static int *height_map;
-static int maxval=0;
-static int forests=0;
+static const int maxval=1000;
+static int reliefval=0, seaval=0;
+static int forests_to_be_placed =0;
+static int deserts_to_be_placed=0;
+static int grass_to_be_placed=0;
+static int plains_to_be_placed=0;
+static int swamps_to_be_placed=0;
struct isledata {
int goodies;
@@ -84,23 +90,43 @@
};
static struct isledata *islands;
-/* this is used for generator>1 */
-#define MAP_NCONT 255
-
/* 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 4 region of a Earth like map
+ =========================================================
+ 0-COLD_LV cold region: most ice/tundra/mountains
+ COLD_LV-TREOPICAL_LV temperate region: all terrains types
+ TROPICAL_LV-WET_LV tropical dry region: most dessert/mountains
+ WET_LV-MAX_TEMP tropical wet region: most jungle/mountains
+*/
+#define COLD_LEVEL (10 * MAX_TEMP / 100)
+#define TROPICAL_LEVEL (65 * MAX_TEMP / 100)
+#define WET_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 */)
+#define T_NOTPLACED T_UNKNOWN
+
+/********************************************************************
+ * used to initialize a array with some value
+ ********************************************************************/
+#define INITIALIZE_ARRAY(A, MAX, VAL) \
+ { \
+ int INI_INEX; \
+ for(INI_INEX = 0; INI_INEX < (MAX);INI_INEX++) { \
+ (A)[INI_INEX] = (VAL); \
+ } \
+ }
/****************************************************************************
Returns the temperature of this map position. This is a value in the
range of 0 to MAX_TEMP (inclusive).
@@ -283,41 +309,65 @@
}
/**************************************************************************
- make_mountains() 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).
+ Checks if land has not yet been placed on tile at (x, y)
**************************************************************************/
-static void make_mountains(int thill)
+static bool not_placed(x, y)
{
- int mount;
- int j;
+ return map_get_terrain(x, y) == T_NOTPLACED;
+}
- for (j = 0; j < 10; j++) {
- mount = 0;
- whole_map_iterate(x, y) {
- if (hmap(x, y) > thill) {
- mount++;
- }
- } whole_map_iterate_end;
- if (mount < (map_num_tiles() * map.mountains) / 1000) {
- thill *= 95;
- } else {
- thill *= 105;
+/**************************************************************************
+ 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_clean(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;
+ };
}
- thill /= 100;
+ } square_iterate_end;
+
+ if ((thill - seaval) * (biger_me) > (my_high - seaval) * 4 ) {
+ return FALSE;
}
-
+ 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).
+ TODO: extend to place ocean/deepocean/abys relief in oceans
+**************************************************************************/
+static void make_relief()
+{
+ reliefval = ((maxval - seaval)* (100 - map.mountains)) / 100 + seaval;
whole_map_iterate(x, y) {
- if (hmap(x, y) > thill && !is_ocean(map_get_terrain(x,y))) {
+ if (not_placed(x,y)
+ && (hmap(x, y) > reliefval
+ || terrain_is_clean(x, y, reliefval, 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);
- } else if (myrand(100) > 25) {
+ } else {
map_set_terrain(x, y, T_HILLS);
- }
+ }
}
} whole_map_iterate_end;
}
@@ -355,6 +405,24 @@
}
} 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.
@@ -365,30 +433,17 @@
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) {
- ptile->terrain = T_GRASSLAND;
- } else if ((T <= 2 * ICE_BASE_LEVEL) && myrand(10) > 4 ) {
- ptile->terrain = T_GRASSLAND;
- }
- } 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 (map_get_terrain(x, y) == T_GRASSLAND
- && (2 * ICE_BASE_LEVEL > T || myrand(MAX_TEMP/5) > T)) {
- map_set_terrain(x, y, T_TUNDRA);
+ if (T < 1.5 * ICE_BASE_LEVEL && ok_for_separate_poles(map_x, map_y)) {
+ ptile->terrain = T_NOTPLACED;
+ 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_NOTPLACED;
+ map_set_continent(map_x, map_y, 0);
}
} whole_map_iterate_end;
}
@@ -401,8 +456,8 @@
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
+ 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);
}
@@ -423,14 +478,16 @@
{
const int DeltaT = MAX_TEMP / (3 * SQSIZE);
+ if(deserts_to_be_placed <= 0) { return; }
+
if (abs(hmap(x, y) - height) < diff
- && map_get_terrain(x, y) == T_GRASSLAND) {
+ && not_placed(x, y) && count_ocean_near_tile(x,y) <= 2) {
map_set_terrain(x, y, T_DESERT);
+ deserts_to_be_placed--;
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;
}
}
@@ -443,125 +500,171 @@
**************************************************************************/
static void make_forest(int map_x, int map_y, int height, int diff)
{
- int nat_x, nat_y, T;
+ int T;
- map_to_native_pos(&nat_x, &nat_y, map_x, map_y);
- T = map_temperature(map_x, map_y);
- if (map_get_terrain(map_x, map_y) == T_GRASSLAND) {
- if (T > 8 * MAX_TEMP / 10
- && myrand(1000) > 500 - 300 * (T * 1000 / MAX_TEMP - 800)) {
+ if(forests_to_be_placed <= 0) { return; }
+ if (not_placed(map_x, map_y)) {
+ if ((T = map_temperature(map_x, map_y))> WET_LEVEL && myrand(100)
> 50) {
map_set_terrain(map_x, map_y, T_JUNGLE);
} else {
map_set_terrain(map_x, map_y, T_FOREST);
}
+ forests_to_be_placed--;
if (abs(hmap(map_x, map_y) - height) < diff) {
cardinal_adjc_iterate(map_x, map_y, x1, y1) {
- if (myrand(10) > 5) {
+ if (myrand(10) > 5 || (T > WET_LEVEL && myrand(10) > 5)) {
make_forest(x1, y1, height, diff - 5);
}
} cardinal_adjc_iterate_end;
}
- forests++;
}
}
/**************************************************************************
- makeforest calls make_forest with random grassland locations until there
- has been made enough forests. (the map.forestsize value controls this)
+ a recursive function that adds swamps to the current location and try
+ to spread out to the neighbours.
**************************************************************************/
-static void make_forests(void)
+static void make_swamp(int map_x, int map_y, int height, int diff)
{
- 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,
- T_GRASSLAND)) {
- 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,
- T_GRASSLAND)) {
- make_forest(x, y, hmap(x, y), 25);
- }
-
- /* And add a cold forest clump (10%-30% temperature). */
- 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);
+ if(swamps_to_be_placed <= 0) { return; }
+ if (not_placed(map_x, map_y)
+ && ( 2 * (hmap(map_x, map_y) - seaval) < myrand(reliefval - seaval)
+ || (map_temperature(map_x, map_y) > WET_LEVEL && myrand(40) > 30))) {
+ map_set_terrain(map_x, map_y, T_SWAMP);
+ swamps_to_be_placed--;
+ if (abs(hmap(map_x, map_y) - height) < diff) {
+ cardinal_adjc_iterate(map_x, map_y, x1, y1) {
+ make_forest(x1, y1, height, diff - 5);
+ } cardinal_adjc_iterate_end;
}
- } while (forests < forestsize);
+ }
}
-
/**************************************************************************
- 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
+ a simple function that adds plains or tundra to the current location.
**************************************************************************/
-static void make_swamps(void)
+static void make_plain(int x, int y)
{
- int x, y, swamps;
- int forever = 0;
+ int T = map_temperature(x, y);
- for (swamps = 0; swamps < map.swampsize; ) {
- forever++;
- if (forever > 1000) {
- return;
- }
- rand_map_pos(&x, &y);
- if (map_get_terrain(x, y) == T_GRASSLAND
- && hmap(x, y) < (maxval * 60) / 100) {
- map_set_terrain(x, y, T_SWAMP);
- cardinal_adjc_iterate(x, y, x1, y1) {
- 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++;
- }
- } cardinal_adjc_iterate_end;
- swamps++;
- }
+ if(2 * ICE_BASE_LEVEL > T || myrand(2 * COLD_LEVEL) > T) {
+ map_set_terrain(x, y, T_TUNDRA); /* in cold place we get tundra instead */
+ } else {
+ map_set_terrain(x, y, T_PLAINS);
}
+ plains_to_be_placed--;
}
-/*************************************************************************
- Make deserts until we have enough of them.
+/**************************************************************************
+ make_terrains calls make_forest, make_dessert 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 can get
+ in a infinite loop!
**************************************************************************/
-static void make_deserts(void)
+static void make_terrains(void)
{
- int x, y, i = map.deserts, j = 0;
+ int x, y;
+ int total = 0;
+ whole_map_iterate(x, y) {
+ if(not_placed(x,y)) {
+ total++;
+ }
+ } whole_map_iterate_end;
- /* "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++;
+ 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);
- /* 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 {
- /* If rand_map_pos_temperature returns FALSE we may as well stop
- * looking. */
- break;
+ /* tundra and plains is counted in map.grasssize */
+ grass_to_be_placed = total * map.grasssize / 2
+ / ( map.forestsize + map.deserts + map.grasssize + map.swampsize);
+ plains_to_be_placed = total /* and tundra */
+ - forests_to_be_placed - deserts_to_be_placed - grass_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_temperature(&x, &y,
+ (COLD_LEVEL + ICE_BASE_LEVEL) / 2, MAX_TEMP,
+ T_NOTPLACED)) {
+ make_forest(x, y, hmap(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;
+ }
}
- }
+
+ if(swamps_to_be_placed > 0) {
+ /* Place one swamp clump between COLD_LEVEL and MAX_TEMP.. */
+ if (rand_map_pos_temperature(&x, &y,
+ COLD_LEVEL, MAX_TEMP,
+ T_NOTPLACED)) {
+ make_swamp(x, y, hmap(x, y), 25);
+ } else {
+ /* If rand_map_pos_temperature returns FALSE we may as well stop
+ * looking for swamp. */
+ plains_to_be_placed += swamps_to_be_placed; /* reactivate plains */
+ swamps_to_be_placed = 0;
+ }
+ }
+
+ if(deserts_to_be_placed > 0) {
+ /* Choose a random coordinate between TROPICAL_LEVEL and WET_LEVEL;
+ make_desert will expand them). */
+ if (rand_map_pos_temperature(&x, &y,
+ TROPICAL_LEVEL, WET_LEVEL,
+ T_NOTPLACED)){
+ make_desert(x, y, hmap(x, y), 40, map_temperature(x, y));
+ } 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;
+ }
+ }
+
+ /* Make the grass */
+ if(grass_to_be_placed > 0) {
+ if (rand_map_pos_temperature(&x, &y,
+ COLD_LEVEL, MAX_TEMP,
+ T_NOTPLACED)){
+ map_set_terrain(x, y, T_GRASSLAND);
+ grass_to_be_placed--;
+ } else {
+ plains_to_be_placed += grass_to_be_placed;
+ grass_to_be_placed = 0;
+ }
+ }
+
+ /* 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_temperature(&x, &y,
+ 0, MAX_TEMP,
+ T_NOTPLACED)){
+ 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
+ || grass_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;
}
/*********************************************************************
@@ -814,7 +917,7 @@
if (adjacent_river_tiles4(x, y) != 0
|| adjacent_ocean_tiles4(x, y) != 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);
@@ -1027,56 +1130,6 @@
river_map = NULL;
}
-/**************************************************************************
- make_plains converts 50% of the remaining grassland to plains, this should
- maybe be lowered to 30% or done in batches, like the swamps?
-**************************************************************************/
-static void make_plains(void)
-{
- whole_map_iterate(x, y) {
- if (map_get_terrain(x, y) == T_GRASSLAND && myrand(100) > 50)
- map_set_terrain(x, y, T_PLAINS);
- } 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.
@@ -1117,6 +1170,21 @@
}
} whole_map_iterate_end;
}
+/**************************************************************************
+ if there are room the isle is grownd by one else isle is deleted
+**************************************************************************/
+static void grown_tiny_isle(int x,int y, int nr) {
+ adjc_iterate(x, y, x1, y1) {
+ if(count_ocean_near_tile(x1,y1) == 7) {
+ map_set_terrain(x1, y1, T_NOTPLACED);
+ map_set_continent(x1, y1, nr);
+ MASS_SIZE(nr)++;
+ return;
+ }
+ } adjc_iterate_end;
+ map_set_terrain(x, y, T_OCEAN);
+ return;
+}
/**************************************************************************
make land simply does it all based on a generated heightmap
@@ -1125,44 +1193,34 @@
**************************************************************************/
static void make_land(void)
{
- int tres;
- int count=0;
- int total = (map_num_tiles() * map.landpercent) / 100;
- int forever=0;
-
adjust_map();
normalize_hmap_poles();
- tres = (maxval * map.landpercent) / 100;
-
- do {
- forever++;
- if (forever>50) break; /* loop elimination */
- count=0;
- whole_map_iterate(x, y) {
- if (hmap(x, y) < tres)
- map_set_terrain(x, y, T_OCEAN);
- else {
- map_set_terrain(x, y, T_GRASSLAND);
- count++;
- }
- } whole_map_iterate_end;
- if (count>total)
- tres*=11;
- else
- tres*=9;
- tres/=10;
- } while (abs(total-count)> maxval/40);
-
+ seaval = maxval - (maxval * map.landpercent) / 100;
+ whole_map_iterate(x, y) {
+ if (hmap(x, y) < seaval)
+ map_set_terrain(x, y, T_OCEAN);
+ else {
+ map_set_terrain(x, y, T_NOTPLACED);
+ }
+ } whole_map_iterate_end;
renormalize_hmap_poles();
make_polar_land(); /* make extra land at poles*/
- make_mountains(maxval*8/10);
- make_arctic();
- make_tundra();
- make_forests();
- make_swamps();
- make_deserts();
- make_plains();
- make_fair();
+ assign_continent_numbers(); /* count sizes */
+ whole_map_iterate(x, y) {
+ int nr = map_get_continent(x,y);
+ /* avoid too small oceans */
+ if (is_ocean(map_get_terrain(x, y)) && MASS_SIZE(nr) < 8) {
+ map_set_terrain(x, y, T_NOTPLACED);
+ }
+ /* avoid tiny isles */
+ else if (!is_ocean(map_get_terrain(x, y)) && MASS_SIZE(nr) == 1) {
+ grown_tiny_isle(x, y, nr);
+ }
+ } whole_map_iterate_end;
+
+ make_relief(); /* base relief on map */
+ make_arctic();
+ make_terrains();/* place forest/dessert/swamp/grass/tundra and plains */
make_rivers();
assign_continent_numbers();
@@ -1204,63 +1262,6 @@
} whole_map_iterate_end;
}
-/**************************************************************************
- Number this tile and recursive adjacent tiles with specified
- continent number, by flood-fill algorithm.
- is_land tells us whether we are assigning continent numbers or ocean
- numbers.
-**************************************************************************/
-static void assign_continent_flood(int x, int y, bool is_land, int nr)
-{
- if (map_get_continent(x, y) != 0) {
- return;
- }
-
- if ((is_land && is_ocean(map_get_terrain(x, y)))
- || (!is_land && !is_ocean(map_get_terrain(x, y)))) {
- return;
- }
-
- map_set_continent(x, y, nr);
-
- adjc_iterate(x, y, x1, y1) {
- assign_continent_flood(x1, y1, is_land, nr);
- } adjc_iterate_end;
-}
-
-/**************************************************************************
- Assign continent and ocean numbers to all tiles, set map.num_continents
- and map.num_oceans.
- Continents have numbers 1 to map.num_continents _inclusive_.
- Oceans have (negative) numbers -1 to -map.num_oceans _inclusive_.
-**************************************************************************/
-void assign_continent_numbers(void)
-{
- /* Initialize */
- map.num_continents = 0;
- map.num_oceans = 0;
- whole_map_iterate(x, y) {
- map_set_continent(x, y, 0);
- } whole_map_iterate_end;
-
- /* Assign new numbers */
- whole_map_iterate(x, y) {
- if (map_get_continent(x, y) != 0) {
- /* Already assigned */
- continue;
- }
- if (!is_ocean(map_get_terrain(x, y))) {
- map.num_continents++;
- assign_continent_flood(x, y, TRUE, map.num_continents);
- } else {
- map.num_oceans++;
- assign_continent_flood(x, y, FALSE, -map.num_oceans);
- }
- } whole_map_iterate_end;
-
- freelog(LOG_VERBOSE, "Map has %d continents and %d oceans",
- map.num_continents, map.num_oceans);
-}
/****************************************************************************
Return an approximation of the goodness of a tile to a civilization.
@@ -1674,9 +1675,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) {
@@ -1690,25 +1691,43 @@
}
/**************************************************************************
- Adjust the map so that its minimum height is 0. This raises or lowers
- every position by a fixed amount and sets the "maxval" global variable
- to hold the maximum height.
+ Adjust the hmap to be a linearize distribution of heights
+ form 0 to maxval (maxval is a global const )
+ sample
+ ( hmap[x,y] < 0.13 * maxval) handle the 13% lowerest part of the map
**************************************************************************/
static void adjust_map(void)
{
- int minval = maxval = hnat(0, 0);
+ int i, min = hnat(0, 0), max = hnat(0, 0);
+ int count=0, f[maxval];
+
+ INITIALIZE_ARRAY(f,maxval,0);
/* Determine minimum and maximum heights. */
whole_map_iterate(x, y) {
- maxval = MAX(maxval, hmap(x, y));
- minval = MIN(minval, hmap(x, y));
+ max = MAX(max, hmap(x, y));
+ min = MIN(min, hmap(x, y));
} whole_map_iterate_end;
- /* Translate heights so the minimum height is 0. */
- maxval -= minval;
+ /* Translate heights so the minimum height is 0 and maximum is maxval.
+ and count pos in granularity */
+ max -= min;
whole_map_iterate(x, y) {
- hmap(x, y) -= minval;
+ hmap(x, y) = (hmap(x, y) - min) * maxval;
+ hmap(x, y) /= max;
+ f[hmap(x, y)]++;
} whole_map_iterate_end;
+
+ /* create the linearize function */
+ for(i = -1; i++ < maxval;) {
+ count += f[i];
+ f[i] = (count * maxval) / (map.xsize * map.ysize) ;
+ }
+
+ /* apply the linearize function */
+ whole_map_iterate(x, y) {
+ hmap(x, y) = f[hmap(x, y)];
+ } whole_map_iterate_end;
}
/**************************************************************************
@@ -2364,6 +2383,17 @@
#define DMSIS 10
/**************************************************************************
+ make_plains converts 50% of the remaining grassland to plains, this should
+ maybe be lowered to 30% or done in batches, like the swamps?
+**************************************************************************/
+static void make_plains(void)
+{
+ whole_map_iterate(x, y) {
+ if (map_get_terrain(x, y) == T_GRASSLAND && myrand(100) > 50)
+ map_set_terrain(x, y, T_PLAINS);
+ } whole_map_iterate_end;
+}
+/**************************************************************************
island base map generators
**************************************************************************/
static void mapgenerator2(void)
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-08-22 15:10:44.771328976 +0200
@@ -13,7 +13,6 @@
#ifndef FC__MAPGEN_H
#define FC__MAPGEN_H
-void assign_continent_numbers(void);
void map_fractal_generate(void);
void create_start_positions(void);
diff -ruN -Xfreeciv/diff_ignore freeciv/server/maphand.c
freeciv_/server/maphand.c
--- freeciv/server/maphand.c 2004-08-20 22:53:03.000000000 +0200
+++ freeciv_/server/maphand.c 2004-08-22 15:10:44.773328672 +0200
@@ -32,7 +32,6 @@
#include "citytools.h"
#include "cityturn.h"
#include "gamelog.h"
-#include "mapgen.h" /* assign_continent_numbers */
#include "plrhand.h" /* notify_player */
#include "sernet.h"
#include "srv_main.h"
@@ -41,6 +40,74 @@
#include "maphand.h"
+
+int mass_size[2 * MAP_NCONT];
+/**************************************************************************
+ Number this tile and recursive adjacent tiles with specified
+ continent number, by flood-fill algorithm.
+ is_land tells us whether we are assigning continent numbers or ocean
+ numbers.
+**************************************************************************/
+static void assign_continent_flood(int x, int y, bool is_land, int nr)
+{
+ if (map_get_continent(x, y) != 0) {
+ return;
+ }
+
+ if (!XOR(is_land , is_ocean(map_get_terrain(x, y)))) {
+ return;
+ }
+
+ map_set_continent(x, y, nr);
+ MASS_SIZE(nr)++;
+
+ adjc_iterate(x, y, x1, y1) {
+ assign_continent_flood(x1, y1, is_land, nr);
+ } adjc_iterate_end;
+}
+
+/**************************************************************************
+ Assign continent and ocean numbers to all tiles, set map.num_continents
+ and map.num_oceans.
+ Continents have numbers 1 to map.num_continents _inclusive_.
+ Oceans have (negative) numbers -1 to -map.num_oceans _inclusive_.
+**************************************************************************/
+void assign_continent_numbers(void)
+{
+ int i;
+
+ /* Initialize */
+ for(i = 0; i < 2 * MAP_NCONT; i++) {
+ MASS_SIZE(i) = 0;
+ }
+ map.num_continents = 0;
+ map.num_oceans = 0;
+
+ whole_map_iterate(x, y) {
+ map_set_continent(x, y, 0);
+ } whole_map_iterate_end;
+
+ /* Assign new numbers */
+ whole_map_iterate(x, y) {
+ if (map_get_continent(x, y) != 0) {
+ /* Already assigned */
+ continue;
+ }
+ if (!is_ocean(map_get_terrain(x, y))) {
+ map.num_continents++;
+ assert ( map.num_continents < MAP_NCONT);
+ assign_continent_flood(x, y, TRUE, map.num_continents);
+ } else {
+ map.num_oceans++;
+ assert ( map.num_oceans < MAP_NCONT);
+ assign_continent_flood(x, y, FALSE, -map.num_oceans);
+ }
+ } whole_map_iterate_end;
+
+ freelog(LOG_VERBOSE, "Map has %d continents and %d oceans",
+ map.num_continents, map.num_oceans);
+}
+
static void player_tile_init(int x, int y, struct player *pplayer);
static void give_tile_info_from_player_to_player(struct player *pfrom,
struct player *pdest,
diff -ruN -Xfreeciv/diff_ignore freeciv/server/maphand.h
freeciv_/server/maphand.h
--- freeciv/server/maphand.h 2004-08-09 07:24:35.000000000 +0200
+++ freeciv_/server/maphand.h 2004-08-22 15:10:44.775328368 +0200
@@ -49,6 +49,15 @@
short last_updated;
};
+/* this is used for generator 2-4 and in assign_continent number */
+#define MAP_NCONT 300
+
+/* signus safe way for nr continent <0 or >0 */
+extern int mass_size[2 * MAP_NCONT];
+#define MASS_SIZE(nr) (mass_size[FC_WRAP((nr), 2 * MAP_NCONT)])
+void assign_continent_numbers(void);
+
+
void global_warming(int effect);
void nuclear_winter(int effect);
void give_map_from_player_to_player(struct player *pfrom, struct player
*pdest);
diff -ruN -Xfreeciv/diff_ignore freeciv/server/stdinhand.c
freeciv_/server/stdinhand.c
--- freeciv/server/stdinhand.c 2004-08-09 17:45:49.000000000 +0200
+++ freeciv_/server/stdinhand.c 2004-08-22 15:10:44.781327456 +0200
@@ -369,7 +369,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 and plains squares"), "", NULL,
MAP_MIN_GRASS, MAP_MAX_GRASS, MAP_DEFAULT_GRASS)
GEN_INT("forests", map.forestsize,
diff -ruN -Xfreeciv/diff_ignore freeciv/utility/shared.h
freeciv_/utility/shared.h
--- freeciv/utility/shared.h 2004-07-24 14:26:07.000000000 +0200
+++ freeciv_/utility/shared.h 2004-08-22 15:10:44.783327152 +0200
@@ -101,8 +101,8 @@
? ((value) % (range) != 0 ? (value) % (range) + (range) : 0) \
: ((value) >= (range) ? (value) % (range) : (value)))
-#define BOOL_VAL(x) ((x)!=0)
-
+#define BOOL_VAL(x) ((x) != 0)
+#define XOR(p,q) (!(p) != !(q))
/*
* DIVIDE() divides and rounds down, rather than just divides and
* rounds toward 0. It is assumed that the divisor is positive.
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda, 2004/08/06
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda, 2004/08/06
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda, 2004/08/07
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Jason Short, 2004/08/09
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda, 2004/08/10
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda, 2004/08/10
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda, 2004/08/13
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda, 2004/08/13
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda, 2004/08/13
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda, 2004/08/15
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up,
Marcelo Burda <=
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda, 2004/08/27
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda, 2004/08/27
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda, 2004/08/28
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda, 2004/08/29
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda via RT, 2004/08/31
- [Freeciv-Dev] (PR#9627) PATCH: correct some parameters in map generator and clean-up, Marcelo Burda via RT, 2004/08/31
|
|