[Freeciv-Dev] Re: (PR#3489) Patch to add new generator
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Okay. Regenerated the patch to do that.
The map used to look something like this with 5 players:
###################
## ### ### ###
##
## ### ###
###################
Now it will look like this:
###################
## ### ### ###
##
## ### ###
###################
Added lines:
/* x_adder centers the peninsulas if there are an odd number */
int x_adder = (direction == 1 && game.nplayers % 2 == 1) ?
(peninsula_width + peninsula_separation)/2 : 0;
Modified lines:
From:
x = index * (peninsula_width + peninsula_separation)
+ isthmus_width + peninsula_separation;
To:
x = index * (peninsula_width + peninsula_separation)
+ isthmus_width + peninsula_separation + x_adder;
--
Josh Cogliati
jjc@xxxxxxxxxxxxxxxxxx
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.141
diff -U9 -r1.141 map.h
--- common/map.h 2003/03/11 17:59:26 1.141
+++ common/map.h 2003/03/28 14:23:05
@@ -629,19 +629,19 @@
#define MAP_MIN_RIVERS 0
#define MAP_MAX_RIVERS 100
#define MAP_DEFAULT_FORESTS 20
#define MAP_MIN_FORESTS 0
#define MAP_MAX_FORESTS 100
#define MAP_DEFAULT_GENERATOR 1
#define MAP_MIN_GENERATOR 1
-#define MAP_MAX_GENERATOR 5
+#define MAP_MAX_GENERATOR 6
#define MAP_DEFAULT_TINYISLES FALSE
#define MAP_MIN_TINYISLES FALSE
#define MAP_MAX_TINYISLES TRUE
#define MAP_DEFAULT_SEPARATE_POLES TRUE
#define MAP_MIN_SEPARATE_POLES FALSE
#define MAP_MAX_SEPARATE_POLES TRUE
Index: server/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/mapgen.c,v
retrieving revision 1.110
diff -U9 -r1.110 mapgen.c
--- server/mapgen.c 2003/02/20 09:45:22 1.110
+++ server/mapgen.c 2003/03/28 14:23:30
@@ -36,18 +36,19 @@
#define rmap(x, y) (river_map[map_pos_to_index(x, y)])
static void make_huts(int number);
static void add_specials(int prob);
static void mapgenerator1(void);
static void mapgenerator2(void);
static void mapgenerator3(void);
static void mapgenerator4(void);
static void mapgenerator5(void);
+static void mapgenerator6(void);
static void smooth_map(void);
static void adjust_map(int minval);
#define RIVERS_MAXTRIES 32767
enum river_map_type {RS_BLOCKED = 0, RS_RIVER = 1};
/* Array needed to mark tiles as blocked to prevent a river from
falling into itself, and for storing rivers temporarly.
A value of 1 means blocked.
@@ -1151,18 +1152,20 @@
mysrand(map.seed);
/* 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) {
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 == 5 )
mapgenerator5();
if (map.generator == 4 )
mapgenerator4();
if (map.generator == 3 )
mapgenerator3();
if( map.generator == 2 )
mapgenerator2();
if( map.generator == 1 )
@@ -2134,9 +2137,264 @@
minval = hmap(x, y);
} whole_map_iterate_end;
maxval -= minval;
adjust_map(minval);
make_land();
free(height_map);
height_map = NULL;
}
+
+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 */
+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) = myrand(7000) - 2000;
+ /*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) {
+ int low = polar_height;
+ int high = map.ysize - polar_height - 1;
+ int direction;
+ for (direction = -1; direction < 2; direction += 2) {
+ int start = (direction == 1) ? low : high;
+ int end = (direction == 1) ? high : low;
+ for (y = start; y != end + direction; y += direction) {
+ 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_adder centers the peninsulas if there are an odd number */
+ int x_adder = (direction == 1 && game.nplayers % 2 == 1) ?
+ (peninsula_width + peninsula_separation)/2 : 0;
+ x = index * (peninsula_width + peninsula_separation)
+ + isthmus_width + peninsula_separation + x_adder;
+ 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 */
+ smooth_map();
+ 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);
+
+}
+
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.273
diff -U9 -r1.273 stdinhand.c
--- server/stdinhand.c 2003/03/24 22:20:58 1.273
+++ server/stdinhand.c 2003/03/28 14:23:56
@@ -236,19 +236,21 @@
"3 = equally sized large islands with one player each, and "
"a number of other\n"
" islands of similar size;\n"
"4 = equally sized large islands with two players on every "
"island (or one\n"
" with three players for an odd number of players), and "
"additional\n"
" smaller islands.\n"
"5 = one or more large earthlike continents with some scatter.\n"
- "Note: values 2,3 and 4 generate \"fairer\" (but more boring) "
+ "6 = equally sized peninsulas with one player each surrounding \n"
+ " an inland sea.\n"
+ "Note: values 2,3,4 and 6 generate \"fairer\" (but more boring) "
"maps.\n"
"(Zero indicates a scenario map.)"), NULL,
MAP_MIN_GENERATOR, MAP_MAX_GENERATOR, MAP_DEFAULT_GENERATOR)
GEN_BOOL("tinyisles", map.tinyisles, SSET_MAP_GEN, SSET_TO_CLIENT,
N_("Presence or absence of 1x1 islands"),
N_("0 = no 1x1 islands; 1 = some 1x1 islands"), NULL,
MAP_DEFAULT_TINYISLES)
[Freeciv-Dev] Re: (PR#3489) Patch to add new generator, Gregory Berkolaiko, 2003/03/31
|
|