#ifndef lint
static char *RCSid = "$Header: /usr/brule/guest/empire/empire/emprcs/lib/commands/new.c,v 2.4 1995/09/26 18:41:00 empire Exp $";
#endif /* not lint */

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

#include "misc.h"
#include "player.h"
#include "var.h"
#include "nat.h"
#include "sect.h"
#include "path.h"
#include "file.h"
#include "xy.h"
#include "tel.h"
#include "land.h"
#include "nsc.h"
#include "options.h"
#include "optlist.h"


#include <fcntl.h>

extern float start_education, start_happiness;
extern float start_technology, start_research;

static	void ok();
static	int isok();

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

#define	MAXAVAIL	300

new()
{
	extern	int max_btus;
	extern	int players_at_00;
	extern	int at_least_one_100;
#ifdef START_UNITS
	extern	int start_unit_type[START_UNITS];
#endif /* START_UNITS */
	struct	sctstr sect;
	struct	natstr *natp;
	struct	boundstr newrealms;
	struct	range absrealm;
	natid	num;
	long    now;
	coord   x, y;
	int     i;
	s_char	*p;
	int	n;
	extern int startmob;
	s_char	buf[1024];

	natp = getnatp(player->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(player->argp[1], "Country? ")) < 0) {
		pr("Bad country number\n");
		return 0;
	}
	num = n;
	natp = getnatp(num);
	if ((natp->nat_stat & STAT_NEW) == 0) {
		pr("Country #%d (%s) isn't a new country!\n",
		       num, cname(num));
		return RET_SYN;
	}
	if (player->argp[2] != 0) {
		if ((p = getstarg(player->argp[2], "sanctuary pair : ", buf)) == 0)
			return RET_SYN;
		if (!sarg_xy(p, &x, &y) || !getsect(x, y, &sect))
			return RET_SYN;
		if (sect.sct_type != SCT_RURAL) {
			pr("%s is a %s; try again...\n",
				xyas(x, y, player->cnum), dchr[sect.sct_type].d_name);
			return RET_SYN;
		}
		getsect(x + 2, y, &sect);
		if (sect.sct_type != SCT_RURAL) {
			pr("%s is a %s; try again...\n",
				xyas(x, y, player->cnum), dchr[sect.sct_type].d_name);
			return RET_SYN;
		}
	} else {
		(void) time(&now);
		(void) srandom(now);
		for (i = 0; i < 300 && !player->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 (player->aborted)
		return RET_FAIL;
	pr("added country %d at %s\n", num, xyas(x, y, player->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;
	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, 550, (s_char *)&sect, EF_SECTOR);
	putvar(V_MILIT, 10, (s_char *)&sect, EF_SECTOR);
	putvar(V_FOOD, 1000, (s_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, 550, (s_char *)&sect, EF_SECTOR);
	putvar(V_FOOD, 100, (s_char *)&sect, EF_SECTOR);
	putvar(V_MILIT, 100, (s_char *)&sect, EF_SECTOR);
	putvar(V_UW, 100, (s_char *)&sect, EF_SECTOR);
	putsect(&sect);
	natp->nat_btu = max_btus;
	natp->nat_stat &= ~STAT_NEW;
	natp->nat_stat |= STAT_SANCT;
	natp->nat_xstart = x;
	natp->nat_ystart = y;
	natp->nat_xcap = x;
	natp->nat_ycap = y;
	if (players_at_00) {
		natp->nat_xorg = 0;
		natp->nat_yorg = 0;
	} else {
		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;
	natp->nat_money = START_CASH;
	natp->nat_level[NAT_HLEV] = start_happiness;
	natp->nat_level[NAT_RLEV] = start_research;
	natp->nat_level[NAT_TLEV] = start_technology;
	natp->nat_level[NAT_ELEV] = start_education;
	for (i = 0; i < MAXNOR; i++)
		natp->nat_b[i] = newrealms;
	natp->nat_tgms = 0;
	(void) close(open(mailbox(buf, num), O_RDWR|O_TRUNC|O_CREAT, 0660));
#ifdef START_UNITS
	for(n=0;n<START_UNITS;n++)
		deity_build_land(start_unit_type[n], x, y, num, 0);
#endif /* START_UNITS */
	putnat(natp);
	return 0;
}

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

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

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

static void
ok(map, x, y)
	s_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, (s_char *)&sect))
		return;
	if (sect.sct_type == SCT_WATER || sect.sct_type == SCT_BSPAN)
		return;
	navail++;
	if (navail >= MAXAVAIL) {
		pr("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);
}

deity_build_land(type, x, y, own, tlev)
	int	type;
	coord	x, y;
	natid	own;
	int	tlev;
{
	extern	int land_mob_max;
	struct	lndstr land;
	struct	lchrstr *lp;
	struct	nstr_item nstr;
	struct  natstr *natp;
	double	techfact();
	int	lvec[I_MAX+1];
	int	extend = 1;

	natp = getnatp(own);

	snxtitem_all(&nstr, EF_LAND);
	while (nxtitem(&nstr, (s_char *)&land)) {
		if (land.lnd_own == 0) {
			extend = 0;
			break;
		}
	}
	if (extend)
		ef_extend(EF_LAND, 50);
	land.lnd_x = x;
	land.lnd_y = y;
	land.lnd_own = own;
	land.lnd_mission = 0;
	land.lnd_type = type;
	land.lnd_effic = 100;
	land.lnd_mobil = land_mob_max;
	land.lnd_sell = 0;
	land.lnd_tech = tlev;
	land.lnd_uid = nstr.cur;
	land.lnd_army = ' ';
	land.lnd_flags = 0;
	land.lnd_ship = -1;
	land.lnd_harden = 0;
	land.lnd_retreat = 75 - (int)natp->nat_level[NAT_HLEV];
	if (land.lnd_retreat < 0)
		land.lnd_retreat = 0;

	lp = &lchr[type];
	land.lnd_fuel = lp->l_fuelc;
	land.lnd_nxlight = 0;
	land.lnd_rflags = 0;
	bzero(land.lnd_rpath,10);
	land.lnd_rad_max = lp->l_rad;
	land.lnd_nv = 0;

	bzero(lvec, sizeof(lvec));
	getvec(VT_ITEM, lvec, (s_char *)&land, EF_LAND);
	lvec[I_FOOD] += vl_find(V_FOOD,lp->l_vtype,lp->l_vamt,(int)lp->l_nv);
	putvec(VT_ITEM, lvec, (s_char *)&land, EF_LAND);

	putland(nstr.cur, &land);
	pr("%s", prland(&land));
	pr(" built in sector %s\n", xyas(x, y, player->cnum));
	return 1;
}
