X-Git-Url: http://git.pond.sub.org/?p=empserver;a=blobdiff_plain;f=src%2Futil%2Ffairland.c;h=d95282f2c60e82ee872f093ba680e1dbe47ee670;hp=63c2f7230112550fe7cd43cc54fe1a242ef8edfd;hb=9102ecce5;hpb=8cd0160176447fad9561cbc5deacba2cf9fccf32 diff --git a/src/util/fairland.c b/src/util/fairland.c index 63c2f7230..d95282f2c 100644 --- a/src/util/fairland.c +++ b/src/util/fairland.c @@ -1,11 +1,11 @@ /* * Empire - A multi-player, client/server Internet based war game. - * Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak, - * Ken Stevens, Steve McClure + * Copyright (C) 1986-2013, Dave Pare, Jeff Bailey, Thomas Ruschak, + * Ken Stevens, Steve McClure, Markus Armbruster * - * This program is free software; you can redistribute it and/or modify + * Empire is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -14,24 +14,26 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program. If not, see . * * --- * - * See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the - * related information and legal notices. It is expected that any future - * projects/authors will amend these files as needed. + * See files README, COPYING and CREDITS in the root of the source + * tree for related information and legal notices. It is expected + * that future projects/authors will amend these files as needed. * * --- * * fairland.c: Create a nice, new world - * + * * Known contributors to this file: * Ken Stevens, 1995 * Steve McClure, 1998 + * Markus Armbruster, 2004-2012 */ +#include + /* define ORE 1 to add resources, define ORE 0 if you want to use another program to add the resources */ static int ORE = 1; @@ -53,7 +55,7 @@ static int quiet = 0; #define FERT_MAX 56 /* raise OIL_MAX for more oil */ -#define OIL_MAX 33 +#define OIL_MAX 33 /* lower IRON_MIN for more iron */ #define IRON_MIN 22 @@ -64,22 +66,18 @@ static int quiet = 0; /* lower URAN_MIN for more uranium */ #define URAN_MIN 56 -#if defined(aix) || defined(linux) || defined(solaris) -#include -#endif /* aix or linux */ - +#include +#include +#include #include -#include -#include "var.h" -#include "misc.h" -#include "power.h" -#include "nat.h" -#include "sect.h" -#include "gamesdef.h" +#include +#include "chance.h" #include "file.h" -#include "xy.h" #include "optlist.h" #include "prototypes.h" +#include "sect.h" +#include "version.h" +#include "xy.h" /* do not change these 4 defines */ #define LANDMIN 1 /* plate altitude for normal land */ @@ -87,9 +85,11 @@ static int quiet = 0; #define PLATMIN 36 /* plate altitude for plateau */ #define HIGHMIN 98 /* plate altitude for mountains */ -static void qprint(const char *str); +static void qprint(const char * const fmt, ...) + ATTRIBUTE((format (printf, 1, 2))); -static const char *outfile = "newcap_script"; +#define DEFAULT_OUTFILE_NAME "newcap_script" +static const char *outfile = DEFAULT_OUTFILE_NAME; /* mark the continents with a * so you can tell them from the islands 1 = mark, 0 = don't mark. */ static int AIRPORT_MARKER = 0; @@ -98,10 +98,10 @@ static int AIRPORT_MARKER = 0; 1 = don't merge, 0 = merge. */ static int DISTINCT_ISLANDS = 1; -#define XSIZE ((WORLD_X) / 2) /* basically world x-y size */ -#define YSIZE (WORLD_Y) +static char *program_name; + #define STABLE_CYCLE 4 /* stability required for perterbed capitals */ -#define INFINITY 999 /* a number which means "BIG" */ +#define INFINITY 999 /* a number which means "BIG" */ /* these defines prevent infinite loops: */ @@ -117,63 +117,57 @@ static int DISTINCT_ISLANDS = 1; #define new_x(newx) (((newx) + WORLD_X) % WORLD_X) #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y) -#if !defined(_WIN32) -#define max(a,b) (a>b?a:b) -#endif -#define rnd(x) (random() % (x)) - -int secs; /* number of sectors grown */ -int ctot; /* total number of continents and islands grown */ -int *isecs; /* array of how large each island is */ - -int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */ -int *capx, *capy; /* location of the nc capitals */ -int *mc, mcc; /* array and counter used for stability + +static int secs; /* number of sectors grown */ +static int ctot; /* total number of continents and islands grown */ +static int *isecs; /* array of how large each island is */ + +static int nc, sc, di, sp, pm, ni, is, id; /* the 8 args to this program */ +static unsigned long rnd_seed; /* optional seed argument */ +static int *capx, *capy; /* location of the nc capitals */ +static int *mc, mcc; /* array and counter used for stability check when perturbing */ -int spike; /* are we spiking? */ -int mind; /* the final distance between capitals that +static int spike; /* are we spiking? */ +static int mind; /* the final distance between capitals that we achieved */ -int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */ -int diry[] = { 0, -1, -1, 0, 1, 1 }; - -int **own; /* owner of the sector. -1 means water */ -int **elev; /* elevation of the sectors */ -int **sectx, **secty; /* the sectors for each continent */ -int **sectc; /* which sectors are on the coast? */ -int *vector; /* used for measuring distances */ -int *weight; /* used for placing mountains */ -int *dsea, *dmoun; /* the dist to the ocean and mountain */ -int the_file; /* the file we write everything to */ -struct sctstr **sects; -struct sctstr *sectsbuf; -int fl_status; /* is anything wrong? */ -#define STATUS_NO_ROOM (1) /* there was no room to grow */ +static int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */ +static int diry[] = { 0, -1, -1, 0, 1, 1 }; + +static int **own; /* owner of the sector. -1 means water */ +static int **elev; /* elevation of the sectors */ +static int **sectx, **secty; /* the sectors for each continent */ +static int **sectc; /* which sectors are on the coast? */ +static int *vector; /* used for measuring distances */ +static int *weight; /* used for placing mountains */ +static int *dsea, *dmoun; /* the dist to the ocean and mountain */ +static int fl_status; /* is anything wrong? */ +#define STATUS_NO_ROOM 1 /* there was no room to grow */ #define NUMTRIES 10 /* keep trying to grow this many times */ -const char *numletter = +static const char *numletter = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; -void parse_args(int argc, char *argv[]); -int allocate_memory(void); -void init(void); -int drift(void); -void grow_continents(void); -void create_elevations(void); -void write_sects(void); -int write_file(void); -void output(void); -int write_newcap_script(void); -int stable(void); -void elevate_land(void); -void elevate_sea(void); -void translate_continents(void); -int map_symbol(int x, int y); -static void fl_sct_init(coord x, coord y, s_char *ptr); - -void print_vars(void); -void fl_move(int); -void next_coast(int c, int x, int y, int *xp, int *yp); -void grow_islands(void); +static void help(char *); +static void usage(void); +static void parse_args(int argc, char *argv[]); +static void allocate_memory(void); +static void init(void); +static int drift(void); +static void grow_continents(void); +static void create_elevations(void); +static void write_sects(void); +static void output(void); +static int write_newcap_script(void); +static int stable(void); +static void elevate_land(void); +static void elevate_sea(void); +static int map_symbol(int x, int y); +static void set_coastal_flags(void); + +static void print_vars(void); +static void fl_move(int); +static void next_coast(int c, int x, int y, int *xp, int *yp); +static void grow_islands(void); /**************************************************************************** MAIN @@ -183,56 +177,67 @@ int main(int argc, char *argv[]) { int opt; - extern int optind; - extern char *optarg; char *config_file = NULL; - char tbuf[512]; int i = 0; + int seed_set = 0; -#if !defined(_WIN32) - while ((opt = getopt(argc, argv, "ae:ioqs:")) != EOF) { + program_name = argv[0]; + rnd_seed = 0; + + while ((opt = getopt(argc, argv, "ae:hioqR:s:v")) != EOF) { switch (opt) { case 'a': AIRPORT_MARKER = 1; break; - case 'i': - DISTINCT_ISLANDS = 0; - break; case 'e': config_file = optarg; break; + case 'i': + DISTINCT_ISLANDS = 0; + break; case 'o': ORE = 0; break; case 'q': quiet = 1; break; + case 'R': + rnd_seed = strtoul(optarg, NULL, 10); + seed_set = 1; + break; case 's': outfile = optarg; break; + case 'h': + usage(); + exit(0); + case 'v': + printf("%s\n\n%s", version, legal); + exit(0); + default: + help(NULL); + exit(1); } } -#endif - if (config_file == NULL) { - sprintf(tbuf, "%s/econfig", datadir); - config_file = tbuf; - } - emp_config(config_file); - -#if !defined(_WIN32) parse_args(argc - optind, argv + optind); -#else - parse_args(argc - 1, argv + 1); -#endif - if (allocate_memory() == -1) - exit(-1); + + if (!seed_set) + rnd_seed = pick_seed(); + seed_prng(rnd_seed); + empfile_init(); + if (emp_config(config_file) < 0) + exit(1); + empfile_fixup(); + + allocate_memory(); print_vars(); do { init(); - if (!quiet && i) - printf("\ntry #%d (out of %d)...", i + 1, NUMTRIES); + if (i) + qprint("\ntry #%d (out of %d)...", i + 1, NUMTRIES); qprint("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n"); + qprint("seed is %lu\n", rnd_seed); qprint("placing capitals...\n"); if (!drift()) qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n"); @@ -251,16 +256,28 @@ main(int argc, char *argv[]) qprint("designating sectors...\n"); if (ORE) qprint("adding resources...\n"); + write_newcap_script(); + + if (chdir(gamedir)) { + fprintf(stderr, "Can't chdir to %s (%s)\n", gamedir, strerror(errno)); + exit(EXIT_FAILURE); + } + if (!ef_open(EF_SECTOR, EFF_MEM | EFF_NOTIME)) + exit(1); write_sects(); qprint("writing to sectors file...\n"); - if (write_file() == -1) - exit(-1); + if (!ef_close(EF_SECTOR)) + exit(1); + output(); - write_newcap_script(); + qprint("\n\nA script for adding all the countries can be found in \"%s\".\n", + outfile); + if (!ORE) + qprint("\t*** Resources have not been added ***\n"); exit(0); } -void +static void print_vars(void) { if (quiet) @@ -291,28 +308,48 @@ my_sqrt(int n) PARSE COMMAND LINE ARGUMENTS ****************************************************************************/ -void +static void +help(char *complaint) +{ + if (complaint) + fprintf(stderr, "%s: %s\n", program_name, complaint); + fprintf(stderr, "Try -h for help.\n"); +} + +static void +usage(void) +{ + printf("Usage: %s [OPTION]... NC SC [NI] [IS] [SP] [PM] [DI] [ID]\n" + " -a airport marker for continents\n" + " -e CONFIG-FILE configuration file\n" + " (default %s)\n" + " -h display this help and exit\n" + " -i islands may merge\n" + " -o don't set resources\n" + " -q quiet\n" + " -R SEED seed for random number generator\n" + " -s SCRIPT name of script to create (default %s)\n" + " NC number of continents\n" + " SC continent size\n" + " NI number of islands (default NC)\n" + " IS average island size (default SC/2)\n" + " SP spike percentage: 0 = round, 100 = snake (default %d)\n" + " PM percentage of land that is mountain (default %d)\n" + " DI minimum distance between continents (default %d)\n" + " ID minimum distance from islands to continents (default %d)\n", + program_name, dflt_econfig, DEFAULT_OUTFILE_NAME, + DEFAULT_SPIKE, DEFAULT_MOUNTAIN, DEFAULT_CONTDIST, DEFAULT_ISLDIST); +} + +static void parse_args(int argc, char *argv[]) { - if (argc < 2 || argc > 8) { - puts("fairland syntax:\n"); - puts("fairland [-e config] [-aiqo] [-s script] [] [] [] [] [] []"); - puts("-q = quiet, -o = no ore produced"); - puts("-a = Airport marker for continents, -i = islands not distinct"); - printf("-e = read config file, -s = name of script (default %s)\n", - outfile); - puts("nc = number of continents [MANDATORY]"); - puts("sc = continent size [MANDATORY]"); - puts("ni = number of islands (default = nc)"); - puts("is = average size of islands (default = sc/2)"); - printf("sp = spike percentage: 0 = round, 100 = snake (default = %d)\n", - DEFAULT_SPIKE); - printf("pm = the percentage of land that is mountain (default = %d)\n", - DEFAULT_MOUNTAIN); - printf("di = the minimum distance between continents (default = %d)\n", - DEFAULT_CONTDIST); - printf("id = minimum distance from islands to continents (default = %d)\n", - DEFAULT_ISLDIST); + if (argc < 2) { + help("missing arguments"); + exit(1); + } + if (argc > 8) { + help("too many arguments"); exit(1); } nc = atoi(argv[0]); @@ -336,8 +373,8 @@ parse_args(int argc, char *argv[]) is = atoi(argv[3]); else is = sc / 2; - if (is < 0) - is = 0; + if (is < 1) + is = 1; if (argc > 4) sp = atoi(argv[4]); @@ -382,10 +419,9 @@ parse_args(int argc, char *argv[]) exit(1); } if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) { - puts("fairland: error -- world not big enough to fit continents."); - puts("arguments must satisfy:"); + puts("fairland: warning -- world might be too small to fit continents."); + puts("arguments should satisfy:"); puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y"); - exit(1); } } @@ -393,67 +429,42 @@ parse_args(int argc, char *argv[]) VARIABLE INITIALIZATION ****************************************************************************/ -int +static void allocate_memory(void) { int i; - time_t now; - -#if !defined(_WIN32) - the_file = - open(empfile[EF_SECTOR].file, O_RDWR | O_CREAT | O_TRUNC, 0660); -#else - the_file = - open(empfile[EF_SECTOR].file, - O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0660); -#endif - if (the_file < 0) { - perror(empfile[EF_SECTOR].file); - return -1; - } - sectsbuf = - (struct sctstr *)calloc((YSIZE * XSIZE), sizeof(struct sctstr)); - sects = (struct sctstr **)calloc(YSIZE, sizeof(struct sctstr *)); - for (i = 0; i < YSIZE; i++) - sects[i] = §sbuf[XSIZE * i]; - time(&now); -#if !defined(_WIN32) - srandom(now + getpid()); -#else - srandom(now); -#endif - capx = (int *)calloc(nc, sizeof(int)); - capy = (int *)calloc(nc, sizeof(int)); - vector = (int *)calloc(WORLD_X + WORLD_Y, sizeof(int)); - mc = (int *)calloc(STABLE_CYCLE, sizeof(int)); - own = (int **)calloc(WORLD_X, sizeof(int *)); - elev = (int **)calloc(WORLD_X, sizeof(int *)); + + capx = calloc(nc, sizeof(int)); + capy = calloc(nc, sizeof(int)); + vector = calloc(WORLD_X + WORLD_Y, sizeof(int)); + mc = calloc(STABLE_CYCLE, sizeof(int)); + own = calloc(WORLD_X, sizeof(int *)); + elev = calloc(WORLD_X, sizeof(int *)); for (i = 0; i < WORLD_X; ++i) { - own[i] = (int *)calloc(WORLD_Y, sizeof(int)); - elev[i] = (int *)calloc(WORLD_Y, sizeof(int)); + own[i] = calloc(WORLD_Y, sizeof(int)); + elev[i] = calloc(WORLD_Y, sizeof(int)); } - sectx = (int **)calloc(nc + ni, sizeof(int *)); - secty = (int **)calloc(nc + ni, sizeof(int *)); - sectc = (int **)calloc(nc + ni, sizeof(int *)); - isecs = (int *)calloc(nc + ni, sizeof(int)); - weight = (int *)calloc(max(sc, is * 2), sizeof(int)); - dsea = (int *)calloc(max(sc, is * 2), sizeof(int)); - dmoun = (int *)calloc(max(sc, is * 2), sizeof(int)); + sectx = calloc(nc + ni, sizeof(int *)); + secty = calloc(nc + ni, sizeof(int *)); + sectc = calloc(nc + ni, sizeof(int *)); + isecs = calloc(nc + ni, sizeof(int)); + weight = calloc(MAX(sc, is * 2), sizeof(int)); + dsea = calloc(MAX(sc, is * 2), sizeof(int)); + dmoun = calloc(MAX(sc, is * 2), sizeof(int)); for (i = 0; i < nc; ++i) { - sectx[i] = (int *)calloc(sc, sizeof(int)); - secty[i] = (int *)calloc(sc, sizeof(int)); - sectc[i] = (int *)calloc(sc, sizeof(int)); + sectx[i] = calloc(sc, sizeof(int)); + secty[i] = calloc(sc, sizeof(int)); + sectc[i] = calloc(sc, sizeof(int)); } for (i = nc; i < nc + ni; ++i) { - sectx[i] = (int *)calloc(is * 2, sizeof(int)); - secty[i] = (int *)calloc(is * 2, sizeof(int)); - sectc[i] = (int *)calloc(is * 2, sizeof(int)); + sectx[i] = calloc(is * 2, sizeof(int)); + secty[i] = calloc(is * 2, sizeof(int)); + sectc[i] = calloc(is * 2, sizeof(int)); } - return 0; } -void +static void init(void) { int i, j, xx = 0, yy = 0; @@ -468,7 +479,7 @@ init(void) } } - for (i = 0; i < nc; ++i, xx += 2) { + for (i = 0; i < nc; ++i) { if (xx >= WORLD_X) { ++yy; xx = yy % 2; @@ -479,6 +490,7 @@ init(void) } capx[i] = xx; capy[i] = yy; + xx += 2; } for (i = 0; i < STABLE_CYCLE; ++i) mc[i] = i; @@ -508,7 +520,7 @@ iso(int j, int newx, int newy) /* Drift all the capitals */ -int +static int drift(void) { int i, turns; @@ -525,7 +537,7 @@ drift(void) /* Check to see if we have stabilized--can we stop drifting the capitals? */ -int +static int stable(void) { int i, isod, d = 0, stab = 1; @@ -546,12 +558,12 @@ stable(void) /* This routine does the actual drifting */ -void +static void fl_move(int j) { int i, n, newx, newy; - for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) { + for (i = roll0(6), n = 0; n < 6; i = (i + 1) % 6, ++n) { newx = new_x(capx[j] + dirx[i]); newy = new_y(capy[j] + diry[i]); if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) { @@ -632,7 +644,7 @@ try_to_grow(int c, int newx, int newy, int d) /* Move along the coast in a clockwise direction. */ -void +static void next_coast(int c, int x, int y, int *xp, int *yp) { int i, nx, ny, wat = 0; @@ -668,18 +680,14 @@ new_try(int c) if (sectc[c][0]) return 0; } else { - i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs); + i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : roll0(secs); do { if (sectc[c][i]) return i; i = (i + 1) % secs; } while (i != starti); - if (c < nc) { - printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n", - c + 'a', secs); - exit(1); - } else - return -1; + assert(c >= nc); + return -1; } return -1; } @@ -692,7 +700,7 @@ grow_one_sector(int c) { int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy; - spike = rnd(100) < sp; + spike = roll0(100) < sp; if ((try1 = new_try(c)) == -1) return 0; x = sx = sectx[c][try1]; @@ -701,7 +709,7 @@ grow_one_sector(int c) done = 0; do { if (spike) { - for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) { + for (i = roll0(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) { newx = new_x(x + dirx[i]); newy = new_y(y + diry[i]); if (own[newx][newy] == -1 && @@ -712,7 +720,7 @@ grow_one_sector(int c) done = 1; } } else - for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) { + for (i = roll0(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) { newx = new_x(x + dirx[i]); newy = new_y(y + diry[i]); if (own[newx][newy] == -1) @@ -724,9 +732,8 @@ grow_one_sector(int c) } while (!done && coast_search < COAST_SEARCH_MAX && (secs == 1 || x != sx || y != sy)); if (!done && c < nc) { - if (!quiet) - printf("fairland: error -- continent %c had no room to grow!\n", - numletter[c % 62]); + qprint("fairland: error -- continent %c had no room to grow!\n", + numletter[c % 62]); fl_status |= STATUS_NO_ROOM; } return done; @@ -734,7 +741,7 @@ grow_one_sector(int c) /* Grow all the continents */ -void +static void grow_continents(void) { int c; @@ -754,8 +761,11 @@ grow_continents(void) grow_one_sector(c); } } - if (fl_status && !quiet) - printf("Only managed to grow %d out of %d sectors.\n", secs, sc); + for (c = 0; c < nc; ++c) + find_coast(c); + + if (fl_status) + qprint("Only managed to grow %d out of %d sectors.\n", secs, sc); ctot = nc; } @@ -769,8 +779,8 @@ static int place_island(int c, int *xp, int *yp) { int d, sx, sy; - int ssy = rnd(WORLD_Y); - int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2); + int ssy = roll0(WORLD_Y); + int ssx = new_x(roll0(WORLD_X / 2) * 2 + ssy % 2); if (ssx > WORLD_X - 2) ssx = new_x(ssx + 2); @@ -781,7 +791,7 @@ place_island(int c, int *xp, int *yp) for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) { if (*xp >= WORLD_X) { *yp = new_y(*yp + 1); - *xp = (*yp) % 2; + *xp = *yp % 2; if (*xp == sx && *yp == sy) break; } @@ -795,7 +805,7 @@ place_island(int c, int *xp, int *yp) /* Grow all the islands */ -void +static void grow_islands(void) { int c, x, y, isiz; @@ -804,22 +814,22 @@ grow_islands(void) secs = 0; if (!place_island(c, &x, &y)) return; - isiz = 1 + rnd(2 * is - 1); + isiz = roll(2 * is - 1); do { ++secs; find_coast(c); } while (secs < isiz && grow_one_sector(c)); - if (quiet == 0) - printf(" %d(%d)", c - nc + 1, secs); + find_coast(c); + qprint(" %d(%d)", c - nc + 1, secs); isecs[c] = secs; - ctot = c; + ctot++; } } /**************************************************************************** CREATE ELEVATIONS ****************************************************************************/ -void +static void create_elevations(void) { elevate_land(); @@ -869,7 +879,7 @@ distance_to_what(int x, int y, int flag) /* Decide where the mountains go */ -void +static void elevate_land(void) { int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk, @@ -890,7 +900,7 @@ elevate_land(void) for (k = nm, mountain_search = 0; k && mountain_search < MOUNTAIN_SEARCH_MAX; ++mountain_search) { - r = rnd(total); + r = roll0(total); for (i = 0; i < ns; ++i) if (r < weight[i] && ELEV == -INFINITY && (c >= nc || @@ -944,14 +954,14 @@ elevate_land(void) for (i = 0; i < ns; ++i) { if (ELEV == INFINITY) { if (dsea[i] == 1) - ELEV = HILLMIN + rnd(PLATMIN - HILLMIN); + ELEV = HILLMIN + roll0(PLATMIN - HILLMIN); else - ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) + - rnd((256 - HIGHMIN) / 2); - } else if ((c < nc && - ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) || - ((new_x(capx[c] + 2) == sectx[c][i] && - capy[c] == secty[c][i]))) + ELEV = HIGHMIN + roll0((256 - HIGHMIN) / 2) + + roll0((256 - HIGHMIN) / 2); + } else if (c < nc && + (((capx[c] == sectx[c][i] && capy[c] == secty[c][i])) || + ((new_x(capx[c] + 2) == sectx[c][i] && + capy[c] == secty[c][i])))) ELEV = PLATMIN; } } @@ -959,7 +969,7 @@ elevate_land(void) #define distance_to_land() distance_to_what(x, y, 1) -void +static void elevate_sea(void) { int x, y; @@ -967,7 +977,7 @@ elevate_sea(void) for (y = 0; y < WORLD_Y; ++y) { for (x = y % 2; x < WORLD_X; x += 2) { if (elev[x][y] == -INFINITY) - elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1; + elev[x][y] = -roll(distance_to_land() * 20 + 27); } } } @@ -983,9 +993,9 @@ set_fert(int e) if (e < LANDMIN) fert = LANDMIN - e + 40; else if (e < FERT_MAX) - fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN); - if (fert > 120) - fert = 120; + fert = (120 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN); + if (fert > 100) + fert = 100; return fert; } @@ -994,7 +1004,7 @@ set_oil(int e) { int oil = 0; if (e < LANDMIN) - oil = (LANDMIN - e) * 2 + rnd(2); + oil = (LANDMIN - e) * 2 + roll0(2); else if (e <= OIL_MAX) oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1); if (oil > 100) @@ -1053,18 +1063,16 @@ add_resources(struct sctstr *sct) DESIGNATE THE SECTORS ****************************************************************************/ -void +static void write_sects(void) { - register struct sctstr *sct; + struct sctstr *sct; int c, x, y, total; - /* sct = §s[0][0]; */ - sct = sectsbuf; - for (y = 0; y < YSIZE; y++) { - for (x = 0; x < XSIZE; x++, sct++) { - fl_sct_init(x * 2 + (y & 01), y, (s_char *)sct); - total = elev[sct->sct_x][y]; + for (y = 0; y < WORLD_Y; y++) { + for (x = y % 2; x < WORLD_X; x += 2) { + sct = getsectp(x, y); + total = elev[x][y]; if (total < LANDMIN) { sct->sct_type = SCT_WATER; } else if (total < HILLMIN) @@ -1083,41 +1091,20 @@ write_sects(void) } if (AIRPORT_MARKER) for (c = 0; c < nc; ++c) { - sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT; - sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT; + sct = getsectp(capx[c], capy[c]); + sct->sct_type = SCT_AIRPT; + sct->sct_newtype = SCT_AIRPT; } -} - -/**************************************************************************** - WRITE ALL THIS STUFF TO THE FILE -****************************************************************************/ -int -write_file(void) -{ - int n; - - /* if ((n = write(the_file, sects, sizeof(sects))) < 0) { */ - if ((n = write(the_file, sectsbuf, YSIZE * XSIZE * sizeof(struct sctstr))) < 0) { - perror(empfile[EF_SECTOR].file); - return -1; - } - if (n != (int)(YSIZE * XSIZE * sizeof(struct sctstr))) { - printf("%s:partial write\n", empfile[EF_SECTOR].file); - return -1; - } - close(the_file); - return 0; + set_coastal_flags(); } /**************************************************************************** PRINT A PICTURE OF THE MAP TO YOUR SCREEN ****************************************************************************/ -void +static void output(void) { int i, j; - if (opt_BLITZ) - translate_continents(); if (quiet == 0) { for (i = 0; i < WORLD_Y; ++i) { puts(""); @@ -1133,59 +1120,12 @@ output(void) } } if (AIRPORT_MARKER) - printf("\n\nEach continent is marked by a \"*\" on the map (to distinguish them from\nthe islands). You can redesignate these airfields to wilderness sectors\none at a time, each time you add a new country to the game.\n"); -} - -/* Reorder the continents from top left to bottom right */ -void -translate_continents(void) -{ - int i, j, n = 0, k, gotit, c; - int *trans, *trans_cont, *oldcapx, *oldcapy; - - trans = (int *)calloc(nc, sizeof(int)); - trans_cont = (int *)calloc(nc, sizeof(int)); - oldcapx = (int *)calloc(nc, sizeof(int)); - oldcapy = (int *)calloc(nc, sizeof(int)); - - for (i = 0; i < WORLD_Y; ++i) { - for (j = i % 2; j < WORLD_X; j += 2) { - if (own[j][i] > -1 && own[j][i] < nc) { - gotit = 0; - for (k = 0; k < n; ++k) { - if (trans[k] == own[j][i]) - gotit = 1; - } - if (!gotit) { - if (n > nc) { - printf("fairland: BUG in translate continents! mail stevens@math.utoronto.ca\n"); - exit(2); - } - trans[n] = own[j][i]; - trans_cont[own[j][i]] = n; - ++n; - } - } - } - } - for (i = 0; i < WORLD_Y; ++i) { - for (j = i % 2; j < WORLD_X; j += 2) { - if (own[j][i] > -1 && own[j][i] < nc) { - own[j][i] = trans_cont[own[j][i]]; - } - } - } - for (c = 0; c < nc; ++c) { - oldcapx[c] = capx[c]; - oldcapy[c] = capy[c]; - } - for (c = 0; c < nc; ++c) { - capx[c] = oldcapx[trans[c]]; - capy[c] = oldcapy[trans[c]]; - } + printf("\n\nEach continent is marked by a \"*\" on the map (to distinguish them from\n" + "the islands). You can redesignate these airfields to wilderness sectors\n" + "one at a time, each time you add a new country to the game.\n"); } -int +static int map_symbol(int x, int y) { int c, iscap = 0; @@ -1203,7 +1143,7 @@ map_symbol(int x, int y) /*************************************************************************** WRITE A SCRIPT FOR PLACING CAPITALS ****************************************************************************/ -int +static int write_newcap_script(void) { int c; @@ -1215,40 +1155,45 @@ write_newcap_script(void) } for (c = 0; c < nc; ++c) { - fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1); + fprintf(script, "add %d %d %d p\n", c + 1, c + 1, c + 1); if (AIRPORT_MARKER) fprintf(script, "des %d,%d -\n", capx[c], capy[c]); fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]); } - fprintf(script, "add %d visitor visitor v i\n", c + 1); - ++c; + fprintf(script, "add %d visitor visitor v\n", c + 1); fclose(script); - if (quiet == 0) - printf("\n\nA script for adding all the countries can be found in \"%s\".\n", - outfile); - if (ORE && quiet == 0) - printf("\t***IMPORTANT: Resources have already been added***\n\tYou do NOT need to run the ore program.\n"); return 0; } static void -qprint(const char *str) +qprint(const char *const fmt, ...) { - if (quiet == 0) - fputs(str, stdout); + va_list ap; + + if (!quiet) { + va_start(ap, fmt); + vfprintf(stdout, fmt, ap); + va_end(ap); + } } -void -fl_sct_init(coord x, coord y, s_char *ptr) +static void +set_coastal_flags(void) { - struct sctstr *sp = (struct sctstr *)ptr; - - sp->ef_type = EF_SECTOR; - sp->sct_x = x; - sp->sct_y = y; - sp->sct_dist_x = x; - sp->sct_dist_y = y; - sp->sct_road = 0; - sp->sct_rail = 0; - sp->sct_defense = 0; + int i, j; + struct sctstr *sp; + + qprint("setting coastal flags...\n"); + for (i = 0; i < nc; ++i) { + for (j = 0; j < sc; j++) { + sp = getsectp(sectx[i][j], secty[i][j]); + sp->sct_coastal = sectc[i][j]; + } + } + for (i = nc; i < nc + ni; ++i) { + for (j = 0; j < isecs[i]; j++) { + sp = getsectp(sectx[i][j], secty[i][j]); + sp->sct_coastal = sectc[i][j]; + } + } }