#ifndef lint
static char *RCSid = "$Header: expl.c,v 1.12 90/03/19 11:08:04 mr-frog Exp $";
#endif

/*
 * expl.c
 *
 * takeover unoccupied sectors
 *
 * Jeff Wallace, 1989
 */

#include "misc.h"
#include "var.h"
#include "sect.h"
#include "xy.h"
#include "nsc.h"
#include "item.h"
#include "file.h"
#include "deity.h"
#include "nat.h"

static	int explore_map();

expl()
{
	extern	char *argp[];
	register int amount;
	struct	sctstr sect;
	struct	sctstr endsect;
	struct	sctstr start;
	struct	sctstr chksect;
	double	weight;
	int     mcost;
	int     infected;
	int     vtype;
	int     amt_src;
	int     amt_dst;
	struct	ichrstr *ip;
	int     work;
	int     loyal;
	int     own;
	int	justtook;
	coord	x, y;
	char	*p;
	int	n;

	if ((ip = whatitem(argp[1], "explore with what? (civ/mil) ")) == 0)
		return RET_SYN;
	vtype = ip->i_vtype;
	if ((vtype != V_CIVIL) && (vtype != V_MILIT)) {
		pr("You can only explore with civs and mil.\n");
		return RET_FAIL;
	}
	if ((p = getstarg(argp[2], "from sector : ")) == 0)
		return RET_SYN;
	if (!sarg_xy(p, &x, &y))
		return RET_SYN;
	if (!getsect(x, y, &sect) || !owner) {
		pr("Not yours\n");
		return RET_FAIL;
	}
	infected = getvar(V_PTIME, (char *)&sect, EF_SECTOR) == PLG_INFECT;
	if ((amt_src = getvar(vtype, (char *)&sect, EF_SECTOR)) <= 0) {
		pr(fmt("No %s in %s\n", ip->i_name, 
			xyas(sect.sct_x, sect.sct_y, cnum)));
		return RET_SYN;
	}
	own = sect.sct_own;
	if (vtype == V_CIVIL && sect.sct_oldown != own) {
		pr("You can't explore with conquered populace!\n");
		return RET_SYN;
	}
	if (vtype == V_CIVIL) {
		work = sect.sct_work;
		if (work != 100)
			pr("Warning: civil unrest\n");
		loyal = sect.sct_loyal;
	} else if (vtype == V_MILIT) {
		work = 100;
		loyal = 0;
	}
	amount = onearg(argp[3], fmt("Quantity? (max %d) ", amt_src));
	if (amount > amt_src) {
		amount = amt_src;
		pr(fmt("Only exploring with %d.\n", amount));
	}
	if (amount <= 0)
		return RET_SYN;
	weight = amount * ip->i_lbs;
	/*
	 * Now parse the path and return ending sector.
	 */
	mcost = move_ground((char *)ip, &sect, &endsect,
		(double)sect.sct_mobil, weight, argp[4], 
		explore_map, 1);
	if (mcost < 0) {
		pr("Explore aborted\n");
		return RET_FAIL;
	}

	/*
	 *	Check for a multitude of problems
	 */
	getsect(endsect.sct_x, endsect.sct_y, &chksect);
	if(chksect.sct_type == '.') {
		pr("Bridge disappeared!\n");
		return RET_FAIL;
	}
	if(!god && chksect.sct_own && chksect.sct_own != cnum
	&& chksect.sct_type != SCT_SANCT) {
		pr("Somebody beat you there!\n");
		return RET_FAIL;
	}

	/* Charge mobility */
	getsect(sect.sct_x, sect.sct_y, &sect);
	n = sect.sct_mobil - mcost;
	if (n < 0)
		n = 0;
	sect.sct_mobil = n;
	putsect(&sect);
	getsect(endsect.sct_x, endsect.sct_y, &sect);
	justtook = 0;
	if (!god && !owner && sect.sct_type != SCT_SANCT) {
		(void) takeover(&sect, 0);
		justtook = 1;
		sect.sct_oldown = own;
		sect.sct_work = work;
		sect.sct_loyal = loyal;
	}
	if (sect.sct_x == x && sect.sct_y == y) {
		/* didn't go anywhere! */
		return RET_OK;
	}
	if (vtype == V_CIVIL && sect.sct_oldown != cnum) {
		pr("Your civilians don't want to stay!\n");
		return RET_OK;
	}
	amt_dst = getvar(vtype, (char *)&sect, EF_SECTOR);
	if (32767 - amt_dst < amount) {
		amount = 32767 - amt_dst;
		pr(fmt("Only %d can be left there.\n", amount));
		if (amount <= 0)
			return RET_OK;
	}
	if (putvar(vtype, amount + amt_dst, (char *)&sect, EF_SECTOR) < 0) {
		pr(fmt("No more room in %s.\n", 
			xyas(sect.sct_x, sect.sct_y, cnum)));
		return RET_OK;
	}
	/* remove commodities from source sector */
	getsect(x, y, &start);
	amt_src = getvar(vtype, (char *)&start, EF_SECTOR);
	amt_src -= amount;
	if (amt_src < 0) {
		pr(fmt("%s in %s are gone!\n", ip->i_name, 
			xyas(start.sct_x, start.sct_y, cnum)));
		return RET_OK;
	}
	putvar(vtype, amt_src, (char *)&start, EF_SECTOR);
	putsect(&start);
	/*
	 * Now add commodities to destination sector,
	 * along with plague that came along for the ride.
	 * Takeover unowned sectors if not deity.
	 */
	if (!god && sect.sct_type != SCT_SANCT && justtook) {
		pr(fmt("Sector %s is now yours.\n", 
			xyas(sect.sct_x, sect.sct_y, cnum)));
		sect.sct_mobil = 0;
	}
	if (infected && getvar(V_PTIME, (char *)&sect, EF_SECTOR) == 0)
		putvar(V_PTIME, PLG_EXPOSED, (char *)&sect, EF_SECTOR);
	if (vtype == V_CIVIL) {
		/* It only takes one bad apple... */
		if (sect.sct_loyal < loyal)
			sect.sct_loyal = loyal;
		if (sect.sct_work > work)
			sect.sct_work = work;
	}
	putsect(&sect);
	return RET_OK;
}

