#ifndef lint
static char *RCSid = "$Header: move.c,v 1.11 89/09/28 01:32:29 mr-frog Exp $";
#endif

/*
 * move.c
 *
 * Move something somewhere.  Has a weight,
 * returns move cost, and fills a result parameter
 * with the destination sector.
 *
 *
 */

#include "misc.h"
#include "var.h"
#include "sect.h"
#include "item.h"
#include "file.h"
#include "deity.h"
#include "xy.h"
#include "path.h"
#include "nat.h"
#ifdef MOVEMAP
#include "map.h"
#include "nsc.h"

extern int move_map();
#endif /* MOVEMAP */

int
move_ground(what, start, end, mobility, weight, path, map, exploring)
	char	*what;
	struct	sctstr *start;
	struct	sctstr *end;	/* RESULT */
	double	mobility;
	double	weight;
	char	*path;
	int	(*map)();
	int	exploring;
{
	struct	sctstr sect;
	struct	sctstr next;
	int	vec[I_MAX+1];
	coord	curx, cury;
	coord	tmpx, tmpy;
	char	*movstr;
	double	sect_mcost;
	double	total_mcost;
	int	mcost;
	int	dir;
	int	intcost;

	movstr = path;
	tmpx = start->sct_x;
	curx = tmpx;
	tmpy = start->sct_y;
	cury = tmpy;
	total_mcost = 0.0;
	if (getsect(curx, cury, &sect) < 0) {
		logerror("move_path: getsect %d,%d", curx, cury);
		return -1;
	}
	for (;;) {
		tmpx = curx;
		tmpy = cury;
		if (movstr == 0 || *movstr == 0) {
#ifdef MOVEMAP
                        if (exploring) {
                                map(what, curx, cury, (char *)0); }
                        else {
                                move_map(what, curx, cury, (char *)0); }
#else
			if (exploring)
				map(what, curx, cury, (char *)0);
#endif /* MOVEMAP */
			movstr = getstring(fmt("<%.1f: %c %s> ", mobility,
				dchr[sect.sct_type].d_mnem,
				xyas(sect.sct_x, sect.sct_y, cnum)));
		}
		if (movstr == 0 || *movstr == 0)
			movstr = dirch;
		if ((dir = chkdir(*movstr, DIR_STOP, DIR_MAP)) < 0) {
			pr(fmt("\"%c\" is not legal...", *movstr));
			direrr("'%c' to stop ", "'%c' to view ",
				"& '%c' to map\n");
			*movstr = 0;
			continue;
		}
		movstr++;
		if (dir == DIR_MAP) {
			if (!exploring)
				map(what, curx, cury, movstr+1);
			*movstr = 0;
			continue;
		} else if (dir == DIR_STOP)
			break;
		else if (dir == DIR_VIEW) {
			pr(fmt("%d%% %s with %d civilians.\n", sect.sct_effic,
				dchr[sect.sct_type].d_name,
				getvar(V_CIVIL, (char *)&sect, EF_SECTOR)));
			continue;
		}
		/*
		 * now see if we can move into the
		 * next sector.  Mobility, terrain,
		 * or ownership may prevent us.
		 */
		tmpx += diroff[dir][0];
		tmpy += diroff[dir][1];
		if (getsect(tmpx, tmpy, &next) < 0) {
			pr("You can't go there...\n");
			*movstr = 0;
			continue;
		}
		if (!god) {
			if ((next.sct_type == SCT_SANCT) &&
						       (next.sct_own != cnum)) {
				pr("Converts, huh?\n");
				*end = next;
				return total_mcost;
			}
			getvec(VT_ITEM, vec, (char *)&next, EF_SECTOR);
			mcost = dchr[next.sct_type].d_mcst;
			if ((!owner && (!exploring || 
			    (vec[I_MILIT] || vec[I_CIVIL]))) ||
			    mcost == 0) {
				/* already-owned, or prohibited terrain */
				pr("You can't go there...\n");
				*movstr = 0;
				continue;
			}
			sect_mcost = (mcost * 100 - next.sct_effic) / 500.0;
			sect_mcost *= weight;
			if (sect_mcost > mobility) {
				pr("Not enough mobility.  ");
				pr("You can't go there...\n");
				*movstr = 0;
				continue;
			}
			mobility -= sect_mcost;
			total_mcost += sect_mcost;
		}
		curx = tmpx;
		cury = tmpy;
		sect = next;
	}
	*end = sect;
	intcost = (int) total_mcost;
	if (intcost < 0)
		return -1;
	if (chance(total_mcost - intcost))
		intcost++;
	return intcost;
}


#ifdef MOVEMAP
/*ARGSUSED*/
int
move_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;
        int     vec[I_MAX+1];
 
        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;
        getvec(VT_ITEM, vec, (char *)&sect, EF_SECTOR);
        pr(fmt("    %c %c      eff   mob   civ  mil   uw food  work  avail\n",
                view[0], view[1]));
        pr(fmt("   %c %c %c     %3d   %3d  %4d %4d %4d %4d   %3d   %3d\n",
                view[2], view[3], view[4],
                sect.sct_effic, sect.sct_mobil, vec[I_CIVIL],vec[I_MILIT],
          vec[I_UW],vec[I_FOOD], sect.sct_work, sect.sct_avail));
        pr(fmt("    %c %c\n", view[5], view[6]));
        return RET_OK;
}
#endif
