#ifndef lint
static char *RCSid = "$Header: new.c,v 1.9 90/03/19 11:00:58 mr-frog Exp $";
#endif /* not lint */

/*
 * new.c
 *
 * create a new capx,capy for a player
 *
 * Dave Pare, 1986
 */

#include "misc.h"
#include "var.h"
#include "nat.h"
#include "sect.h"
#include "path.h"
#include "file.h"
#include "xy.h"
#include "tel.h"

#include <fcntl.h>

static	ok();
static	int isok();

static	struct range defrealm = {-8, -5, 10, 5, 0, 0};

#define	MAXAVAIL	300

new()
{
	extern	char *argp[];
	extern	int aborted;
	extern	int players_at_00;
	extern	int at_least_one_100;
	struct	sctstr sect;
	struct	natstr *natp;
	struct	boundstr newrealms;
	struct	range absrealm;
	natid	num;
	long    now;
	coord   x, y;
	int     i;
	char	*p;
	int	n;
	extern int startmob;

	natp = getnatp(cnum);
	if (natp->nat_xorg != 0 || natp->nat_yorg != 0) {
		pr("Must be at 0,0 to add a new country\n");
		return 0;
	}
	if ((n = natarg(argp[1], "Country? ")) < 0) {
		pr("Bad country number\n");
		return 0;
	}
	num = n;
	natp = getnatp(num);
	if ((natp->nat_stat & STAT_NEW) == 0) {
		pr(fmt("Country #%d (%s) isn't a new country!\n",
		       num, cname(num)));
		return RET_SYN;
	}
	if (argp[2] != 0) {
		if ((p = getstarg(argp[2], "sanctuary pair : ")) == 0)
			return RET_SYN;
		if (!sarg_xy(p, &x, &y) || !getsect(x, y, &sect))
			return RET_SYN;
		if (sect.sct_type != SCT_RURAL) {
			pr(fmt("%s is a %s; try again...\n",
				xyas(x, y, cnum), dchr[sect.sct_type].d_name));
			return RET_SYN;
		}
		getsect(x + 2, y, &sect);
		if (sect.sct_type != SCT_RURAL) {
			pr(fmt("%s is a %s; try again...\n",
				xyas(x, y, cnum), dchr[sect.sct_type].d_name));
			return RET_SYN;
		}
	} else {
		(void) time(&now);
		(void) srandom(now);
		for (i = 0; i < 300 && !aborted; i++) {
			/* Both x and y should be either odd or even */
			x = (random() % WORLD_X)-(WORLD_X/2);
			y = (((random() % WORLD_Y)-(WORLD_Y/2)) & ~1) | (x & 1);
			/*
			 * If either of the two potential
			 * sanctuary sectors are already
			 * owned by someone else, pick
			 * another place on the map.
			 */
			getsect(x, y, &sect);
			if (sect.sct_type == SCT_WATER || sect.sct_own != 0)
				continue;
			getsect(x+2, y, &sect);
			if (sect.sct_type == SCT_WATER || sect.sct_own != 0)
				continue;
			if (isok(x, y))
				break;
		}
		if (i == 300) {
			pr("couldn't find an empty slot!\n");
			return RET_FAIL;
		}
	}
	if (aborted)
		return RET_FAIL;
	pr(fmt("added country %d at %s\n", num, xyas(x, y, cnum)));
	getsect(x, y, &sect);
	sect.sct_own = num;
	sect.sct_type = SCT_SANCT;
	sect.sct_newtype = SCT_SANCT;
	sect.sct_effic = 100;
	sect.sct_mobil = startmob;
	sect.sct_work = 100;
	sect.sct_oldown = num;
#ifdef MERC
	if (at_least_one_100) {
		sect.sct_oil = 100;
		sect.sct_fertil = 100;
		sect.sct_uran = 100;
		sect.sct_min = 100;
		sect.sct_gmin = 100;
	}
#endif
	putvar(V_CIVIL, 1000, (char *)&sect, EF_SECTOR);
	putvar(V_MILIT, 10, (char *)&sect, EF_SECTOR);
	putvar(V_FOOD, 1000, (char *)&sect, EF_SECTOR);
	putsect(&sect);
	getsect(x + 2, y, &sect);
	sect.sct_own = num;
	sect.sct_type = SCT_SANCT;
	sect.sct_newtype = SCT_SANCT;
	sect.sct_effic = 100;
	sect.sct_work = 100;
	sect.sct_oldown = num;
	sect.sct_mobil = startmob;
	if (at_least_one_100) {
		sect.sct_oil = 100;
		sect.sct_fertil = 100;
		sect.sct_uran = 100;
		sect.sct_min = 100;
		sect.sct_gmin = 100;
	}
	putvar(V_CIVIL, 100, (char *)&sect, EF_SECTOR);
	putvar(V_FOOD, 100, (char *)&sect, EF_SECTOR);
	putvar(V_MILIT, 100, (char *)&sect, EF_SECTOR);
	putvar(V_UW, 100, (char *)&sect, EF_SECTOR);
	putsect(&sect);
	NAT_SET(nat_btu, num, 255);
	NAT_DELTA(nat_stat, num, STAT_SANCT-STAT_NEW);
	NAT_SET(nat_xcap, num, x);
	NAT_SET(nat_ycap, num, y);
	if (players_at_00) {
		NAT_SET(nat_xorg, num, 0);
		NAT_SET(nat_yorg, num, 0);
		natp->nat_xorg = 0;
		natp->nat_yorg = 0;
	} else {
		NAT_SET(nat_xorg, num, x);
		NAT_SET(nat_yorg, num, y);
		natp->nat_xorg = x;
		natp->nat_yorg = y;
	}
	xyabsrange(natp, &defrealm, &absrealm);
	newrealms.b_xl = absrealm.lx;
	newrealms.b_xh = absrealm.hx;
	newrealms.b_yl = absrealm.ly;
	newrealms.b_yh = absrealm.hy;
	NAT_SET(nat_money, num, 25000);
	NAT_SETARY(nat_level[0], num, NAT_HLEV, 0.0);
	NAT_SETARY(nat_level[0], num, NAT_RLEV, 0.0);
	NAT_SETARY(nat_level[0], num, NAT_TLEV, 0.0);
	NAT_SETARY(nat_level[0], num, NAT_ELEV, 0.0);
	for (i = 0; i < MAXNOR; i++)
		NAT_SETARY(nat_b[0], num, i, &newrealms);
	NAT_SET(nat_tgms, num, 0);
	(void) close(open(mailbox(num), O_RDWR|O_TRUNC|O_CREAT, 0660));
#ifdef WIRE
        (void) close(open(wirebox(num), O_RDWR|O_TRUNC|O_CREAT, 0660));
#endif
	return 0;
}