/*ARGSUSED*/
static
explore_map(what, curx, cury, arg)
	char	*what;
	coord	curx, cury;
	char	*arg;
{
	struct	nstr_sect ns;
	struct	natstr *np;
	struct	sctstr sect;
	coord	rel_x, rel_y;
	char	*range;
	char	view[7];
	int	i;

	np = getnatp(cnum);
	rel_x = xrel(np, curx);
	rel_y = yrel(np, cury);
	range = fmt("%d:%d,%d:%d", rel_x-2, rel_x+2, rel_y-1, rel_y+1);
	if (!snxtsct(&ns, range))
		return RET_FAIL;
	i = 0;
	while (i < 7 && nxtsct(&ns, &sect)) {
		view[i] = dchr[sect.sct_type].d_mnem;
		switch (sect.sct_type) {
		case SCT_WATER:
		case SCT_RURAL:
		case SCT_MOUNT:
		case SCT_WASTE:
			break;
		default:
			if (sect.sct_own != cnum && !god)
				view[i] = '?';
			break;
		}
#if   defined(BMAP) || defined(AUTONAV)
		setbigmap(ns.x, ns.y, view[i]);
#endif
		i++;
	}
#if   defined(BMAP) || defined(AUTONAV)
	writebigmap();
#endif
	if (!getsect(curx, cury, &sect))
		return RET_FAIL;
	pr(fmt("    %c %c         min gold fert  oil uran\n", view[0], view[1]));
	pr(fmt("   %c %c %c        %3d %4d %4d %4d %4d\n",
		view[2], view[3], view[4],
		sect.sct_min, sect.sct_gmin, sect.sct_fertil, sect.sct_oil,
		sect.sct_uran));
	pr(fmt("    %c %c\n", view[5], view[6]));
	return RET_OK;
}
