/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2006, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2010, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* ---
*
* fairland.c: Create a nice, new world
- *
+ *
* Known contributors to this file:
* Ken Stevens, 1995
* Steve McClure, 1998
/* lower URAN_MIN for more uranium */
#define URAN_MIN 56
-#if defined(_WIN32)
-#include "../lib/gen/getopt.h"
-#endif
-
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
+#include <unistd.h>
+#include "file.h"
#include "misc.h"
-#include "power.h"
#include "nat.h"
-#include "sect.h"
-#include "file.h"
-#include "xy.h"
#include "optlist.h"
+#include "power.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 */
static char *program_name;
-#define XSIZE ((WORLD_X) / 2) /* basically world x-y size */
-#define YSIZE (WORLD_Y)
#define STABLE_CYCLE 4 /* stability required for perterbed capitals */
#define INFINITY 999 /* a number which means "BIG" */
#define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
#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 */
+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 */
-int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
-unsigned long rnd_seed; /* optional seed can be passed as an argument */
-int *capx, *capy; /* location of the nc capitals */
-int *mc, mcc; /* array and counter used for stability
+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 */
-FILE *sect_fptr; /* the file we write everything to */
-struct sctstr **sects;
-struct sctstr *sectsbuf;
-int fl_status; /* is anything wrong? */
+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";
static void help(char *);
static void grow_continents(void);
static void create_elevations(void);
static void write_sects(void);
-static int write_file(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 fl_sct_init(coord, coord, struct sctstr *, time_t timestamp);
static void set_coastal_flags(void);
static void print_vars(void);
exit(1);
}
}
+ parse_args(argc - optind, argv + optind);
+
srandom(rnd_seed);
- if (emp_config(config_file))
+ empfile_init();
+ if (emp_config(config_file) < 0)
exit(1);
+ empfile_fixup();
- parse_args(argc - optind, argv + optind);
if (allocate_memory() == -1)
exit(-1);
print_vars();
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, WORLD_SZ())) {
+ perror("ef_open");
+ exit(1);
+ }
write_sects();
qprint("writing to sectors file...\n");
- if (write_file() == -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);
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);
}
}
allocate_memory(void)
{
int i;
- char *fname;
- fname = malloc(strlen(gamedir) + 1 + strlen(empfile[EF_SECTOR].file) + 1);
- sprintf(fname, "%s/%s", gamedir, empfile[EF_SECTOR].file);
- sect_fptr = fopen(fname, "wb");
- if (sect_fptr == NULL) {
- perror(fname);
- return -1;
- }
- free(fname);
- sectsbuf = calloc((YSIZE * XSIZE), sizeof(struct sctstr));
- sects = calloc(YSIZE, sizeof(struct sctstr *));
- for (i = 0; i < YSIZE; i++)
- sects[i] = §sbuf[XSIZE * i];
capx = calloc(nc, sizeof(int));
capy = calloc(nc, sizeof(int));
vector = calloc(WORLD_X + WORLD_Y, sizeof(int));
}
}
- for (i = 0; i < nc; ++i, xx += 2) {
+ for (i = 0; i < nc; ++i) {
if (xx >= WORLD_X) {
++yy;
xx = yy % 2;
}
capx[i] = xx;
capy[i] = yy;
+ xx += 2;
}
for (i = 0; i < STABLE_CYCLE; ++i)
mc[i] = i;
secs = 0;
if (!place_island(c, &x, &y))
return;
- isiz = 1 + rnd(2 * is - 1);
+ isiz = 1 + rnd(is) + rnd(is);
do {
++secs;
find_coast(c);
find_coast(c);
qprint(" %d(%d)", c - nc + 1, secs);
isecs[c] = secs;
- ctot = c;
+ ctot++;
}
}
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;
}
{
struct sctstr *sct;
int c, x, y, total;
- time_t current_time = time(NULL);
-
- /* 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 & 1), y, sct, current_time);
- 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)
sct->sct_type = SCT_MOUNT;
sct->sct_elev = total;
sct->sct_newtype = sct->sct_type;
+ sct->sct_dterr = own[sct->sct_x][y] + 1;
if (ORE)
add_resources(sct);
}
}
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;
}
set_coastal_flags();
}
-/****************************************************************************
- WRITE ALL THIS STUFF TO THE FILE
-****************************************************************************/
-static int
-write_file(void)
-{
- int n;
-
- n = fwrite(sectsbuf, sizeof(struct sctstr), YSIZE * XSIZE, sect_fptr);
- if (n <= 0) {
- perror(empfile[EF_SECTOR].file);
- return -1;
- }
- if (n != YSIZE * XSIZE) {
- printf("%s:partial write\n", empfile[EF_SECTOR].file);
- return -1;
- }
- fclose(sect_fptr);
- return 0;
-}
-
/****************************************************************************
PRINT A PICTURE OF THE MAP TO YOUR SCREEN
****************************************************************************/
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;
fclose(script);
- qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
- outfile);
return 0;
}
}
}
-static void
-fl_sct_init(coord x, coord y, struct sctstr *sp, time_t timestamp)
-{
- 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;
- sp->sct_timestamp = timestamp;
- sp->sct_coastal = 1;
-}
-
static void
set_coastal_flags(void)
{
int i, j;
+ struct sctstr *sp;
qprint("setting coastal flags...\n");
- for (i = 0; i < nc; ++i)
- for (j = 0; j < sc; j++)
- sects[secty[i][j]][sectx[i][j] / 2].sct_coastal = sectc[i][j];
- for (i = nc; i < nc + ni; ++i)
- for (j = 0; j < isecs[i]; j++)
- sects[secty[i][j]][sectx[i][j] / 2].sct_coastal = sectc[i][j];
+ 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];
+ }
+ }
}