------------------------------------------------------------------------
? 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<MAX_NUM_PLAYERS+MAX_NUM_BARBARIANS; i++)
Index: common/game.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.h,v
retrieving revision 1.121
diff -u -3 -p -r1.121 game.h
--- common/game.h 2003/04/17 20:06:36 1.121
+++ common/game.h 2003/04/24 01:14:44
@@ -227,6 +227,7 @@ struct lvldat {
int advspeed;
};
+void full_game_init(void);
void game_init(void);
void game_free(void);
void ruleset_data_free(void);
Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.138
diff -u -3 -p -r1.138 map.c
--- common/map.c 2003/04/22 20:50:56 1.138
+++ common/map.c 2003/04/24 01:14:45
@@ -195,6 +195,8 @@ void map_init(void)
map.num_continents = 0;
map.num_start_positions = 0;
map.fixed_start_positions = FALSE;
+ map.have_heightmap = FALSE;
+ map.have_tilemap = FALSE;
map.have_specials = FALSE;
map.have_rivers_overlay = FALSE;
map.have_huts = FALSE;
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.145
diff -u -3 -p -r1.145 map.h
--- common/map.h 2003/04/22 20:50:56 1.145
+++ common/map.h 2003/04/24 01:14:45
@@ -171,7 +171,9 @@ struct civ_map {
bool fixed_start_positions;
bool have_specials;
bool have_huts;
- bool have_rivers_overlay; /* only applies if !have_specials */
+ bool have_heightmap;
+ bool have_tilemap;
+ bool have_rivers_overlay;
int num_continents;
struct tile *tiles;
Index: server/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/mapgen.c,v
retrieving revision 1.110
diff -u -3 -p -r1.110 mapgen.c
--- server/mapgen.c 2003/02/20 09:45:22 1.110
+++ server/mapgen.c 2003/04/24 01:14:47
@@ -31,10 +31,7 @@
#include "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)])
-
+static void tiles_to_heightmap(void);
static void make_huts(int number);
static void add_specials(int prob);
static void mapgenerator1(void);
@@ -43,7 +40,6 @@ static void mapgenerator3(void);
static void mapgenerator4(void);
static void mapgenerator5(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};
@@ -54,7 +50,7 @@ enum river_map_type {RS_BLOCKED = 0, RS_
A value of 2 means river. -Erik Sigra */
static int *river_map;
-static int *height_map;
+int *height_map;
static int maxval=0;
static int forests=0;
@@ -671,6 +667,8 @@ static void make_rivers(void)
Is needed to stop a potentially infinite loop. */
int iteration_counter = 0;
+ map.have_rivers_overlay = TRUE;
+
river_map = fc_malloc(sizeof(int)*map.xsize*map.ysize);
/* The main loop in this function. */
@@ -862,7 +860,6 @@ static void make_land(void)
make_plains();
make_polar();
make_fair();
- make_rivers();
}
/**************************************************************************
@@ -1133,6 +1130,44 @@ void create_start_positions(void)
}
/**************************************************************************
+Given a set of tiles, generate a fairly plausible height map.
+Data for this function should be extracted from the ruleset.
+**************************************************************************/
+static void tiles_to_heightmap(void)
+{
+ int heights[T_LAST];
+ int adjc_spread = 3;
+ int square_spread = 4;
+ int radius = 3;
+
+ heights[T_ARCTIC] = 100;
+ heights[T_DESERT] = 180;
+ heights[T_FOREST] = 150;
+ heights[T_GRASSLAND] = 80;
+ heights[T_HILLS] = 300;
+ heights[T_JUNGLE] = 140;
+ heights[T_MOUNTAINS] = 350;
+ heights[T_OCEAN] = 0;
+ heights[T_PLAINS] = 200;
+ heights[T_RIVER] = 90;
+ heights[T_SWAMP] = 50;
+ heights[T_TUNDRA] = 110;
+
+ maxval = 0;
+ whole_map_iterate(x, y) {
+ hmap(x, y) += heights[map_get_terrain(x, y)];
+
+ adjc_iterate(x, y, x1, y1) {
+ hmap(x1, y1) += heights[map_get_terrain(x, y)] / adjc_spread;
+ } adjc_iterate_end;
+
+ square_iterate(x, y, radius, x1, y1) {
+ hmap(x1, y1) += heights[map_get_terrain(x, y)] / square_spread;
+ } square_iterate_end;
+ } whole_map_iterate_end;
+}
+
+/**************************************************************************
See stdinhand.c for information on map generation methods.
FIXME: Some continent numbers are unused at the end of this function, fx
@@ -1145,16 +1180,18 @@ void map_fractal_generate(void)
{
/* save the current random state: */
RANDOM_STATE rstate = get_myrand_state();
-
+
+ if(!map.have_heightmap) {
+ height_map = fc_malloc(sizeof(int) * map.xsize * map.ysize);
+ }
+
if (map.seed==0)
map.seed = (myrand(MAX_UINT32) ^ time(NULL)) & (MAX_UINT32 >> 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();