static int nmin, ngold, noil, nur;
static int nfree, navail, nowned;

static int
isok(x, y)
	int     x;
	int     y;
{
	char	map[WORLD_Y*WORLD_X/2];
	char   *p;

	nmin = ngold = noil = nur = 0;
	navail = nfree = nowned = 0;
	bzero(map, sizeof(map));
	ok(map, x, y);
	if (nfree < 5)
		return 0;
	pr(fmt("Cap at %s; owned sectors: %d, free sectors: %d, avail: %d\n",
	       xyas(x, y, cnum), nowned, nfree, navail));
	pr(fmt("min: %d, oil: %d, gold: %d, uranium: %d\n",
	       nmin, noil, ngold, nur));
	p = getstring("This setup ok? ");
	if (p == 0 || *p != 'y')
		return 0;
	return 1;
}

static
ok(map, x, y)
	char	*map;
	int     x;
	int     y;
{
	struct	sctstr sect;
	int     dir;
	int	id;

	if (navail > MAXAVAIL)
		return;
	id = sctoff(x, y);
	if (map[id])
		return;
	if (!ef_read(EF_SECTOR, id, (char *)&sect))
		return;
	if (sect.sct_type == SCT_WATER || sect.sct_type == SCT_BSPAN)
		return;
	navail++;
	if (navail >= MAXAVAIL) {
		pr(fmt("At least %d...\n", MAXAVAIL));
		return;
	}
	if (sect.sct_type != SCT_MOUNT) {
		if (sect.sct_own == 0)
			nfree++;
		else
			nowned++;
		if (sect.sct_min > 9)
			nmin++;
		if (sect.sct_gmin > 9)
			ngold++;
		if (sect.sct_uran > 9)
			nur++;
		if (sect.sct_oil > 9)
			noil++;
	}
	map[id] = 1;
	for (dir = DIR_FIRST; dir <= DIR_LAST; dir++)
		ok(map, diroff[dir][0] + x, diroff[dir][1] + y);
}
