? generatesillymap.pl ? punchmap.pl ? client/tilespec.c.shelf ? data/trident/.xvpics ? data/trident/tiles.xcf Index: client/civclient.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/civclient.c,v retrieving revision 1.168 diff -u -3 -p -r1.168 civclient.c --- client/civclient.c 2003/04/17 20:06:35 1.168 +++ client/civclient.c 2003/04/24 01:14:43 @@ -616,7 +616,7 @@ void client_game_init() conn_list_init(&game.est_connections); conn_list_init(&game.game_connections); - game_init(); + full_game_init(); attribute_init(); agents_init(); cm_init(); Index: common/game.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/game.c,v retrieving revision 1.161 diff -u -3 -p -r1.161 game.c --- common/game.c 2003/04/17 20:06:36 1.161 +++ common/game.c 2003/04/24 01:14:44 @@ -632,12 +632,14 @@ void game_remove_city(struct city *pcity } /*************************************************************** -... +Do a complete initialisation of game structures. This should run +only at the beginning, because many of these we'll want to leave +untouched later, for example if loading a scenario; we should +leave them at values selected by the user. nb possibly more of +game_init should be moved here. --CJM ***************************************************************/ -void game_init(void) +void full_game_init(void) { - int i; - game.is_new_game = TRUE; game.globalwarming = 0; game.warminglevel = 8; game.nuclearwinter = 0; @@ -651,11 +653,6 @@ void game_init(void) game.timeoutinc = GAME_DEFAULT_TIMEOUTINC; game.timeoutincmult= GAME_DEFAULT_TIMEOUTINCMULT; game.timeoutcounter= 1; - game.tcptimeout = GAME_DEFAULT_TCPTIMEOUT; - game.netwait = GAME_DEFAULT_NETWAIT; - game.last_ping = 0; - game.pingtimeout = GAME_DEFAULT_PINGTIMEOUT; - game.pingtime = GAME_DEFAULT_PINGTIME; game.end_year = GAME_DEFAULT_END_YEAR; game.year = GAME_START_YEAR; game.turn = 0; @@ -698,6 +695,27 @@ void game_init(void) game.nbarbarians = 0; game.occupychance= GAME_DEFAULT_OCCUPYCHANCE; + game.randseed=GAME_DEFAULT_RANDSEED; + game.watchtower_vision=GAME_DEFAULT_WATCHTOWER_VISION; + game.watchtower_extra_vision=GAME_DEFAULT_WATCHTOWER_EXTRA_VISION, + + game_init(); + map_init(); +} + +/*************************************************************** +... +***************************************************************/ +void game_init(void) +{ + int i; + game.is_new_game = TRUE; + game.tcptimeout = GAME_DEFAULT_TCPTIMEOUT; + game.netwait = GAME_DEFAULT_NETWAIT; + game.last_ping = 0; + game.pingtimeout = GAME_DEFAULT_PINGTIMEOUT; + game.pingtime = GAME_DEFAULT_PINGTIME; + game.heating = 0; game.cooling = 0; sz_strlcpy(game.save_name, GAME_DEFAULT_SAVE_NAME); @@ -707,9 +725,6 @@ void game_init(void) #else game.save_compress_level = GAME_NO_COMPRESS_LEVEL; #endif - game.randseed=GAME_DEFAULT_RANDSEED; - game.watchtower_vision=GAME_DEFAULT_WATCHTOWER_VISION; - game.watchtower_extra_vision=GAME_DEFAULT_WATCHTOWER_EXTRA_VISION, game.allowed_city_names = GAME_DEFAULT_ALLOWED_CITY_NAMES; sz_strlcpy(game.rulesetdir, GAME_DEFAULT_RULESETDIR); @@ -740,7 +755,6 @@ void game_init(void) game.load_options.load_settings = TRUE; init_our_capability(); - map_init(); idex_init(); for(i=0; i> 1); 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 == 5 ) @@ -1167,18 +1204,49 @@ void map_fractal_generate(void) mapgenerator2(); if( map.generator == 1 ) mapgenerator1(); - if (!map.tinyisles) { - remove_tiny_islands(); - } } - if(!map.have_specials) /* some scenarios already provide specials */ + if(!map.have_heightmap && !map.have_tilemap) { + /* The mapgenerator failed, or we loaded an empty scenario. */ + freelog(LOG_FATAL, "mapgen.c: This map contains neither a heightmap not a tilemap."); + abort(); + } + + if(!map.have_tilemap) { + /* we don't have a tilemap, so we must have a heightmap. */ + assert(map.have_heightmap); + map_allocate(); + make_land(); + } + + if(!map.have_heightmap) { + /* we don't have a heightmap, so we must have a tilemap. */ + assert(map.have_tilemap); + tiles_to_heightmap(); + } + + if (!map.tinyisles) { + remove_tiny_islands(); + } + + if(!map.have_rivers_overlay) { + make_rivers(); + } + + if(!map.have_specials) { /* some scenarios already provide specials */ add_specials(map.riches); /* hvor mange promiller specials oensker vi*/ + } - if (!map.have_huts) + if (!map.have_huts) { make_huts(map.huts); /* Vi vil have store promiller; man kan aldrig faa - for meget oel! */ + * for meget oel! */ + } + /* we no longer need the height map. + * Note that we might want to keep it eventually. */ + free(height_map); + height_map = NULL; + /* restore previous random state: */ set_myrand_state(rstate); } @@ -1220,8 +1288,18 @@ void adjust_terrain_param(void) i reduce the height so the lowest height is zero, this makes calculations easier **************************************************************************/ -static void adjust_map(int minval) +void adjust_map(void) { + unsigned int minval = MAX_UINT32; + 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; + whole_map_iterate(x, y) { hmap(x, y) -= minval; } whole_map_iterate_end; @@ -1233,8 +1311,6 @@ static void adjust_map(int minval) static void mapgenerator1(void) { int i; - int minval=5000000; - height_map=fc_malloc (sizeof(int)*map.xsize*map.ysize); adjust_terrain_param(); @@ -1256,19 +1332,12 @@ static void mapgenerator1(void) smooth_map(); smooth_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; + adjust_map(); - maxval-=minval; - adjust_map(minval); - - make_land(); - free(height_map); - height_map = NULL; + /* this generator provides a heightmap, but no tilemap. */ + map.have_tilemap = FALSE; + map.have_heightmap = TRUE; + map.have_rivers_overlay = FALSE; } /************************************************************************** @@ -1743,7 +1812,7 @@ static void initworld(struct gen234_stat { int x, y; - height_map = fc_malloc(sizeof(int) * map.ysize * map.xsize); + //height_map = fc_malloc(sizeof(int) * map.ysize * map.xsize); islands = fc_malloc((MAP_NCONT+1)*sizeof(struct isledata)); for (y = 0 ; y < map.ysize ; y++) @@ -1788,6 +1857,8 @@ static void mapgenerator2(void) return; } + map_allocate(); /* we're making a tilemap, not a heightmap. */ + adjust_terrain_param(); pstate->totalmass = ((map.ysize - 6 - spares) * map.landpercent * (map.xsize - spares)) / @@ -1815,12 +1886,15 @@ static void mapgenerator2(void) make_island(10 * pstate->totalmass / totalweight, 0, pstate); } make_plains(); - free(height_map); - height_map = NULL; if(checkmass>map.xsize+map.ysize+totalweight) { freelog(LOG_VERBOSE, "%ld mass left unplaced", checkmass); } + + /* this generator provides a tilemap and rivers, but no heightmap. */ + map.have_tilemap = TRUE; + map.have_heightmap = FALSE; + map.have_rivers_overlay = TRUE; } /************************************************************************** @@ -1842,6 +1916,8 @@ static void mapgenerator3(void) return; } + map_allocate(); /* we're making a tilemap, not a heightmap. */ + adjust_terrain_param(); pstate->totalmass = ((map.ysize - 6 - spares) * map.landpercent * (map.xsize - spares)) / @@ -1900,8 +1976,6 @@ static void mapgenerator3(void) } make_plains(); - free(height_map); - height_map = NULL; if(j==1500) { freelog(LOG_NORMAL, _("Generator 3 left %li landmass unplaced."), checkmass); @@ -1909,6 +1983,10 @@ static void mapgenerator3(void) freelog(LOG_VERBOSE, "%ld mass left unplaced", checkmass); } + /* this generator provides a tilemap and rivers, but no heightmap. */ + map.have_tilemap = TRUE; + map.have_heightmap = FALSE; + map.have_rivers_overlay = TRUE; } /************************************************************************** @@ -1922,7 +2000,6 @@ static void mapgenerator4(void) struct gen234_state state; struct gen234_state *pstate = &state; - /* no islands with mass >> sqr(min(xsize,ysize)) */ i = game.nplayers / 2; @@ -1931,6 +2008,8 @@ static void mapgenerator4(void) return; } + map_allocate(); /* we're making a tilemap, not a heightmap. */ + if(map.landpercent>60) bigweight=30; else if(map.landpercent>40) @@ -1976,12 +2055,15 @@ static void mapgenerator4(void) make_island(10 * pstate->totalmass / totalweight, 0, pstate); } make_plains(); - free(height_map); - height_map = NULL; if(checkmass>map.xsize+map.ysize+totalweight) { freelog(LOG_VERBOSE, "%ld mass left unplaced", checkmass); } + + /* this generator provides a tilemap and rivers, but no heightmap. */ + map.have_tilemap = TRUE; + map.have_heightmap = FALSE; + map.have_rivers_overlay = TRUE; } /************************************************************************** @@ -2045,7 +2127,7 @@ blocks and on each block raising or lowe midpoints and middle and so on recursively. Fiddling with 'xdiv' and 'ydiv' will change the size of the initial blocks and, if the map does not wrap in at least one direction, fiddling with 'avoidedge' will change the -liklihood of continents butting up to non-wrapped edges. +likelihood of continents butting up to non-wrapped edges. **************************************************************************/ static void mapgenerator5(void) { @@ -2070,8 +2152,6 @@ static void mapgenerator5(void) /* edges are avoided more strongly as this increases */ int avoidedge = (50 - map.landpercent) * step / 100 + step / 3; - height_map = fc_malloc(sizeof(int) * map.xsize * map.ysize); - adjust_terrain_param(); /* initialize map */ @@ -2127,16 +2207,10 @@ static void mapgenerator5(void) whole_map_iterate(x, y) { /* put in some random fuzz */ hmap(x, y) = 8 * hmap(x, y) + myrand(4) - 2; - /* and calibrate maxval and minval */ - 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); + adjust_map(); - make_land(); - free(height_map); - height_map = NULL; + /* this generator provides a heightmap, but not tilemap. */ + map.have_tilemap = FALSE; + map.have_heightmap = TRUE; } Index: server/mapgen.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/mapgen.h,v retrieving revision 1.10 diff -u -3 -p -r1.10 mapgen.h --- server/mapgen.h 2002/02/05 19:05:51 1.10 +++ server/mapgen.h 2003/04/24 01:14:47 @@ -13,9 +13,14 @@ #ifndef FC__MAPGEN_H #define FC__MAPGEN_H +/* Wrapper for easy access. It's a macro so it can be a lvalue. */ +#define hmap(x, y) (height_map[map_pos_to_index(x, y)]) +#define rmap(x, y) (river_map[map_pos_to_index(x, y)]) + void assign_continent_numbers(void); void map_fractal_generate(void); void create_start_positions(void); void adjust_terrain_param(void); +void adjust_map(void); #endif /* FC__MAPGEN_H */ Index: server/savegame.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v retrieving revision 1.116 diff -u -3 -p -r1.116 savegame.c --- server/savegame.c 2003/04/22 20:50:56 1.116 +++ server/savegame.c 2003/04/24 01:14:49 @@ -52,6 +52,9 @@ #include "savegame.h" +extern int *height_map; +#include "mapgen.h" + /* * This loops over the entire map to save data. It collects all the * data of a line using get_xy_char and then executes the @@ -114,14 +117,14 @@ * we let any map data type to be empty, and just print an * informative warning message about it. */ -#define LOAD_MAP_DATA(secfile_lookup_line, set_xy_char) \ +#define LOAD_MAP_DATA(secfile_lookup_line, set_xy_char, nibbles) \ { \ int y; \ bool warning_printed = FALSE; \ for (y = 0; y < map.ysize; y++) { \ char *line = secfile_lookup_line; \ int x; \ - if (!line || strlen(line) != map.xsize) { \ + if (!line || strlen(line) != map.xsize*nibbles) { \ if(!warning_printed) { \ freelog(LOG_ERROR, _("The save file contains incomplete " \ "map data. This can happen with old saved " \ @@ -130,8 +133,8 @@ if(!line) { \ freelog(LOG_ERROR, _("Reason: line not found")); \ } else { \ - freelog(LOG_ERROR, _("Reason: line too short " \ - "(expected %d got %lu"), map.xsize, \ + freelog(LOG_ERROR, _("Reason: line wrong length " \ + "(expected %d got %lu)"), map.xsize*nibbles, \ (unsigned long) strlen(line)); \ } \ freelog(LOG_ERROR, "secfile_lookup_line='%s'", \ @@ -140,21 +143,26 @@ } \ continue; \ } \ - for(x = 0; x < map.xsize; x++) { \ - char ch = line[x]; \ - if (regular_map_pos_is_normal(x, y)) { \ + for(x = 0; x < map.xsize * nibbles; x += nibbles) { \ + char ch[nibbles]; \ + int nib; \ + for(nib = 0; nib < nibbles; nib++) { \ + ch[nib] = line[x+nib]; \ + } \ + if (regular_map_pos_is_normal(x/nibbles, y)) { \ set_xy_char; \ } else { \ - assert(ch == '#'); \ + assert(ch[0] == '#'); /* ??? CJM */ \ } \ } \ } \ } /* The following should be removed when compatibility with - pre-1.13.0 savegames is broken: startoptions, spacerace2 - and rulesets */ -#define SAVEFILE_OPTIONS "startoptions spacerace2 rulesets" \ + * pre-1.13.0 savegames is broken: spacerace2 + * and rulesets. Note that startoptions is no longer needed, even without + * breaking compatibility with 1.9.0. */ +#define SAVEFILE_OPTIONS "spacerace2 rulesets" \ " diplchance_percent worklists2 map_editor known32fix turn " \ "attributes watchtower rulesetdir client_worklists" @@ -264,6 +272,46 @@ static int unquote_block(const char *con } /*************************************************************** +Load specials only, ignoring rivers (which are stored in the same word). +***************************************************************/ +static void map_specials_load(struct section_file *file) +{ + LOAD_MAP_DATA(secfile_lookup_str(file, "map.l%03d", y), + map_get_tile(x, y)->special = + (map_get_tile(x, y)->special & S_RIVER) | + (ascii_hex2bin(ch[0], 0) & ~S_RIVER),1); + LOAD_MAP_DATA(secfile_lookup_str(file, "map.u%03d", y), + map_get_tile(x, y)->special |= + (ascii_hex2bin(ch[0], 1) & ~S_RIVER),1); + LOAD_MAP_DATA(secfile_lookup_str_default(file, NULL, "map.n%03d", y), + map_get_tile(x, y)->special |= + (ascii_hex2bin(ch[0], 2) & ~S_RIVER),1); + LOAD_MAP_DATA(secfile_lookup_str_default(file, NULL, "map.f%03d", y), + map_get_tile(x, y)->special |= + (ascii_hex2bin(ch[0], 3) & ~S_RIVER),1); +} + +/*************************************************************** +Load height map. Note that this is stored as one set of long lines, +using 4 nibbles (16 bits) each. Note that the nibbles are big-endian, +ie they read they way you might expect. +***************************************************************/ +static void map_height_load(struct section_file *file) +{ + const int size = 4; /* how many nibbles per data value? */ + + LOAD_MAP_DATA(secfile_lookup_str(file, "map.H%03d", y), + hmap(x/size,y) = (ascii_hex2bin(ch[0], 3) | + ascii_hex2bin(ch[1], 2) | + ascii_hex2bin(ch[2], 1) | + ascii_hex2bin(ch[3], 0)), size); + + adjust_map(); /* fix maxval and minval for mapgen */ + + map.have_heightmap = TRUE; +} + +/*************************************************************** load starting positions for the players from a savegame file Now we don't know how many start positions there are nor how many should be because rulesets are loaded later. So try to load as @@ -298,10 +346,11 @@ load the tile map from a savegame file ***************************************************************/ static void map_tiles_load(struct section_file *file) { - map.is_earth=secfile_lookup_bool(file, "map.is_earth"); + map.is_earth = secfile_lookup_bool_default(file, FALSE, "map.is_earth"); + map.have_tilemap = TRUE; /* In some cases we read these before, but not always, and - * its safe to read them again: + * it's safe to read them again: */ map.xsize=secfile_lookup_int(file, "map.width"); map.ysize=secfile_lookup_int(file, "map.height"); @@ -310,27 +359,22 @@ static void map_tiles_load(struct sectio /* get the terrain type */ LOAD_MAP_DATA(secfile_lookup_str(file, "map.t%03d", y), - map_get_tile(x, y)->terrain = char2terrain(ch)); + map_get_tile(x, y)->terrain = char2terrain(ch[0]), 1); assign_continent_numbers(); } /*************************************************************** -load the rivers overlay map from a savegame file - -(This does not need to be called from map_load(), because - map_load() loads the rivers overlay along with the rest of - the specials. Call this only if you've already called - map_tiles_load(), and want to overlay rivers defined as - specials, rather than as terrain types.) +load the rivers overlay map from a savegame file. ***************************************************************/ static void map_rivers_overlay_load(struct section_file *file) { /* Get the bits of the special flags which contain the river special and extract the rivers overlay from them. */ LOAD_MAP_DATA(secfile_lookup_str_default(file, NULL, "map.n%03d", y), - map_get_tile(x, y)->special |= - (ascii_hex2bin(ch, 2) & S_RIVER)); + map_get_tile(x, y)->special = + (map_get_tile(x, y)->special & ~S_RIVER) | + (ascii_hex2bin(ch[0], 2) & S_RIVER), 1); map.have_rivers_overlay = TRUE; } @@ -341,11 +385,6 @@ static void map_load(struct section_file { char *savefile_options = secfile_lookup_str(file, "savefile.options"); - /* map_init(); - * This is already called in game_init(), and calling it - * here stomps on map.huts etc. --dwp - */ - map_tiles_load(file); if (secfile_lookup_bool_default(file, TRUE, "game.save_starts") && game.load_options.load_starts) { @@ -355,39 +394,35 @@ static void map_load(struct section_file map.fixed_start_positions = FALSE; } - /* get 4-bit segments of 16-bit "special" field. */ - LOAD_MAP_DATA(secfile_lookup_str(file, "map.l%03d", y), - map_get_tile(x, y)->special = ascii_hex2bin(ch, 0)); - LOAD_MAP_DATA(secfile_lookup_str(file, "map.u%03d", y), - map_get_tile(x, y)->special |= ascii_hex2bin(ch, 1)); - LOAD_MAP_DATA(secfile_lookup_str_default(file, NULL, "map.n%03d", y), - map_get_tile(x, y)->special |= ascii_hex2bin(ch, 2)); - LOAD_MAP_DATA(secfile_lookup_str_default(file, NULL, "map.f%03d", y), - map_get_tile(x, y)->special |= ascii_hex2bin(ch, 3)); + /* load specials and rivers; we actually waste a bit of speed here, + * since the rivers and specials are stored together. But it makes + * the code more maintainable. */ + map_specials_load(file); + map_rivers_overlay_load(file); if (secfile_lookup_bool_default(file, TRUE, "game.save_known") && game.load_options.load_known) { /* get 4-bit segments of the first half of the 32-bit "known" field */ LOAD_MAP_DATA(secfile_lookup_str(file, "map.a%03d", y), - map_get_tile(x, y)->known = ascii_hex2bin(ch, 0)); + map_get_tile(x, y)->known = ascii_hex2bin(ch[0], 0), 1); LOAD_MAP_DATA(secfile_lookup_str(file, "map.b%03d", y), - map_get_tile(x, y)->known |= ascii_hex2bin(ch, 1)); + map_get_tile(x, y)->known |= ascii_hex2bin(ch[0], 1), 1); LOAD_MAP_DATA(secfile_lookup_str(file, "map.c%03d", y), - map_get_tile(x, y)->known |= ascii_hex2bin(ch, 2)); + map_get_tile(x, y)->known |= ascii_hex2bin(ch[0], 2), 1); LOAD_MAP_DATA(secfile_lookup_str(file, "map.d%03d", y), - map_get_tile(x, y)->known |= ascii_hex2bin(ch, 3)); + map_get_tile(x, y)->known |= ascii_hex2bin(ch[0], 3), 1); if (has_capability("known32fix", savefile_options)) { /* get 4-bit segments of the second half of the 32-bit "known" field */ LOAD_MAP_DATA(secfile_lookup_str(file, "map.e%03d", y), - map_get_tile(x, y)->known |= ascii_hex2bin(ch, 4)); + map_get_tile(x, y)->known |= ascii_hex2bin(ch[0], 4), 1); LOAD_MAP_DATA(secfile_lookup_str(file, "map.g%03d", y), - map_get_tile(x, y)->known |= ascii_hex2bin(ch, 5)); + map_get_tile(x, y)->known |= ascii_hex2bin(ch[0], 5), 1); LOAD_MAP_DATA(secfile_lookup_str(file, "map.h%03d", y), - map_get_tile(x, y)->known |= ascii_hex2bin(ch, 6)); + map_get_tile(x, y)->known |= ascii_hex2bin(ch[0], 6), 1); LOAD_MAP_DATA(secfile_lookup_str(file, "map.i%03d", y), - map_get_tile(x, y)->known |= ascii_hex2bin(ch, 7)); + map_get_tile(x, y)->known |= ascii_hex2bin(ch[0], 7), 1); } } @@ -1167,37 +1202,37 @@ static void player_map_load(struct playe && game.load_options.load_private_map) { LOAD_MAP_DATA(secfile_lookup_str(file, "player%d.map_t%03d", plrno, y), map_get_player_tile(x, y, plr)->terrain = - char2terrain(ch)); + char2terrain(ch[0]), 1); /* get 4-bit segments of 12-bit "special" field. */ LOAD_MAP_DATA(secfile_lookup_str(file, "player%d.map_l%03d", plrno, y), map_get_player_tile(x, y, plr)->special = - ascii_hex2bin(ch, 0)); + ascii_hex2bin(ch[0], 0), 1); LOAD_MAP_DATA(secfile_lookup_str(file, "player%d.map_u%03d", plrno, y), map_get_player_tile(x, y, plr)->special |= - ascii_hex2bin(ch, 1)); + ascii_hex2bin(ch[0], 1), 1); LOAD_MAP_DATA(secfile_lookup_str_default (file, NULL, "player%d.map_n%03d", plrno, y), map_get_player_tile(x, y, plr)->special |= - ascii_hex2bin(ch, 2)); + ascii_hex2bin(ch[0], 2), 1); /* get 4-bit segments of 16-bit "updated" field */ LOAD_MAP_DATA(secfile_lookup_str (file, "player%d.map_ua%03d", plrno, y), map_get_player_tile(x, y, plr)->last_updated = - ascii_hex2bin(ch, 0)); + ascii_hex2bin(ch[0], 0),1); LOAD_MAP_DATA(secfile_lookup_str (file, "player%d.map_ub%03d", plrno, y), map_get_player_tile(x, y, plr)->last_updated |= - ascii_hex2bin(ch, 1)); + ascii_hex2bin(ch[0], 1),1); LOAD_MAP_DATA(secfile_lookup_str (file, "player%d.map_uc%03d", plrno, y), map_get_player_tile(x, y, plr)->last_updated |= - ascii_hex2bin(ch, 2)); + ascii_hex2bin(ch[0], 2),1); LOAD_MAP_DATA(secfile_lookup_str (file, "player%d.map_ud%03d", plrno, y), map_get_player_tile(x, y, plr)->last_updated |= - ascii_hex2bin(ch, 3)); + ascii_hex2bin(ch[0], 3),1); { int j; @@ -1778,34 +1813,49 @@ void game_load(struct section_file *file "game.metaserver")); meta_addr_split(); - game.gold = secfile_lookup_int(file, "game.gold"); - game.tech = secfile_lookup_int(file, "game.tech"); - game.skill_level = secfile_lookup_int(file, "game.skill_level"); + game.gold = + secfile_lookup_int_default(file, game.gold, "game.gold"); + game.tech = + secfile_lookup_int_default(file, game.tech, "game.tech"); + game.skill_level = + secfile_lookup_int_default(file, game.skill_level, "game.skill_level"); if (game.skill_level==0) game.skill_level = GAME_OLD_DEFAULT_SKILL_LEVEL; - game.timeout = secfile_lookup_int(file, "game.timeout"); - game.timeoutint = secfile_lookup_int_default(file, - GAME_DEFAULT_TIMEOUTINT, - "game.timeoutint"); + game.timeout = + secfile_lookup_int_default(file, game.timeout, "game.timeout"); + game.timeoutint = + secfile_lookup_int_default(file, game.timeoutint, "game.timeoutint"); game.timeoutintinc = - secfile_lookup_int_default(file, GAME_DEFAULT_TIMEOUTINTINC, - "game.timeoutintinc"); + secfile_lookup_int_default(file, game.timeoutintinc, + "game.timeoutintinc"); game.timeoutinc = - secfile_lookup_int_default(file, GAME_DEFAULT_TIMEOUTINC, - "game.timeoutinc"); + secfile_lookup_int_default(file, game.timeoutinc, "game.timeoutinc"); game.timeoutincmult = - secfile_lookup_int_default(file, GAME_DEFAULT_TIMEOUTINCMULT, - "game.timeoutincmult"); + secfile_lookup_int_default(file, game.timeoutincmult, + "game.timeoutincmult"); game.timeoutcounter = - secfile_lookup_int_default(file, 1, "game.timeoutcounter"); + secfile_lookup_int_default(file, game.timeoutcounter, + "game.timeoutcounter"); - game.end_year = secfile_lookup_int(file, "game.end_year"); - game.researchcost = secfile_lookup_int_default(file, 0, "game.researchcost"); - if (game.researchcost == 0) - game.researchcost = secfile_lookup_int(file, "game.techlevel"); + game.end_year = + secfile_lookup_int_default(file, game.end_year, "game.end_year"); + + { + /* Savefiles as recent as 1.9.0 called researchcost "techlevel. + * So save the current researchcost, and try to load researchcost + * from the file; it we fail, try to load techlevel, but fall back + * to what was there before. */ + int rcost = game.researchcost; + game.researchcost = + secfile_lookup_int_default(file, 0, "game.researchcost"); + if (game.researchcost == 0) { + game.researchcost = + secfile_lookup_int_default(file, rcost, "game.techlevel"); + } + } - game.year = secfile_lookup_int(file, "game.year"); + game.year = secfile_lookup_int_default(file, game.year, "game.year"); if (has_capability("turn", savefile_options)) { game.turn = secfile_lookup_int(file, "game.turn"); @@ -1813,72 +1863,87 @@ void game_load(struct section_file *file game.turn = -2; } - game.min_players = secfile_lookup_int(file, "game.min_players"); - game.max_players = secfile_lookup_int(file, "game.max_players"); - game.nplayers = secfile_lookup_int(file, "game.nplayers"); - game.globalwarming = secfile_lookup_int(file, "game.globalwarming"); - game.warminglevel = secfile_lookup_int(file, "game.warminglevel"); - game.nuclearwinter = secfile_lookup_int_default(file, 0, "game.nuclearwinter"); - game.coolinglevel = secfile_lookup_int_default(file, 8, "game.coolinglevel"); - game.notradesize = secfile_lookup_int_default(file, 0, "game.notradesize"); - game.fulltradesize = secfile_lookup_int_default(file, 1, "game.fulltradesize"); - game.unhappysize = secfile_lookup_int(file, "game.unhappysize"); - game.angrycitizen = secfile_lookup_bool_default(file, FALSE, "game.angrycitizen"); - - if (game.version >= 10100) { - game.cityfactor = secfile_lookup_int(file, "game.cityfactor"); - game.diplcost = secfile_lookup_int(file, "game.diplcost"); - game.freecost = secfile_lookup_int(file, "game.freecost"); - game.conquercost = secfile_lookup_int(file, "game.conquercost"); - game.foodbox = secfile_lookup_int(file, "game.foodbox"); - game.techpenalty = secfile_lookup_int(file, "game.techpenalty"); - game.razechance = secfile_lookup_int(file, "game.razechance"); - - /* suppress warnings about unused entries in old savegames: */ - (void) section_file_lookup(file, "game.rail_food"); - (void) section_file_lookup(file, "game.rail_prod"); - (void) section_file_lookup(file, "game.rail_trade"); - (void) section_file_lookup(file, "game.farmfood"); - } - if (game.version >= 10300) { - game.civstyle = secfile_lookup_int_default(file, 0, "game.civstyle"); - game.save_nturns = secfile_lookup_int(file, "game.save_nturns"); - } + game.min_players = + secfile_lookup_int_default(file, game.min_players, "game.min_players"); + game.max_players = + secfile_lookup_int_default(file, game.max_players, "game.max_players"); + game.nplayers = + secfile_lookup_int_default(file, game.nplayers, "game.nplayers"); + game.globalwarming = + secfile_lookup_int_default(file, game.globalwarming, + "game.globalwarming"); + game.warminglevel = + secfile_lookup_int_default(file, game.warminglevel, "game.warminglevel"); + game.nuclearwinter = + secfile_lookup_int_default(file, 0, "game.nuclearwinter"); + game.coolinglevel = + secfile_lookup_int_default(file, 8, "game.coolinglevel"); + game.notradesize = + secfile_lookup_int_default(file, 0, "game.notradesize"); + game.fulltradesize = + secfile_lookup_int_default(file, 1, "game.fulltradesize"); + game.unhappysize = + secfile_lookup_int_default(file, game.unhappysize, "game.unhappysize"); + game.angrycitizen = + secfile_lookup_bool_default(file, FALSE, "game.angrycitizen"); + + /* These options are valid for game.version >= 1.1.0, + * but we already require 1.9.0. */ + game.cityfactor = + secfile_lookup_int_default(file, game.cityfactor, "game.cityfactor"); + game.diplcost = + secfile_lookup_int_default(file, game.diplcost, "game.diplcost"); + game.freecost = + secfile_lookup_int_default(file, game.freecost, "game.freecost"); + game.conquercost = + secfile_lookup_int_default(file, game.conquercost, "game.conquercost"); + game.foodbox = + secfile_lookup_int_default(file, game.foodbox, "game.foodbox"); + game.techpenalty = + secfile_lookup_int_default(file, game.techpenalty, "game.techpenalty"); + game.razechance = + secfile_lookup_int_default(file, game.razechance, "game.razechance"); + + /* These options are valid for game.version >= 1.3.0, + * but we already require 1.9.0. */ + game.civstyle = + secfile_lookup_int_default(file, game.civstyle, "game.civstyle"); + game.save_nturns = + secfile_lookup_int_default(file, game.save_nturns, "game.save_nturns"); game.citymindist = secfile_lookup_int_default(file, - GAME_DEFAULT_CITYMINDIST, "game.citymindist"); + game.citymindist, "game.citymindist"); game.rapturedelay = secfile_lookup_int_default(file, - GAME_DEFAULT_RAPTUREDELAY, "game.rapturedelay"); + game.rapturedelay, "game.rapturedelay"); - if (has_capability("watchtower", savefile_options)) { + /* If these aren't defined in the file, use the current values. */ game.watchtower_extra_vision = - secfile_lookup_int(file, "game.watchtower_extra_vision"); + secfile_lookup_int_default(file, game.watchtower_extra_vision, + "game.watchtower_extra_vision"); game.watchtower_vision = - secfile_lookup_int(file, "game.watchtower_vision"); - } else { - game.watchtower_extra_vision = 0; - game.watchtower_vision = 1; - } + secfile_lookup_int_default(file, game.watchtower_vision, + "game.watchtower_vision"); sz_strlcpy(game.save_name, - secfile_lookup_str_default(file, GAME_DEFAULT_SAVE_NAME, + secfile_lookup_str_default(file, game.save_name, "game.save_name")); - game.aifill = secfile_lookup_int_default(file, 0, "game.aifill"); + game.aifill = + secfile_lookup_int_default(file, game.aifill, "game.aifill"); - game.scorelog = secfile_lookup_bool_default(file, FALSE, "game.scorelog"); + game.scorelog = + secfile_lookup_bool_default(file, game.scorelog, "game.scorelog"); sz_strlcpy(game.id, secfile_lookup_str_default(file, "", "game.id")); - game.fogofwar = secfile_lookup_bool_default(file, FALSE, "game.fogofwar"); + game.fogofwar = secfile_lookup_bool_default(file, game.fogofwar, + "game.fogofwar"); game.fogofwar_old = game.fogofwar; - game.civilwarsize = - secfile_lookup_int_default(file, GAME_DEFAULT_CIVILWARSIZE, - "game.civilwarsize"); + game.civilwarsize = secfile_lookup_int_default(file, game.civilwarsize, + "game.civilwarsize"); game.contactturns = - secfile_lookup_int_default(file, GAME_DEFAULT_CONTACTTURNS, - "game.contactturns"); + secfile_lookup_int_default(file, game.contactturns, "game.contactturns"); if(has_capability("diplchance_percent", savefile_options)) { game.diplchance = secfile_lookup_int_default(file, game.diplchance, @@ -1980,64 +2045,120 @@ void game_load(struct section_file *file } { - if (game.version >= 10300) { - if (game.load_options.load_settings) { - game.settlers = secfile_lookup_int(file, "game.settlers"); - game.explorer = secfile_lookup_int(file, "game.explorer"); - game.dispersion = - secfile_lookup_int_default(file, GAME_DEFAULT_DISPERSION, "game.dispersion"); - } - - map.riches = secfile_lookup_int(file, "map.riches"); - map.huts = secfile_lookup_int(file, "map.huts"); - map.generator = secfile_lookup_int(file, "map.generator"); - map.seed = secfile_lookup_int(file, "map.seed"); - map.landpercent = secfile_lookup_int(file, "map.landpercent"); - map.grasssize = - secfile_lookup_int_default(file, MAP_DEFAULT_GRASS, "map.grasssize"); - map.swampsize = secfile_lookup_int(file, "map.swampsize"); - map.deserts = secfile_lookup_int(file, "map.deserts"); - map.riverlength = secfile_lookup_int(file, "map.riverlength"); - map.mountains = secfile_lookup_int(file, "map.mountains"); - map.forestsize = secfile_lookup_int(file, "map.forestsize"); - map.have_huts = secfile_lookup_bool_default(file, TRUE, "map.have_huts"); - - if (has_capability("startoptions", savefile_options)) { - map.xsize = secfile_lookup_int(file, "map.width"); - map.ysize = secfile_lookup_int(file, "map.height"); - } else { - /* old versions saved with these names in PRE_GAME_STATE: */ - map.xsize = secfile_lookup_int(file, "map.xsize"); - map.ysize = secfile_lookup_int(file, "map.ysize"); - } - - if (tmp_server_state==PRE_GAME_STATE - && map.generator == 0 - && !has_capability("map_editor",savefile_options)) { - /* generator 0 = map done with map editor */ - /* aka a "scenario" */ - if (has_capability("specials",savefile_options)) { - map_load(file); - map.fixed_start_positions = TRUE; - return; - } - map_tiles_load(file); - if (has_capability("riversoverlay",savefile_options)) { + if (game.load_options.load_settings) { + game.settlers = + secfile_lookup_int_default(file, game.settlers, "game.settlers"); + game.explorer = + secfile_lookup_int_default(file, game.explorer, "game.explorer"); + game.dispersion = + secfile_lookup_int_default(file, game.dispersion, "game.dispersion"); + } + + map.riches = + secfile_lookup_int_default(file, map.riches, "map.riches"); + map.huts = + secfile_lookup_int_default(file, map.huts, "map.huts"); + map.generator = /* Only broken maps (ie those made by external generators) + * are likely to forget to set the generator. */ + secfile_lookup_int_default(file, 0, "map.generator"); + map.seed = + secfile_lookup_int_default(file, map.seed, "map.seed"); + map.landpercent = + secfile_lookup_int_default(file, map.landpercent, "map.landpercent"); + map.grasssize = + secfile_lookup_int_default(file, map.grasssize, "map.grasssize"); + map.swampsize = + secfile_lookup_int_default(file, map.swampsize, "map.swampsize"); + map.deserts = + secfile_lookup_int_default(file, map.deserts, "map.deserts"); + map.riverlength = + secfile_lookup_int_default(file, map.riverlength, "map.riverlength"); + map.mountains = + secfile_lookup_int_default(file, map.mountains, "map.mountains"); + map.forestsize = + secfile_lookup_int_default(file, map.forestsize, "map.forestsize"); + map.have_huts = + secfile_lookup_bool_default(file, TRUE, "map.have_huts"); + + /* extremely old savegames used xsize and ysize instead of + * width and height. But that was old even in in 1.9.0, which + * is the oldest savegame we support. */ + map.xsize = secfile_lookup_int(file, "map.width"); + map.ysize = secfile_lookup_int(file, "map.height"); + + map.tinyisles = + secfile_lookup_bool_default(file, map.tinyisles, "map.tinyisles"); + map.separatepoles = + secfile_lookup_bool_default(file, map.separatepoles,"map.separatepoles"); + + if (tmp_server_state==PRE_GAME_STATE) { + if(map.generator == 0) { + freelog(LOG_DEBUG, "Anticipating possibly-incomplete scenario map"); + + /* It's a map not generated by us, and may be incomplete. + * 1. Try to load height map. + * 2. Load tile map, or make a tile map from the height map + * using the standard land placing algorithm, or + * exit with an error. + * 3. Load specials, or make them up; load rivers, or make them up; + * load starting positions, or make them up. + */ + + /* try to load height map ... */ + if(has_capability("heightmap", savefile_options)) { + freelog(LOG_DEBUG, "Reading heightmap"); + height_map=fc_calloc (map.xsize*map.ysize, sizeof(int)); + + /* actually read it. */ + map_height_load(file); + + /* now even if we have a height map, we may still have tiles, + * but not, for example, rivers. So if we have a height map, + * we have to say if we also have a tile map. */ + if(has_capability("tilemap", savefile_options)) { + freelog(LOG_DEBUG, "Tilemap also exists; reading it"); + map_tiles_load(file); + } + } else { + /* no height map; we must have a tile map. Load it. */ + map_tiles_load(file); + } + + /* load specials. If we don't have them here, we'll make them later. */ + if(has_capability("specials", savefile_options)) { + map_specials_load(file); + map.have_specials = TRUE; + } else { + /* in mapgen we'll add specials */ + map.have_specials = FALSE; + } + + /* load rivers */ + if(has_capability("riversoverlay", savefile_options)) { map_rivers_overlay_load(file); + map.have_rivers_overlay = TRUE; + } else { + /* in mapgen we'll make up some rivers */ + map.have_rivers_overlay = FALSE; } - if (has_capability("startpos",savefile_options)) { - map_startpos_load(file); - map.fixed_start_positions = TRUE; - return; - } + + if(has_capability("startpos", savefile_options)) { + /* load starting positions, and record that we have them. + * we'll make them up later if there aren't any. */ + map_startpos_load(file); + } + return; } - } - if(tmp_server_state==PRE_GAME_STATE) { + + /* server state is not PRE_GAME_STATE, but generator is non-zero. */ return; } } + /* we can only get here if the server is not in PRE_GAME_STATE, which means + * it's a real savegame, not a scenario or partial map. */ + /* We check 1) if the block exists at all. 2) if it is saved. */ @@ -2181,7 +2302,7 @@ void game_save(struct section_file *file if (map.have_specials) { sz_strlcat(options, " specials"); } - if (map.have_rivers_overlay && !map.have_specials) { + if (map.have_rivers_overlay) { sz_strlcat(options, " riversoverlay"); } } Index: server/srv_main.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v retrieving revision 1.123 diff -u -3 -p -r1.123 srv_main.c --- server/srv_main.c 2003/04/17 20:06:37 1.123 +++ server/srv_main.c 2003/04/24 01:14:50 @@ -1545,7 +1545,7 @@ void srv_main(void) con_flush(); - game_init(); + full_game_init(); /* init network */ init_connections();