[comp.sources.games] v02i004: nethack - display oriented dungeons & dragons, Part04/16

games-request@tekred.TEK.COM (07/28/87)

Submitted by: mike@genat.UUCP (Mike Stephenson)
Comp.sources.games: Volume 2, Issue 4
Archive-name: nethack/Part04


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 16)."
# Contents:  invent.c mklev.c options.c
# Wrapped by billr@tekred on Tue Jul 28 09:49:24 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f invent.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"invent.c\"
else
echo shar: Extracting \"invent.c\" \(22500 characters\)
sed "s/^X//" >invent.c <<'END_OF_invent.c'
X/*	SCCS Id: @(#)invent.c	1.3	87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* invent.c - version 1.0.3 */
X
X#include	<stdio.h>
X#include	"hack.h"
Xextern struct obj *splitobj();
Xextern struct obj zeroobj;
Xextern char morc;
Xextern char quitchars[];
Xstatic char *xprname();
X
X#ifndef NOWORM
X#include	"wseg.h"
Xextern struct wseg *wsegs[32];
X#endif
X
X#define	NOINVSYM	'#'
X
Xint lastinvnr = 51;	/* 0 ... 51 */
X
Xstatic
Xassigninvlet(otmp)
Xregister struct obj *otmp;
X{
X	boolean inuse[52];
X	register int i;
X	register struct obj *obj;
X
X	for(i = 0; i < 52; i++) inuse[i] = FALSE;
X	for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) {
X		i = obj->invlet;
X		if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else
X		if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE;
X		if(i == otmp->invlet) otmp->invlet = 0;
X	}
X	if((i = otmp->invlet) &&
X	    (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z')))
X		return;
X	for(i = lastinvnr+1; i != lastinvnr; i++) {
X		if(i == 52) { i = -1; continue; }
X		if(!inuse[i]) break;
X	}
X	otmp->invlet = (inuse[i] ? NOINVSYM :
X			(i < 26) ? ('a'+i) : ('A'+i-26));
X	lastinvnr = i;
X}
X
Xstruct obj *
Xaddinv(obj)
Xregister struct obj *obj;
X{
X	register struct obj *otmp;
X
X	/* merge or attach to end of chain */
X	if(!invent) {
X		invent = obj;
X		otmp = 0;
X	} else
X	for(otmp = invent; /* otmp */; otmp = otmp->nobj) {
X		if(merged(otmp, obj, 0))
X			return(otmp);
X		if(!otmp->nobj) {
X			otmp->nobj = obj;
X			break;
X		}
X	}
X	obj->nobj = 0;
X
X	if(flags.invlet_constant) {
X		assigninvlet(obj);
X		/*
X		 * The ordering of the chain is nowhere significant
X		 * so in case you prefer some other order than the
X		 * historical one, change the code below.
X		 */
X		if(otmp) {	/* find proper place in chain */
X			otmp->nobj = 0;
X			if((invent->invlet ^ 040) > (obj->invlet ^ 040)) {
X				obj->nobj = invent;
X				invent = obj;
X			} else
X			for(otmp = invent; ; otmp = otmp->nobj) {
X			    if(!otmp->nobj ||
X				(otmp->nobj->invlet ^ 040) > (obj->invlet ^ 040)){
X				obj->nobj = otmp->nobj;
X				otmp->nobj = obj;
X				break;
X			    }
X			}
X		}
X	}
X
X	return(obj);
X}
X
Xuseup(obj)
Xregister struct obj *obj;
X{
X	if(obj->quan > 1){
X		obj->quan--;
X		obj->owt = weight(obj);
X	} else {
X		setnotworn(obj);
X		freeinv(obj);
X		obfree(obj, (struct obj *) 0);
X	}
X}
X
Xfreeinv(obj)
Xregister struct obj *obj;
X{
X	register struct obj *otmp;
X
X	if(obj == invent)
X		invent = invent->nobj;
X	else {
X		for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj)
X			if(!otmp->nobj) panic("freeinv");
X		otmp->nobj = obj->nobj;
X	}
X}
X
X/* destroy object in fobj chain (if unpaid, it remains on the bill) */
Xdelobj(obj) register struct obj *obj; {
X	freeobj(obj);
X	unpobj(obj);
X	obfree(obj, (struct obj *) 0);
X}
X
X/* unlink obj from chain starting with fobj */
Xfreeobj(obj) register struct obj *obj; {
X	register struct obj *otmp;
X
X	if(obj == fobj) fobj = fobj->nobj;
X	else {
X		for(otmp = fobj; otmp->nobj != obj; otmp = otmp->nobj)
X			if(!otmp) panic("error in freeobj");
X		otmp->nobj = obj->nobj;
X	}
X}
X
X/* Note: freegold throws away its argument! */
Xfreegold(gold) register struct gold *gold; {
X	register struct gold *gtmp;
X
X	if(gold == fgold) fgold = gold->ngold;
X	else {
X		for(gtmp = fgold; gtmp->ngold != gold; gtmp = gtmp->ngold)
X			if(!gtmp) panic("error in freegold");
X		gtmp->ngold = gold->ngold;
X	}
X	free((char *) gold);
X}
X
Xdeltrap(trap)
Xregister struct trap *trap;
X{
X	register struct trap *ttmp;
X
X	if(trap == ftrap)
X		ftrap = ftrap->ntrap;
X	else {
X		for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ;
X		ttmp->ntrap = trap->ntrap;
X	}
X	free((char *) trap);
X}
X
Xstruct wseg *m_atseg;
X
Xstruct monst *
Xm_at(x,y)
Xregister x,y;
X{
X	register struct monst *mtmp;
X#ifndef NOWORM
X	register struct wseg *wtmp;
X#endif
X
X	m_atseg = 0;
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
X		if(mtmp->mx == x && mtmp->my == y)
X			return(mtmp);
X#ifndef NOWORM
X		if(mtmp->wormno){
X		    for(wtmp = wsegs[mtmp->wormno]; wtmp; wtmp = wtmp->nseg)
X		    if(wtmp->wx == x && wtmp->wy == y){
X			m_atseg = wtmp;
X			return(mtmp);
X		    }
X		}
X#endif
X	}
X	return(0);
X}
X
Xstruct obj *
Xo_at(x,y)
Xregister x,y;
X{
X	register struct obj *otmp;
X
X	for(otmp = fobj; otmp; otmp = otmp->nobj)
X		if(otmp->ox == x && otmp->oy == y) return(otmp);
X	return(0);
X}
X
Xstruct obj *
Xsobj_at(n,x,y)
Xregister n,x,y;
X{
X	register struct obj *otmp;
X
X	for(otmp = fobj; otmp; otmp = otmp->nobj)
X		if(otmp->ox == x && otmp->oy == y && otmp->otyp == n)
X			return(otmp);
X	return(0);
X}
X
Xcarried(obj) register struct obj *obj; {
Xregister struct obj *otmp;
X	for(otmp = invent; otmp; otmp = otmp->nobj)
X		if(otmp == obj) return(1);
X	return(0);
X}
X
Xstruct obj *
Xcarrying(type)
Xregister int type;
X{
X	register struct obj *otmp;
X
X	for(otmp = invent; otmp; otmp = otmp->nobj)
X		if(otmp->otyp == type)
X			return(otmp);
X	return((struct obj *) 0);
X}
X
Xstruct obj *
Xo_on(id, objchn) unsigned int id; register struct obj *objchn; {
X	while(objchn) {
X		if(objchn->o_id == id) return(objchn);
X		objchn = objchn->nobj;
X	}
X	return((struct obj *) 0);
X}
X
Xstruct trap *
Xt_at(x,y)
Xregister x,y;
X{
X	register struct trap *trap = ftrap;
X	while(trap) {
X		if(trap->tx == x && trap->ty == y) return(trap);
X		trap = trap->ntrap;
X	}
X	return(0);
X}
X
Xstruct gold *
Xg_at(x,y)
Xregister x,y;
X{
X	register struct gold *gold = fgold;
X	while(gold) {
X		if(gold->gx == x && gold->gy == y) return(gold);
X		gold = gold->ngold;
X	}
X	return(0);
X}
X
X/* make dummy object structure containing gold - for temporary use only */
Xstruct obj *
Xmkgoldobj(q)
Xregister long q;
X{
X	register struct obj *otmp;
X
X	otmp = newobj(0);
X	/* should set o_id etc. but otmp will be freed soon */
X	otmp->olet = '$';
X	u.ugold -= q;
X	OGOLD(otmp) = q;
X	flags.botl = 1;
X	return(otmp);
X}
X
X/*
X * getobj returns:
X *	struct obj *xxx:	object to do something with.
X *	(struct obj *) 0	error return: no object.
X *	&zeroobj		explicitly no object (as in w-).
X */
Xstruct obj *
Xgetobj(let,word)
Xregister char *let,*word;
X{
X	register struct obj *otmp;
X	register char ilet,ilet1,ilet2;
X	char buf[BUFSZ];
X	char lets[BUFSZ];
X	register int foo = 0, foo2;
X	register char *bp = buf;
X	xchar allowcnt = 0;	/* 0, 1 or 2 */
X	boolean allowgold = FALSE;
X	boolean allowall = FALSE;
X	boolean allownone = FALSE;
X	xchar foox = 0;
X	long cnt;
X
X	if(*let == '0') let++, allowcnt = 1;
X	if(*let == '$') let++, allowgold = TRUE;
X	if(*let == '#') let++, allowall = TRUE;
X	if(*let == '-') let++, allownone = TRUE;
X	if(allownone) *bp++ = '-';
X	if(allowgold) *bp++ = '$';
X	if(bp > buf && bp[-1] == '-') *bp++ = ' ';
X
X	ilet = 'a';
X	for(otmp = invent; otmp; otmp = otmp->nobj){
X	    if(!*let || index(let, otmp->olet)) {
X		bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet;
X
X		/* ugly check: remove inappropriate things */
X		if((!strcmp(word, "take off") &&
X		    !(otmp->owornmask & (W_ARMOR - W_ARM2)))
X		|| (!strcmp(word, "wear") &&
X		    (otmp->owornmask & (W_ARMOR | W_RING)))
X		|| (!strcmp(word, "wield") &&
X		    (otmp->owornmask & W_WEP))
X#ifdef MARKER
X		|| (!strcmp(word, "write with") &&
X		    (otmp->olet == TOOL_SYM && otmp->otyp != MAGIC_MARKER))
X#endif
X		    ) {
X			foo--;
X			foox++;
X		}
X	    }
X	    if(ilet == 'z') ilet = 'A'; else ilet++;
X	}
X	bp[foo] = 0;
X	if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0;
X	(void) strcpy(lets, bp);	/* necessary since we destroy buf */
X	if(foo > 5) {			/* compactify string */
X		foo = foo2 = 1;
X		ilet2 = bp[0];
X		ilet1 = bp[1];
X		while(ilet = bp[++foo2] = bp[++foo]){
X			if(ilet == ilet1+1){
X				if(ilet1 == ilet2+1)
X					bp[foo2 - 1] = ilet1 = '-';
X				else if(ilet2 == '-') {
X					bp[--foo2] = ++ilet1;
X					continue;
X				}
X			}
X			ilet2 = ilet1;
X			ilet1 = ilet;
X		}
X	}
X	if(!foo && !allowall && !allowgold && !allownone) {
X		pline("You don't have anything %sto %s.",
X			foox ? "else " : "", word);
X		return(0);
X	}
X	for(;;) {
X		if(!buf[0])
X#ifdef REDO
X		    if(!in_doagain)
X#endif
X			pline("What do you want to %s [*]? ", word);
X		else
X#ifdef REDO
X		    if(!in_doagain)
X#endif
X			pline("What do you want to %s [%s or ?*]? ",
X				word, buf);
X
X		cnt = 0;
X		ilet = readchar();
X		while(digit(ilet) && allowcnt) {
X#ifdef REDO
X			if (ilet != '?' && ilet != '*')	savech(ilet);
X#endif
X			cnt = 10*cnt + (ilet - '0');
X			allowcnt = 2;	/* signal presence of cnt */
X			ilet = readchar();
X		}
X		if(digit(ilet)) {
X			pline("No count allowed with this command.");
X			continue;
X		}
X		if(index(quitchars,ilet))
X			return((struct obj *)0);
X		if(ilet == '-') {
X			return(allownone ? &zeroobj : (struct obj *) 0);
X		}
X		if(ilet == '$') {
X			if(!allowgold){
X				pline("You cannot %s gold.", word);
X				continue;
X			}
X			if(!(allowcnt == 2 && cnt < u.ugold))
X				cnt = u.ugold;
X			return(mkgoldobj(cnt));
X		}
X		if(ilet == '?') {
X			doinv(lets);
X			if(!(ilet = morc)) continue;
X			/* he typed a letter (not a space) to more() */
X		} else if(ilet == '*') {
X			doinv((char *) 0);
X			if(!(ilet = morc)) continue;
X			/* ... */
X		}
X#ifdef REDO
X		if (ilet != '?' && ilet != '*')	savech(ilet);
X#endif
X		if(flags.invlet_constant) {
X			for(otmp = invent; otmp; otmp = otmp->nobj)
X				if(otmp->invlet == ilet) break;
X		} else {
X			if(ilet >= 'A' && ilet <= 'Z') ilet += 'z'-'A'+1;
X			ilet -= 'a';
X			for(otmp = invent; otmp && ilet;
X					ilet--, otmp = otmp->nobj) ;
X		}
X		if(!otmp) {
X			pline("You don't have that object.");
X			continue;
X		}
X		if(cnt < 0 || otmp->quan < cnt) {
X			pline("You don't have that many! [You have %u]"
X			, otmp->quan);
X			continue;
X		}
X		break;
X	}
X	if(!allowall && let && !index(let,otmp->olet)) {
X		pline("That is a silly thing to %s.",word);
X		return(0);
X	}
X	if(allowcnt == 2) {	/* cnt given */
X		if(cnt == 0) return(0);
X		if(cnt != otmp->quan) {
X			register struct obj *obj;
X			obj = splitobj(otmp, (int) cnt);
X			if(otmp == uwep) setuwep(obj);
X		}
X	}
X	return(otmp);
X}
X
Xckunpaid(otmp) register struct obj *otmp; {
X	return( otmp->unpaid );
X}
X
X/* interactive version of getobj - used for Drop and Identify */
X/* return the number of times fn was called successfully */
Xggetobj(word, fn, max)
Xchar *word;
Xint (*fn)(),  max;
X{
Xchar buf[BUFSZ];
Xregister char *ip;
Xregister char sym;
Xregister int oletct = 0, iletct = 0;
Xregister boolean allflag = FALSE;
Xchar olets[20], ilets[20];
Xint (*ckfn)() = (int (*)()) 0;
Xxchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0;	/* BAH */
X	if(!invent && !allowgold){
X		pline("You have nothing to %s.", word);
X		return(0);
X	} else {
X		register struct obj *otmp = invent;
X		register int uflg = 0;
X
X		if(allowgold) ilets[iletct++] = '$';
X		ilets[iletct] = 0;
X		while(otmp) {
X			if(!index(ilets, otmp->olet)){
X				ilets[iletct++] = otmp->olet;
X				ilets[iletct] = 0;
X			}
X			if(otmp->unpaid) uflg = 1;
X			otmp = otmp->nobj;
X		}
X		ilets[iletct++] = ' ';
X		if(uflg) ilets[iletct++] = 'u';
X		if(invent) ilets[iletct++] = 'a';
X		ilets[iletct] = 0;
X	}
X	pline("What kinds of thing do you want to %s? [%s] ",
X		word, ilets);
X	getlin(buf);
X	if(buf[0] == '\033') {
X		clrlin();
X		return(0);
X	}
X	ip = buf;
X	olets[0] = 0;
X	while(sym = *ip++){
X		if(sym == ' ') continue;
X		if(sym == '$') {
X			if(allowgold == 1)
X				(*fn)(mkgoldobj(u.ugold));
X			else if(!u.ugold)
X				pline("You have no gold.");
X			allowgold = 2;
X		} else
X		if(sym == 'a' || sym == 'A') allflag = TRUE; else
X		if(sym == 'u' || sym == 'U') ckfn = ckunpaid; else
X#ifdef SPELLS
X		if(index("!%?[()=*/+\"0", sym)){
X#else
X		if(index("!%?[()=*/\"0", sym)){
X#endif
X			if(!index(olets, sym)){
X				olets[oletct++] = sym;
X				olets[oletct] = 0;
X			}
X		}
X		else pline("You don't have any %c's.", sym);
X	}
X	if(allowgold == 2 && !oletct)
X		return(1);	/* he dropped gold (or at least tried to) */
X	else
X		return(askchain(invent, olets, allflag, fn, ckfn, max));
X}
X
X/*
X * Walk through the chain starting at objchn and ask for all objects
X * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL)
X * whether the action in question (i.e., fn) has to be performed.
X * If allflag then no questions are asked. Max gives the max nr of
X * objects to be treated. Return the number of objects treated.
X */
Xaskchain(objchn, olets, allflag, fn, ckfn, max)
Xstruct obj *objchn;
Xregister char *olets;
Xint allflag;
Xint (*fn)(), (*ckfn)();
Xint max;
X{
Xregister struct obj *otmp, *otmp2;
Xregister char sym, ilet;
Xregister int cnt = 0;
X#ifdef SORTING
X	/* changes so the askchain is interrogated in the order specified.
X	 * For example, if a person specifies =/ then first all rings will be
X	 * asked about followed by all wands -dgk
X	 */
Xnextclass:
X#endif
X	ilet = 'a'-1;
X	for(otmp = objchn; otmp; otmp = otmp2){
X		if(ilet == 'z') ilet = 'A'; else ilet++;
X		otmp2 = otmp->nobj;
X#ifdef SORTING
X		if (olets && *olets && otmp->olet != *olets) continue;
X#else
X		if(olets && *olets && !index(olets, otmp->olet)) continue;
X#endif
X		if(ckfn && !(*ckfn)(otmp)) continue;
X		if(!allflag) {
X			pline(xprname(otmp, ilet));
X			addtopl(" [nyaq]? ");
X			sym = readchar();
X		}
X		else	sym = 'y';
X
X		switch(sym){
X		case 'a':
X			allflag = 1;
X		case 'y':
X			cnt += (*fn)(otmp);
X			if(--max == 0) goto ret;
X		case 'n':
X		default:
X			break;
X		case 'q':
X			goto ret;
X		}
X	}
X#ifdef SORTING
X	if (olets && *olets && *++olets)
X		goto nextclass;
X#endif
X	pline(cnt ? "That was all." : "No applicable objects.");
Xret:
X	return(cnt);
X}
X
Xobj_to_let(obj)	/* should of course only be called for things in invent */
Xregister struct obj *obj;
X{
X	register struct obj *otmp;
X	register char ilet;
X
X	if(flags.invlet_constant)
X		return(obj->invlet);
X	ilet = 'a';
X	for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj)
X		if(++ilet > 'z') ilet = 'A';
X	return(otmp ? ilet : NOINVSYM);
X}
X
Xprinv(obj)
Xregister struct obj *obj;
X{
X	pline(xprname(obj, obj_to_let(obj)));
X}
X
Xstatic char *
Xxprname(obj,let)
Xregister struct obj *obj;
Xregister char let;
X{
X	static char li[BUFSZ];
X
X	(void) sprintf(li, "%c - %s.",
X		flags.invlet_constant ? obj->invlet : let,
X		doname(obj));
X	return(li);
X}
X
Xddoinv()
X{
X	doinv((char *) 0);
X	return(0);
X}
X
X#ifdef SORTING
X# ifdef SPELLS
Xchar inv_order[] = "\")[%?+/=!(*0_`";	/* to be safe, include _ and ` */
X# else
Xchar inv_order[] = "\")[%?/=!(*0_`";
X# endif
Xextern char *let_to_name();
X#endif
X
X/* called with 0 or "": all objects in inventory */
X/* otherwise: all objects with (serial) letter in lets */
Xdoinv(lets)
Xregister char *lets;
X{
X	register struct obj *otmp;
X	register char ilet;
X	int ct = 0;
X	char any[BUFSZ];
X#ifdef SORTING
X	char *invlet = inv_order;
X	int classcount = 0;
X#endif /* SORTING /**/
X
X	morc = 0;		/* just to be sure */
X
X	if(!invent){
X		pline("Not carrying anything.");
X		return;
X	}
X
X	cornline(0, (char *) 0);
X#ifdef SORTING
Xnextclass:
X	classcount = 0;
X	ilet = 'a';
X	for(otmp = invent; otmp; otmp = otmp->nobj) {
X		if(flags.invlet_constant) ilet = otmp->invlet;
X		if(!lets || !*lets || index(lets, ilet)) {
X			if (!flags.sortpack || otmp->olet == *invlet) {
X				if (flags.sortpack && !classcount) {
X					cornline(1, let_to_name(*invlet));
X					classcount++;
X				}
X				cornline(1, xprname(otmp, ilet));
X				any[ct++] = ilet;
X			}
X		}
X		if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
X	}
X	if (flags.sortpack && *++invlet) goto nextclass;
X#else
X	ilet = 'a';
X	for(otmp = invent; otmp; otmp = otmp->nobj) {
X	    if(flags.invlet_constant) ilet = otmp->invlet;
X	    if(!lets || !*lets || index(lets, ilet)) {
X		    cornline(1, xprname(otmp, ilet));
X		    any[ct++] = ilet;
X	    }
X	    if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
X	}
X#endif /* SORTING /**/
X	any[ct] = 0;
X	cornline(2, any);
X}
X
Xdotypeinv ()				/* free after Robert Viduya */
X/* Changed to one type only, so he doesnt have to type cr */
X{
X    char c, ilet;
X    char stuff[BUFSZ];
X    register int stct;
X    register struct obj *otmp;
X    boolean billx = inshop() && doinvbill(0);
X    boolean unpd = FALSE;
X
X	if (!invent && !u.ugold && !billx) {
X	    pline ("You aren't carrying anything.");
X	    return(0);
X	}
X
X	stct = 0;
X	if(u.ugold) stuff[stct++] = '$';
X	stuff[stct] = 0;
X	for(otmp = invent; otmp; otmp = otmp->nobj) {
X	    if (!index (stuff, otmp->olet)) {
X		stuff[stct++] = otmp->olet;
X		stuff[stct] = 0;
X	    }
X	    if(otmp->unpaid)
X		unpd = TRUE;
X	}
X	if(unpd) stuff[stct++] = 'u';
X	if(billx) stuff[stct++] = 'x';
X	stuff[stct] = 0;
X
X	if(stct > 1) {
X#ifdef REDO
X	  if (!in_doagain)
X#endif
X	    pline ("What type of object [%s] do you want an inventory of? ",
X		stuff);
X	    c = readchar();
X#ifdef REDO
X	    savech(c);
X#endif
X	    if(index(quitchars,c)) return(0);
X	} else
X	    c = stuff[0];
X
X	if(c == '$')
X	    return(doprgold());
X
X	if(c == 'x' || c == 'X') {
X	    if(billx)
X		(void) doinvbill(1);
X	    else
X		pline("No used-up objects on the shopping bill.");
X	    return(0);
X	}
X
X	if((c == 'u' || c == 'U') && !unpd) {
X		pline("You are not carrying any unpaid objects.");
X		return(0);
X	}
X
X	stct = 0;
X	ilet = 'a';
X	for (otmp = invent; otmp; otmp = otmp -> nobj) {
X	    if(flags.invlet_constant) ilet = otmp->invlet;
X	    if (c == otmp -> olet || (c == 'u' && otmp -> unpaid))
X		stuff[stct++] = ilet;
X	    if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
X	}
X	stuff[stct] = '\0';
X	if(stct == 0)
X		pline("You have no such objects.");
X	else
X		doinv (stuff);
X
X	return(0);
X}
X
X/* look at what is here */
Xdolook() {
X    register struct obj *otmp, *otmp0;
X    register struct gold *gold;
X    char *verb = Blind ? "feel" : "see";
X    int	ct = 0;
X    int fd = 0;
X
X#ifdef KAA
X    if(!Blind) read_engr_at(u.ux, u.uy); /* Eric Backus */
X#endif
X    if(!u.uswallow) {
X	otmp0 = o_at(u.ux, u.uy);
X	gold = g_at(u.ux, u.uy);
X    }  else  {
X	pline("You %s no objects here.", verb);
X	return(!!Blind);
X    }
X
X    /* added by GAN 10/30/86 */
X#ifdef FOUNTAINS
X    if(IS_FOUNTAIN(levl[u.ux][u.uy].typ))  {
X	fd++;
X	pline("There is a fountain here.");
X    }
X#endif
X#ifdef NEWCLASS
X    if(IS_THRONE(levl[u.ux][u.uy].typ))  {
X	fd++;
X	pline("There is an opulent throne here.");
X    }    
X#endif
X    if(u.ux == xupstair && u.uy == yupstair)  {
X	fd++;
X	pline("There is a stairway up here.");
X    }
X    if(u.ux == xdnstair && u.uy == ydnstair)  {
X	fd++;
X	cornline(1, "There is a stairway down here.");
X    }
X    if(Blind)  {
X	 pline("You try to feel what is lying here on the floor.");
X	 if(Levitation)  {
X		pline("But you can't reach it!");
X		return(0);
X	 }
X    }
X 
X    if(!otmp0 && !gold) {
X	if(Blind || !fd)
X		pline("You %s no objects here.", verb);
X	return(!!Blind);
X    }
X
X    cornline(0, "Things that are here:");
X    for(otmp = otmp0; otmp; otmp = otmp->nobj) {
X	if(otmp->ox == u.ux && otmp->oy == u.uy) {
X	    ct++;
X	    cornline(1, doname(otmp));
X	    if(Blind && otmp->otyp == DEAD_COCKATRICE && !uarmg) {
X		pline("Touching the dead cockatrice is a fatal mistake ...");
X		pline("You die ...");
X		killer = "dead cockatrice";
X		done("died");
X	    }
X	}
X    }
X
X    if(gold) {
X	char gbuf[30];
X
X	(void) sprintf(gbuf, "%ld gold piece%s",
X		gold->amount, plur(gold->amount));
X	if(!ct++)
X	    pline("You %s here %s.", verb, gbuf);
X	else
X	    cornline(1, gbuf);
X    }
X
X    if(ct == 1 && !gold) {
X	pline("You %s here %s.", verb, doname(otmp0));
X	cornline(3, (char *) 0);
X    }
X    if(ct > 1)
X	cornline(2, (char *) 0);
X    return(!!Blind);
X}
X
Xstackobj(obj) register struct obj *obj; {
Xregister struct obj *otmp = fobj;
X	for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp != obj)
X	if(otmp->ox == obj->ox && otmp->oy == obj->oy &&
X		merged(obj,otmp,1))
X			return;
X}
X
X/* merge obj with otmp and delete obj if types agree */
Xmerged(otmp,obj,lose) register struct obj *otmp, *obj; {
X	if(obj->otyp == otmp->otyp &&
X	  obj->unpaid == otmp->unpaid &&
X	  obj->spe == otmp->spe &&
X	  obj->dknown == otmp->dknown &&
X	  obj->cursed == otmp->cursed &&
X#ifdef SPELLS
X	  (index("%*?!+", obj->olet) ||
X#else
X	  (index("%*?!", obj->olet) ||
X#endif
X	    (obj->known == otmp->known &&
X		(obj->olet == WEAPON_SYM && obj->otyp < BOOMERANG)))) {
X		otmp->quan += obj->quan;
X		otmp->owt += obj->owt;
X		if(lose) freeobj(obj);
X		obfree(obj,otmp);	/* free(obj), bill->otmp */
X		return(1);
X	} else	return(0);
X}
X
X/*
X * Gold is no longer displayed; in fact, when you have a lot of money,
X * it may take a while before you have counted it all.
X * [Bug: d$ and pickup still tell you how much it was.]
X */
Xextern int (*occupation)();
Xextern char *occtxt;
Xstatic long goldcounted;
X
Xcountgold(){
X	if((goldcounted += 100*(u.ulevel + 1)) >= u.ugold) {
X		long eps = 0;
X		if(!rn2(2)) eps = rnd((int) (u.ugold/100 + 1));
X		pline("You probably have about %ld gold pieces.",
X			u.ugold + eps);
X		return(0);	/* done */
X	}
X	return(1);		/* continue */
X}
X
Xdoprgold(){
X	if(!u.ugold)
X		pline("You do not carry any gold.");
X	else if(u.ugold <= 500)
X		pline("You are carrying %ld gold piece%s.", u.ugold, plur(u.ugold));
X	else {
X		pline("You sit down in order to count your gold pieces.");
X		goldcounted = 500;
X		occupation = countgold;
X		occtxt = "counting your gold";
X	}
X	return(1);
X}
X
X/* --- end of gold counting section --- */
X
Xdoprwep(){
X	if(!uwep) pline("You are empty handed.");
X	else prinv(uwep);
X	return(0);
X}
X
Xdoprarm(){
X	if(!uarm && !uarmg && !uarms && !uarmh)
X		pline("You are not wearing any armor.");
X	else {
X		char lets[6];
X		register int ct = 0;
X
X		if(uarm) lets[ct++] = obj_to_let(uarm);
X		if(uarm2) lets[ct++] = obj_to_let(uarm2);
X		if(uarmh) lets[ct++] = obj_to_let(uarmh);
X		if(uarms) lets[ct++] = obj_to_let(uarms);
X		if(uarmg) lets[ct++] = obj_to_let(uarmg);
X		lets[ct] = 0;
X		doinv(lets);
X	}
X	return(0);
X}
X
Xdoprring(){
X	if(!uleft && !uright)
X		pline("You are not wearing any rings.");
X	else {
X		char lets[3];
X		register int ct = 0;
X
X		if(uleft) lets[ct++] = obj_to_let(uleft);
X		if(uright) lets[ct++] = obj_to_let(uright);
X		lets[ct] = 0;
X		doinv(lets);
X	}
X	return(0);
X}
X
Xdigit(c) char c; {
X	return(c >= '0' && c <= '9');
X}
X
X/*
X * useupf(obj)
X * uses up an object that's on the floor
X */
Xuseupf(obj)
Xregister struct obj *obj;
X{
X	if(obj->quan > 1)  {
X		obj->quan--;
X		obj->owt = weight(obj);
X	}  else delobj(obj);
X}
X
X#ifdef SORTING
X/*
X * Convert from a symbol to a string for printing object classes
X *
X * Names from objects.h
X * char obj_symbols[] = {
X *	ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM,
X *	BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM, POTION_SYM, SCROLL_SYM,
X *	WAND_SYM, [SPBOOK_SYM], RING_SYM, GEM_SYM, 0 };
X */
X#define Sprintf (void) sprintf
X
Xextern char obj_symbols[];
Xstatic char *names[] = {"Illegal objects", "Amulets", "Comestibles", "Weapons",
X			"Tools", "Iron balls", "Chains", "Rocks", "Armor",
X			"Potions", "Scrolls", "Wands",
X#ifdef SPELLS
X			"Spellbooks",
X#endif
X			"Rings", "Gems"};
Xchar *
Xlet_to_name(let)
Xchar let;
X{
X	char *pos = index(obj_symbols, let);
X	extern char *HI, *HE;
X	/* buffer size is len(HI) + len(HE) + max(len(names[])) + 1 */
X	static char buf[4 + 4 + 15 + 1];
X
X	if (pos == NULL) pos = obj_symbols;
X	Sprintf(buf, "%s%s%s", HI, names[pos - obj_symbols], HE);
X	return (buf);
X}
X#endif /* SORTING /**/
END_OF_invent.c
if test 22500 -ne `wc -c <invent.c`; then
    echo shar: \"invent.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mklev.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"mklev.c\"
else
echo shar: Extracting \"mklev.c\" \(19671 characters\)
sed "s/^X//" >mklev.c <<'END_OF_mklev.c'
X/*	SCCS Id: @(#)mklev.c	1.3	87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* mklev.c - version 1.0.3 */
X
X#include "hack.h"
X
Xextern char *getlogin(), *getenv();
Xextern struct monst *makemon();
Xextern struct obj *mkobj_at();
Xextern struct trap *maketrap();
X
X#define somex() ((rand()%(croom->hx-croom->lx+1))+croom->lx)
X#define somey() ((rand()%(croom->hy-croom->ly+1))+croom->ly)
X
X#include "mkroom.h"
X#define	XLIM	4	/* define minimum required space around a room */
X#define	YLIM	3
Xboolean secret;		/* TRUE while making a vault: increase [XY]LIM */
Xstruct mkroom rooms[MAXNROFROOMS+1];
Xint smeq[MAXNROFROOMS+1];
Xcoord doors[DOORMAX];
Xint doorindex;
Xstruct rm zerorm;
Xint comp();
Xschar nxcor;
Xboolean goldseen;
Xint nroom;
Xxchar xdnstair,xupstair,ydnstair,yupstair;
X
X/* Definitions used by makerooms() and addrs() */
X#define	MAXRS	50	/* max lth of temp rectangle table - arbitrary */
Xstruct rectangle {
X	xchar rlx,rly,rhx,rhy;
X} rs[MAXRS+1];
Xint rscnt,rsmax;	/* 0..rscnt-1: currently under consideration */
X			/* rscnt..rsmax: discarded */
X
Xmakelevel()
X{
X	register struct mkroom *croom, *troom;
X	register unsigned tryct;
X#ifndef REGBUG
X	register
X#endif
X		 int x,y;
X
X	nroom = 0;
X	doorindex = 0;
X	rooms[0].hx = -1;	/* in case we are in a maze */
X
X	for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++)
X		levl[x][y] = zerorm;
X
X	oinit();	/* assign level dependent obj probabilities */
X
X	if(dlevel >= rn1(3, 26)) {	/* there might be several mazes */
X		makemaz();
X		return;
X	}
X
X	/* construct the rooms */
X	nroom = 0;
X	secret = FALSE;
X	(void) makerooms();
X
X	/* construct stairs (up and down in different rooms if possible) */
X	croom = &rooms[rn2(nroom)];
X	xdnstair = somex();
X	ydnstair = somey();
X	levl[xdnstair][ydnstair].scrsym ='>';
X	levl[xdnstair][ydnstair].typ = STAIRS;
X	if(nroom > 1) {
X		troom = croom;
X		croom = &rooms[rn2(nroom-1)];
X		if(croom >= troom) croom++;
X	}
X	xupstair = somex();	/* %% < and > might be in the same place */
X	yupstair = somey();
X	levl[xupstair][yupstair].scrsym ='<';
X	levl[xupstair][yupstair].typ = STAIRS;
X
X	/* for each room: put things inside */
X	for(croom = rooms; croom->hx > 0; croom++) {
X
X		/* put a sleeping monster inside */
X		/* Note: monster may be on the stairs. This cannot be
X		   avoided: maybe the player fell through a trapdoor
X		   while a monster was on the stairs. Conclusion:
X		   we have to check for monsters on the stairs anyway. */
X		if(!rn2(3)) (void)
X			makemon((struct permonst *) 0, somex(), somey());
X
X		/* put traps and mimics inside */
X		goldseen = FALSE;
X		while(!rn2(8-(dlevel/6))) mktrap(0,0,croom);
X		if(!goldseen && !rn2(3)) mkgold(0L,somex(),somey());
X#ifdef FOUNTAINS
X		if(!rn2(10)) mkfount(0,croom);
X#endif
X		if(!rn2(3)) {
X			(void) mkobj_at(0, somex(), somey());
X			tryct = 0;
X			while(!rn2(5)) {
X				if(++tryct > 100){
X					printf("tryct overflow4\n");
X					break;
X				}
X				(void) mkobj_at(0, somex(), somey());
X			}
X		}
X	}
X
X	qsort((char *) rooms, nroom, sizeof(struct mkroom), comp);
X	makecorridors();
X	make_niches();
X
X	/* make a secret treasure vault, not connected to the rest */
X	if(nroom <= (2*MAXNROFROOMS/3)) if(rn2(3)) {
X		troom = &rooms[nroom];
X		secret = TRUE;
X		if(makerooms()) {
X			troom->rtype = VAULT;		/* treasure vault */
X			for(x = troom->lx; x <= troom->hx; x++)
X			for(y = troom->ly; y <= troom->hy; y++)
X				mkgold((long)(rnd(dlevel*100) + 50), x, y);
X			if(!rn2(3))
X				makevtele();
X		}
X	}
X
X#ifdef WIZARD
X	if(wizard && getenv("SHOPTYPE")) mkshop(); else
X#endif
X	if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 3) mkshop();
X	else
X#ifdef NEWCLASS
X	if(dlevel > 4 && !rn2(6)) mkzoo(COURT);
X#endif
X	if(dlevel > 6 && !rn2(7)) mkzoo(ZOO);
X	else
X	if(dlevel > 9 && !rn2(5)) mkzoo(BEEHIVE);
X	else
X	if(dlevel > 11 && !rn2(6)) mkzoo(MORGUE);
X	else
X	if(dlevel > 18 && !rn2(6)) mkswamp();
X}
X
Xmakerooms() {
Xregister struct rectangle *rsp;
Xregister int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy;
Xint tryct = 0, xlim, ylim;
X
X	/* init */
X	xlim = XLIM + secret;
X	ylim = YLIM + secret;
X	if(nroom == 0) {
X		rsp = rs;
X		rsp->rlx = rsp->rly = 0;
X		rsp->rhx = COLNO-1;
X		rsp->rhy = ROWNO-1;
X		rsmax = 1;
X	}
X	rscnt = rsmax;
X
X	/* make rooms until satisfied */
X	while(rscnt > 0 && nroom < MAXNROFROOMS-1) {
X		if(!secret && nroom > (MAXNROFROOMS/3) &&
X		   !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom)))
X			return(0);
X
X		/* pick a rectangle */
X		rsp = &rs[rn2(rscnt)];
X		hx = rsp->rhx;
X		hy = rsp->rhy;
X		lx = rsp->rlx;
X		ly = rsp->rly;
X
X		/* find size of room */
X		if(secret)
X			dx = dy = 1;
X		else {
X			dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8);
X			dy = 2 + rn2(4);
X			if(dx*dy > 50)
X				dy = 50/dx;
X		}
X
X		/* look whether our room will fit */
X		if(hx-lx < dx + dx/2 + 2*xlim || hy-ly < dy + dy/3 + 2*ylim) {
X					/* no, too small */
X					/* maybe we throw this area out */
X			if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) {
X				rscnt--;
X				rs[rsmax] = *rsp;
X				*rsp = rs[rscnt];
X				rs[rscnt] = rs[rsmax];
X				tryct = 0;
X			} else
X				tryct++;
X			continue;
X		}
X
X		lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1);
X		lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1);
X		hix = lowx + dx;
X		hiy = lowy + dy;
X
X		if(maker(lowx, dx, lowy, dy)) {
X			if(secret) return(1);
X			addrs(lowx-1, lowy-1, hix+1, hiy+1);
X			tryct = 0;
X		} else
X			if(tryct++ > 100)
X				break;
X	}
X	return(0);	/* failed to make vault - very strange */
X}
X
Xaddrs(lowx,lowy,hix,hiy)
Xregister int lowx,lowy,hix,hiy;
X{
X	register struct rectangle *rsp;
X	register int lx,ly,hx,hy,xlim,ylim;
X	boolean discarded;
X
X	xlim = XLIM + secret;
X	ylim = YLIM + secret;
X
X	/* walk down since rscnt and rsmax change */
X	for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) {
X		
X		if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||
X		   (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy)
X			continue;
X		if((discarded = (rsp >= &rs[rscnt]))) {
X			*rsp = rs[--rsmax];
X		} else {
X			rsmax--;
X			rscnt--;
X			*rsp = rs[rscnt];
X			if(rscnt != rsmax)
X				rs[rscnt] = rs[rsmax];
X		}
X		if(lowy - ly > 2*ylim + 4)
X			addrsx(lx,ly,hx,lowy-2,discarded);
X		if(lowx - lx > 2*xlim + 4)
X			addrsx(lx,ly,lowx-2,hy,discarded);
X		if(hy - hiy > 2*ylim + 4)
X			addrsx(lx,hiy+2,hx,hy,discarded);
X		if(hx - hix > 2*xlim + 4)
X			addrsx(hix+2,ly,hx,hy,discarded);
X	}
X}
X
Xaddrsx(lx,ly,hx,hy,discarded)
Xregister int lx,ly,hx,hy;
Xboolean discarded;		/* piece of a discarded area */
X{
X	register struct rectangle *rsp;
X
X	/* check inclusions */
X	for(rsp = rs; rsp < &rs[rsmax]; rsp++) {
X		if(lx >= rsp->rlx && hx <= rsp->rhx &&
X		   ly >= rsp->rly && hy <= rsp->rhy)
X			return;
X	}
X
X	/* make a new entry */
X	if(rsmax >= MAXRS) {
X#ifdef WIZARD
X		if(wizard) pline("MAXRS may be too small.");
X#endif
X		return;
X	}
X	rsmax++;
X	if(!discarded) {
X		*rsp = rs[rscnt];
X		rsp = &rs[rscnt];
X		rscnt++;
X	}
X	rsp->rlx = lx;
X	rsp->rly = ly;
X	rsp->rhx = hx;
X	rsp->rhy = hy;
X}
X
Xcomp(x,y)
Xregister struct mkroom *x,*y;
X{
X	if(x->lx < y->lx) return(-1);
X	return(x->lx > y->lx);
X}
X
Xcoord
Xfinddpos(xl,yl,xh,yh) {
X	coord ff;
X	register x,y;
X
X	x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
X	y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
X	if(okdoor(x, y))
X		goto gotit;
X
X	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
X		if(okdoor(x, y))
X			goto gotit;
X
X	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
X		if(levl[x][y].typ == DOOR || levl[x][y].typ == SDOOR)
X			goto gotit;
X	/* cannot find something reasonable -- strange */
X	x = xl;
X	y = yh;
Xgotit:
X	ff.x = x;
X	ff.y = y;
X	return(ff);
X}
X
X/* see whether it is allowable to create a door at [x,y] */
Xokdoor(x,y)
Xregister x,y;
X{
X	if(levl[x-1][y].typ == DOOR || levl[x+1][y].typ == DOOR ||
X	   levl[x][y+1].typ == DOOR || levl[x][y-1].typ == DOOR ||
X	   levl[x-1][y].typ == SDOOR || levl[x+1][y].typ == SDOOR ||
X	   levl[x][y-1].typ == SDOOR || levl[x][y+1].typ == SDOOR ||
X	   (levl[x][y].typ != HWALL && levl[x][y].typ != VWALL) ||
X	   doorindex >= DOORMAX)
X		return(0);
X	return(1);
X}
X
Xdodoor(x,y,aroom)
Xregister x,y;
Xregister struct mkroom *aroom;
X{
X	if(doorindex >= DOORMAX) {
X		impossible("DOORMAX exceeded?");
X		return;
X	}
X	if(!okdoor(x,y) && nxcor)
X		return;
X	dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);
X}
X
Xdosdoor(x,y,aroom,type)
Xregister x,y;
Xregister struct mkroom *aroom;
Xregister type;
X{
X	register struct mkroom *broom;
X	register tmp;
X
X	if(!IS_WALL(levl[x][y].typ))	/* avoid SDOORs with '+' as scrsym */
X		type = DOOR;
X	levl[x][y].typ = type;
X	if(type == DOOR)
X#ifdef DGK
X		levl[x][y].scrsym = symbol.door;
X#else
X		levl[x][y].scrsym = '+';
X#endif /* DGK /**/
X	aroom->doorct++;
X	broom = aroom+1;
X	if(broom->hx < 0) tmp = doorindex; else
X	for(tmp = doorindex; tmp > broom->fdoor; tmp--)
X		doors[tmp] = doors[tmp-1];
X	doorindex++;
X	doors[tmp].x = x;
X	doors[tmp].y = y;
X	for( ; broom->hx >= 0; broom++) broom->fdoor++;
X}
X
X/* Only called from makerooms() */
Xmaker(lowx,ddx,lowy,ddy)
Xschar lowx,ddx,lowy,ddy;
X{
X	register struct mkroom *croom;
X	register x, y, hix = lowx+ddx, hiy = lowy+ddy;
X	register xlim = XLIM + secret, ylim = YLIM + secret;
X
X	if(nroom >= MAXNROFROOMS) return(0);
X	if(lowx < XLIM) lowx = XLIM;
X	if(lowy < YLIM) lowy = YLIM;
X	if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1;
X	if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1;
Xchk:
X	if(hix <= lowx || hiy <= lowy) return(0);
X
X	/* check area around room (and make room smaller if necessary) */
X	for(x = lowx - xlim; x <= hix + xlim; x++) {
X		for(y = lowy - ylim; y <= hiy + ylim; y++) {
X			if(levl[x][y].typ) {
X#ifdef WIZARD
X			    if(wizard && !secret)
X				pline("Strange area [%d,%d] in maker().",x,y);
X#endif
X				if(!rn2(3)) return(0);
X				if(x < lowx)
X					lowx = x+xlim+1;
X				else
X					hix = x-xlim-1;
X				if(y < lowy)
X					lowy = y+ylim+1;
X				else
X					hiy = y-ylim-1;
X				goto chk;
X			}
X		}
X	}
X
X	croom = &rooms[nroom];
X
X	/* on low levels the room is lit (usually) */
X	/* secret vaults are always lit */
X	if((rnd(dlevel) < 10 && rn2(77)) || (ddx == 1 && ddy == 1)) {
X		for(x = lowx-1; x <= hix+1; x++)
X			for(y = lowy-1; y <= hiy+1; y++)
X				levl[x][y].lit = 1;
X		croom->rlit = 1;
X	} else
X		croom->rlit = 0;
X	croom->lx = lowx;
X	croom->hx = hix;
X	croom->ly = lowy;
X	croom->hy = hiy;
X	croom->rtype = croom->doorct = croom->fdoor = 0;
X
X#ifdef DGK
X	for(x = lowx-1; x <= hix+1; x++)
X	    for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
X		levl[x][y].scrsym = symbol.hwall;
X		levl[x][y].typ = HWALL;
X	}
X	for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
X	    for(y = lowy; y <= hiy; y++) {
X		levl[x][y].scrsym = symbol.vwall;
X		levl[x][y].typ = VWALL;
X	}
X	for(x = lowx; x <= hix; x++)
X	    for(y = lowy; y <= hiy; y++) {
X		levl[x][y].scrsym = symbol.room;
X		levl[x][y].typ = ROOM;
X	}
X	levl[lowx-1][lowy-1].scrsym = symbol.tlcorn;
X	levl[hix+1][lowy-1].scrsym = symbol.trcorn;
X	levl[lowx-1][hiy+1].scrsym = symbol.blcorn;
X	levl[hix+1][hiy+1].scrsym = symbol.brcorn;
X#else
X	for(x = lowx-1; x <= hix+1; x++)
X	    for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
X		levl[x][y].scrsym = '-';
X		levl[x][y].typ = HWALL;
X	}
X	for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
X	    for(y = lowy; y <= hiy; y++) {
X		levl[x][y].scrsym = '|';
X		levl[x][y].typ = VWALL;
X	}
X	for(x = lowx; x <= hix; x++)
X	    for(y = lowy; y <= hiy; y++) {
X		levl[x][y].scrsym = '.';
X		levl[x][y].typ = ROOM;
X	}
X#endif /* DGK /**/
X
X	smeq[nroom] = nroom;
X	croom++;
X	croom->hx = -1;
X	nroom++;
X	return(1);
X}
X
Xmakecorridors() {
X	register a,b;
X
X	nxcor = 0;
X	for(a = 0; a < nroom-1; a++)
X		join(a, a+1);
X	for(a = 0; a < nroom-2; a++)
X	    if(smeq[a] != smeq[a+2])
X		join(a, a+2);
X	for(a = 0; a < nroom; a++)
X	    for(b = 0; b < nroom; b++)
X		if(smeq[a] != smeq[b])
X		    join(a, b);
X	if(nroom > 2)
X	    for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) {
X		a = rn2(nroom);
X		b = rn2(nroom-2);
X		if(b >= a) b += 2;
X		join(a, b);
X	    }
X}
X
Xjoin(a,b)
Xregister a,b;
X{
X	coord cc,tt;
X	register tx, ty, xx, yy;
X	register struct rm *crm;
X	register struct mkroom *croom, *troom;
X	register dx, dy, dix, diy, cct;
X
X	croom = &rooms[a];
X	troom = &rooms[b];
X
X	/* find positions cc and tt for doors in croom and troom
X	   and direction for a corridor between them */
X
X	if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
X	if(troom->lx > croom->hx) {
X		dx = 1;
X		dy = 0;
X		xx = croom->hx+1;
X		tx = troom->lx-1;
X		cc = finddpos(xx,croom->ly,xx,croom->hy);
X		tt = finddpos(tx,troom->ly,tx,troom->hy);
X	} else if(troom->hy < croom->ly) {
X		dy = -1;
X		dx = 0;
X		yy = croom->ly-1;
X		cc = finddpos(croom->lx,yy,croom->hx,yy);
X		ty = troom->hy+1;
X		tt = finddpos(troom->lx,ty,troom->hx,ty);
X	} else if(troom->hx < croom->lx) {
X		dx = -1;
X		dy = 0;
X		xx = croom->lx-1;
X		tx = troom->hx+1;
X		cc = finddpos(xx,croom->ly,xx,croom->hy);
X		tt = finddpos(tx,troom->ly,tx,troom->hy);
X	} else {
X		dy = 1;
X		dx = 0;
X		yy = croom->hy+1;
X		ty = troom->ly-1;
X		cc = finddpos(croom->lx,yy,croom->hx,yy);
X		tt = finddpos(troom->lx,ty,troom->hx,ty);
X	}
X	xx = cc.x;
X	yy = cc.y;
X	tx = tt.x - dx;
X	ty = tt.y - dy;
X	if(nxcor && levl[xx+dx][yy+dy].typ)
X		return;
X	dodoor(xx,yy,croom);
X
X	cct = 0;
X	while(xx != tx || yy != ty) {
X	    xx += dx;
X	    yy += dy;
X
X	    /* loop: dig corridor at [xx,yy] and find new [xx,yy] */
X	    if(cct++ > 500 || (nxcor && !rn2(35)))
X		return;
X
X	    if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1)
X		return;		/* impossible */
X
X	    crm = &levl[xx][yy];
X	    if(!(crm->typ)) {
X		if(rn2(100)) {
X			crm->typ = CORR;
X#ifdef DGK
X			crm->scrsym = symbol.corr;
X#else
X			crm->scrsym = CORR_SYM;
X#endif
X			if(nxcor && !rn2(50))
X				(void) mkobj_at(ROCK_SYM, xx, yy);
X		} else {
X			crm->typ = SCORR;
X			crm->scrsym = ' ';
X		}
X	    } else
X	    if(crm->typ != CORR && crm->typ != SCORR) {
X		/* strange ... */
X		return;
X	    }
X
X	    /* find next corridor position */
X	    dix = abs(xx-tx);
X	    diy = abs(yy-ty);
X
X	    /* do we have to change direction ? */
X	    if(dy && dix > diy) {
X		register ddx = (xx > tx) ? -1 : 1;
X
X		crm = &levl[xx+ddx][yy];
X		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
X		    dx = ddx;
X		    dy = 0;
X		    continue;
X		}
X	    } else if(dx && diy > dix) {
X		register ddy = (yy > ty) ? -1 : 1;
X
X		crm = &levl[xx][yy+ddy];
X		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
X		    dy = ddy;
X		    dx = 0;
X		    continue;
X		}
X	    }
X
X	    /* continue straight on? */
X	    crm = &levl[xx+dx][yy+dy];
X	    if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
X		continue;
X
X	    /* no, what must we do now?? */
X	    if(dx) {
X		dx = 0;
X		dy = (ty < yy) ? -1 : 1;
X		crm = &levl[xx+dx][yy+dy];
X		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
X		    continue;
X		dy = -dy;
X		continue;
X	    } else {
X		dy = 0;
X		dx = (tx < xx) ? -1 : 1;
X		crm = &levl[xx+dx][yy+dy];
X		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
X		    continue;
X		dx = -dx;
X		continue;
X	    }
X	}
X
X	/* we succeeded in digging the corridor */
X	dodoor(tt.x, tt.y, troom);
X
X	if(smeq[a] < smeq[b])
X		smeq[b] = smeq[a];
X	else
X		smeq[a] = smeq[b];
X}
X
Xmake_niches()
X{
X	register int ct = rnd(nroom/2 + 1);
X#ifdef NEWCLASS
X	boolean	ltptr = TRUE,
X		vamp = TRUE;
X
X	while(ct--) {
X
X		if(dlevel > 15 && rn1(6,0) == 0 && ltptr) {
X
X			ltptr = FALSE;
X			makeniche(LEVEL_TELEP);
X		} if (rn1(6,0) == 0)	{
X
X			vamp = FALSE;
X			makeniche(TRAPDOOR);
X		} else	makeniche(NO_TRAP);
X	}
X#else
X	while(ct--) makeniche(NO_TRAP);
X#endif
X}
X
Xmakevtele()
X{
X	makeniche(TELEP_TRAP);
X}
X
X/* there should be one of these per trap */
Xchar    *engravings[] = {       "", "", "", "", "",
X				"ad ae?ar um", "?la? ?as ?er?",
X				"", "", ""
X#ifdef NEWTRAPS
X				,"", ""
X#endif
X#ifdef SPIDERS
X				,""
X#endif
X#ifdef NEWCLASS
X				, "", "ad ae?ar um"
X#endif
X#ifdef SPELLS
X				,""
X#endif
X				};
X
Xmakeniche(trap_type)
Xint trap_type;
X{
X	register struct mkroom *aroom;
X	register struct rm *rm;
X	register int vct = 8;
X	coord dd;
X	register dy,xx,yy;
X	register struct trap *ttmp;
X
X	if(doorindex < DOORMAX)
X	  while(vct--) {
X	    aroom = &rooms[rn2(nroom-1)];
X	    if(aroom->rtype != 0) continue;	/* not an ordinary room */
X	    if(aroom->doorct == 1 && rn2(5)) continue;
X	    if(rn2(2)) {
X		dy = 1;
X		dd = finddpos(aroom->lx,aroom->hy+1,aroom->hx,aroom->hy+1);
X	    } else {
X		dy = -1;
X		dd = finddpos(aroom->lx,aroom->ly-1,aroom->hx,aroom->ly-1);
X	    }
X	    xx = dd.x;
X	    yy = dd.y;
X	    if((rm = &levl[xx][yy+dy])->typ) continue;
X	    if(trap_type || !rn2(4)) {
X
X		rm->typ = SCORR;
X		rm->scrsym = ' ';
X		if(trap_type) {
X		    ttmp = maketrap(xx, yy+dy, trap_type);
X		    ttmp->once = 1;
X		    if (strlen(engravings[trap_type]) > 0)
X			make_engr_at(xx, yy-dy, engravings[trap_type]);
X		}
X		dosdoor(xx, yy, aroom, SDOOR);
X	    } else {
X		rm->typ = CORR;
X#ifdef DGK
X		rm->scrsym = symbol.corr;
X#else
X		rm->scrsym = CORR_SYM;
X#endif
X		if(rn2(7))
X		    dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
X		else {
X		    mksobj_at(SCR_TELEPORTATION, xx, yy+dy);
X		    if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy);
X		}
X	    }
X	    return;
X	}
X}
X
X/* make a trap somewhere (in croom if mazeflag = 0) */
Xmktrap(num, mazeflag, croom)
X#ifndef REGBUG
Xregister
X#endif
X	 int num, mazeflag;
X#ifndef REGBUG
Xregister
X#endif
X	 struct mkroom *croom;
X{
X#ifndef REGBUG
X	register
X#endif
X		 struct trap *ttmp;
X#ifndef REGBUG
X	register
X#endif
X		 int kind,nopierc,nomimic,fakedoor,fakegold,
X#ifdef NEWCLASS
X		     nospikes, nolevltp,
X#endif
X		     tryct = 0;
X	xchar mx,my;
X	extern char fut_geno[];
X
X	if(!num || num >= TRAPNUM) {
X		nopierc = (dlevel < 4) ? 1 : 0;
X#ifdef NEWCLASS
X		nolevltp = (dlevel < 5) ? 1 : 0;
X		nospikes = (dlevel < 6) ? 1 : 0;
X#endif
X		nomimic = (dlevel < 9 || goldseen ) ? 1 : 0;
X		if(index(fut_geno, 'M')) nomimic = 1;
X
X		do {
X		    kind = rnd(TRAPNUM-1);
X			if((kind == PIERC && nopierc) ||
X			   (kind == MIMIC && nomimic)
X#ifdef SPIDERS
X			   || (kind == WEB)
X#endif
X#ifdef NEWCLASS
X			   || (kind == SPIKED_PIT && nospikes)
X			   || (kind == LEVEL_TELEP && nolevltp)
X#endif
X			   )  kind = NO_TRAP;
X		} while(kind == NO_TRAP);
X	} else kind = num;
X
X	if(kind == MIMIC) {
X		register struct monst *mtmp;
X
X		fakedoor = (!rn2(3) && !mazeflag);
X		fakegold = (!fakedoor && !rn2(2));
X		if(fakegold) goldseen = TRUE;
X		do {
X			if(++tryct > 200) return;
X			if(fakedoor) {
X				/* note: fakedoor maybe on actual door */
X				if(rn2(2)){
X				    if(rn2(2))	mx = croom->hx+1;
X				    else	mx = croom->lx-1;
X				    my = somey();
X				} else {
X				    if(rn2(2))	my = croom->hy+1;
X				    else	my = croom->ly-1;
X				    mx = somex();
X				}
X			} else if(mazeflag) {
X				extern coord mazexy();
X				coord mm;
X				mm = mazexy();
X				mx = mm.x;
X				my = mm.y;
X			} else {
X				mx = somex();
X				my = somey();
X			}
X		} while(m_at(mx,my) || levl[mx][my].typ == STAIRS);
X		if(mtmp = makemon(PM_MIMIC,mx,my)) {
X		    mtmp->mimic = 1;
X		    mtmp->mappearance =
X#ifdef DGK
X			fakegold ? '$' : fakedoor ? symbol.door :
X#else
X			fakegold ? '$' : fakedoor ? '+' :
X#endif
X			(mazeflag && rn2(2)) ? AMULET_SYM :
X#ifdef SPELLS
X			"=/)%?![<>+" [ rn2(10) ];
X#else
X			"=/)%?![<>" [ rn2(9) ];
X#endif
X		}
X		return;
X	}
X
X	do {
X		if(++tryct > 200)
X			return;
X		if(mazeflag){
X			extern coord mazexy();
X			coord mm;
X			mm = mazexy();
X			mx = mm.x;
X			my = mm.y;
X		} else {
X			mx = somex();
X			my = somey();
X		}
X	} while(t_at(mx, my) || levl[mx][my].typ == STAIRS);
X	ttmp = maketrap(mx, my, kind);
X	if(mazeflag && !rn2(10) && ttmp->ttyp < PIERC)
X		ttmp->tseen = 1;
X}
X
X#ifdef FOUNTAINS
Xmkfount(mazeflag,croom)
Xregister struct mkroom *croom;
Xregister mazeflag;
X{
X      register xchar mx,my;
X      register int tryct = 0;
X
X      do {
X	      if(++tryct > 200)
X		      return;
X	      if(mazeflag){
X		      extern coord mazexy();
X		      coord mm;
X		      mm = mazexy();
X		      mx = mm.x;
X		      my = mm.y;
X	      } else {
X		      mx = somex();
X		      my = somey();
X	      }
X      } while(t_at(mx, my) || levl[mx][my].typ == STAIRS
X#ifdef NEWCLASS
X	      || IS_THRONE(levl[mx][my].typ)
X#endif
X	     );
X
X       /* Put a fountain at mx, my */
X
X       levl[mx][my].typ = FOUNTAIN;
X       levl[mx][my].scrsym = FOUNTAIN_SYM;
X
X}
X#endif /* FOUNTAINS /**/
X
END_OF_mklev.c
if test 19671 -ne `wc -c <mklev.c`; then
    echo shar: \"mklev.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f options.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"options.c\"
else
echo shar: Extracting \"options.c\" \(8991 characters\)
sed "s/^X//" >options.c <<'END_OF_options.c'
X/*	SCCS Id: @(#)options.c	1.3	87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* options.c - version 1.0.3 */
X
X#include "config.h"
X#include "hack.h"
Xextern char *eos();
X#ifdef SORTING
Xstatic boolean set_order;
X#endif
X
Xinitoptions()
X{
X	register char *opts;
X	extern char *getenv();
X
X	flags.time = flags.nonews = flags.notombstone = flags.end_own =
X	flags.standout = flags.nonull = FALSE;
X	flags.no_rest_on_space = TRUE;
X	flags.invlet_constant = TRUE;
X	flags.end_top = 5;
X	flags.end_around = 4;
X	flags.female = FALSE;			/* players are usually male */
X#ifdef SORTING
X	flags.sortpack = TRUE;
X#endif
X#ifdef SAFE_ATTACK
X	flags.confirm = TRUE;
X#endif
X#ifdef DGKMOD
X	flags.silent = 	flags.pickup = TRUE;
X#endif
X#ifdef DGK
X	flags.IBMBIOS = flags.DECRainbow = flags.rawio = FALSE;
X	read_config_file();
X#else
X	if(opts = getenv("HACKOPTIONS"))
X		parseoptions(opts,TRUE);
X#endif
X}
X
Xparseoptions(opts, from_env)
Xregister char *opts;
Xboolean from_env;
X{
X	register char *op,*op2;
X	unsigned num;
X	boolean negated;
X
X	if(op = index(opts, ',')) {
X		*op++ = 0;
X		parseoptions(op, from_env);
X	}
X	if(op = index(opts, ' ')) {
X		op2 = op;
X		while(*op++)
X			if(*op != ' ') *op2++ = *op;
X	}
X	if(!*opts) return;
X	negated = FALSE;
X	while((*opts == '!') || !strncmp(opts, "no", 2)) {
X		if(*opts == '!') opts++; else opts += 2;
X		negated = !negated;
X	}
X	
X#ifndef DGK
X	if(!strncmp(opts,"standout",4)) {
X		flags.standout = !negated;
X		return;
X	}
X
X	if(!strncmp(opts,"null",4)) {
X		flags.nonull = negated;
X		return;
X	}
X
X	if(!strncmp(opts,"tombstone",4)) {
X		flags.notombstone = negated;
X		return;
X	}
X
X	if(!strncmp(opts,"news",4)) {
X		flags.nonews = negated;
X		return;
X	}
X#endif
X
X#ifdef SAFE_ATTACK
X	if (!strncmp(opts, "conf", 4)) {
X		flags.confirm = !negated;
X		return;
X	}
X
X#endif
X#ifdef DGKMOD
X	if (!strncmp(opts, "sile", 4)) {
X		flags.silent = !negated;
X		return;
X	}
X
X	if (!strncmp(opts, "pick", 4)) {
X		flags.pickup = !negated;
X		return;
X	}
X#endif
X#ifdef DGK
X	if (!strncmp(opts, "IBMB", 4)) {
X		flags.IBMBIOS = !negated;
X		return;
X	}
X
X	if (!strncmp(opts, "rawi", 4)) {
X		if (from_env)
X			flags.rawio = !negated;
X		else
X			pline("'rawio' only settable from %s.", configfile);
X		return;
X	}
X
X	if (!strncmp(opts, "DECR", 4)) {
X		flags.DECRainbow = !negated;
X		return;
X	}
X#endif
X
X#ifdef SORTING
X	if (!strncmp(opts, "sort", 4)) {
X		flags.sortpack = !negated;
X		return;
X	}
X
X	/*
X	 * the order to list the pack
X	 */
X	if (!strncmp(opts,"packorder",4)) {
X		register char	*sp, *tmp;
X		extern char	inv_order[];
X		int tmpend;
X
X		op = index(opts,':');
X		if(!op) goto bad;
X		op++;			/* skip : */
X
X		/* Missing characters in new order are filled in at the end 
X		 * from inv_order.
X		 */
X		for (sp = op; *sp; sp++)
X			if (!index(inv_order, *sp))
X				goto bad;		/* bad char in order */
X			else if (index(sp + 1, *sp))
X				goto bad;		/* dup char in order */
X		tmp = (char *) alloc(strlen(inv_order) + 1);
X		(void) strcpy(tmp, op);
X		for (sp = inv_order, tmpend = strlen(tmp); *sp; sp++)
X			if (!index(tmp, *sp)) {
X				tmp[tmpend++] = *sp;
X				tmp[tmpend] = 0;
X			}
X		(void) strcpy(inv_order, tmp);
X		free(tmp);
X		set_order = TRUE;
X		return;
X	}
X#endif
X
X	if(!strncmp(opts,"time",4)) {
X		flags.time = !negated;
X		flags.botl = 1;
X		return;
X	}
X
X	if(!strncmp(opts,"restonspace",4)) {
X		flags.no_rest_on_space = negated;
X		return;
X	}
X
X#ifndef DGK
X	if(!strncmp(opts,"fixinv",4)) {
X		if(from_env)
X			flags.invlet_constant = !negated;
X		else
X			pline("The fixinvlet option must be in HACKOPTIONS.");
X		return;
X	}
X#endif
X
X	if(!strncmp(opts,"male",4)) {
X#ifdef KAA
X		if(!from_env && flags.female != negated)
X			pline("That is not anatomically possible.");
X		else
X#endif
X			flags.female = negated;
X		return;
X	}
X	if(!strncmp(opts,"female",6)) {
X#ifdef KAA
X		if(!from_env && flags.female == negated)
X			pline("That is not anatomically possible.");
X		else
X#endif
X			flags.female = !negated;
X		return;
X	}
X
X	/* name:string */
X	if(!strncmp(opts,"name",4)) {
X		extern char plname[PL_NSIZ];
X		if(!from_env) {
X#ifdef DGK
X		  pline("'name' only settable from %s.", configfile);
X#else
X		  pline("The playername can be set only from HACKOPTIONS.");
X#endif
X		  return;
X		}
X		op = index(opts,':');
X		if(!op) goto bad;
X		(void) strncpy(plname, op+1, sizeof(plname)-1);
X		return;
X	}
X
X	/* endgame:5t[op] 5a[round] o[wn] */
X	if(!strncmp(opts,"endgame",3)) {
X		op = index(opts,':');
X		if(!op) goto bad;
X		op++;
X		while(*op) {
X			num = 1;
X			if(digit(*op)) {
X				num = atoi(op);
X				while(digit(*op)) op++;
X			} else
X			if(*op == '!') {
X				negated = !negated;
X				op++;
X			}
X			switch(*op) {
X			case 't':
X				flags.end_top = num;
X				break;
X			case 'a':
X				flags.end_around = num;
X				break;
X			case 'o':
X				flags.end_own = !negated;
X				break;
X			default:
X				goto bad;
X			}
X			while(letter(*++op)) ;
X			if(*op == '/') op++;
X		}
X		return;
X	}
Xbad:
X	if(!from_env) {
X		if(!strncmp(opts, "help", 4)) {
X			pline("%s%s%s",
X#ifdef DGK
X
X"To set options use OPTIONS=<options> in ", configfile,
X" or give the command \"O\" followed by the line <options> while playing.  ",
X"Here <options> is a list of options separated by commas." );
X			pline("%s%s",
X"Boolean options are confirm, pickup, rawio, silent, sortpack, time, IBMBIOS,",
X" and DECRainbow.  These can be negated by prefixing them with '!' or \"no\"." );
X			pline("%s%s%s",
X"The compound options are name, as in OPTIONS=name:Merlin-W,",
X#ifdef SORTING
X" packorder, which lists the order that items should appear in your pack",
X#ifdef SPELLS
X" (the default is:  packorder:\")[%?+/=!(*0  ), and endgame." );
X#else
X" (the default is:  packorder:\")[%?/=!(*0  ), and endgame." );
X#endif /* SPELLS /**/
X#else
X"and engame.", "");
X#endif /* SORTING /**/ 	
X			pline("%s%s%s",
X"Endgame is followed by a description of which parts of the scorelist ",
X"you wish to see.  You might for example say: ",
X"\"endgame:own scores/5 top scores/4 around my score\"." );
X
X#else
X
X"To set options use `HACKOPTIONS=\"<options>\"' in your environment, or ",
X"give the command 'O' followed by the line `<options>' while playing. ",
X"Here <options> is a list of <option>s separated by commas." );
X			pline("%s%s%s",
X"Simple (boolean) options are rest_on_space, news, time, ",
X"null, tombstone, (fe)male. ",
X"These can be negated by prefixing them with '!' or \"no\"." );
X			pline("%s%s%s",
X"The compound options are name, as in OPTIONS=name:Merlin-W,",
X#ifdef SORTING
X" packorder, which lists the order that items should appear in your pack",
X#ifdef SPELLS
X" (the default is:  packorder:\")[%?+/=!(*0  ), and endgame." );
X#else
X" (the default is:  packorder:\")[%?/=!(*0  ), and endgame." );
X#endif /* SPELLS /**/
X#else
X"and engame.", "");
X#endif /* SORTING /**/ 	
X			pline("%s%s%s",
X"Endgame is followed by a description of what parts of the scorelist",
X"you want to see. You might for example say: ",
X"`endgame:own scores/5 top scores/4 around my score'." );
X
X#endif /* DGK /**/
X			return;
X		}
X		pline("Bad option: %s.", opts);
X		pline("Type `o help<cr>' for help.");
X		return;
X	}
X#ifdef DGK
X	printf("Bad syntax in OPTIONS in %s.", configfile);
X#else
X	puts("Bad syntax in HACKOPTIONS.");
X	puts("Use for example:");
X	puts(
X"HACKOPTIONS=\"!restonspace,notombstone,endgame:own/5 topscorers/4 around me\""
X	);
X#endif
X	getret();
X}
X
Xdoset()
X{
X	char buf[BUFSZ];
X#ifdef SORTING
X	extern char inv_order[];
X#endif
X
X	pline("What options do you want to set? ");
X	getlin(buf);
X	if(!buf[0] || buf[0] == '\033') {
X#ifdef DGK
X	    (void) strcpy(buf,"OPTIONS=");
X#else
X	    (void) strcpy(buf,"HACKOPTIONS=");
X	    (void) strcat(buf, flags.female ? "female," : "male,");
X	    if(flags.standout) (void) strcat(buf,"standout,");
X	    if(flags.nonull) (void) strcat(buf,"nonull,");
X	    if(flags.nonews) (void) strcat(buf,"nonews,");
X	    if(flags.notombstone) (void) strcat(buf,"notombstone,");
X	    if(flags.no_rest_on_space)	(void) strcat(buf,"!rest_on_space,");
X#endif
X#ifdef SORTING
X	    if (flags.sortpack) (void) strcat(buf,"sortpack,");
X	    if (set_order){
X		(void) strcat(buf, "packorder: ");
X		(void) strcat(buf, inv_order);
X		(void) strcat(buf, ",");
X	    }
X#endif
X#ifdef SAFE_ATTACK
X	    if (flags.confirm) (void) strcat(buf,"confirm,");
X#endif
X#ifdef DGKMOD
X	    if (flags.pickup) (void) strcat(buf,"pickup,");
X	    if (flags.silent) (void) strcat(buf,"silent,");
X#endif
X#ifdef DGK
X	    if (flags.rawio) (void) strcat(buf,"rawio,");
X	    if (flags.IBMBIOS) (void) strcat(buf,"IBMBIOS,");
X	    if (flags.DECRainbow) (void) strcat(buf,"DECRainbow,");
X#endif
X	    if(flags.time) (void) strcat(buf,"time,");
X	    if(flags.end_top != 5 || flags.end_around != 4 || flags.end_own){
X		(void) sprintf(eos(buf), "endgame: %u topscores/%u around me",
X			flags.end_top, flags.end_around);
X		if(flags.end_own) (void) strcat(buf, "/own scores");
X	    } else {
X		register char *eop = eos(buf);
X		if(*--eop == ',') *eop = 0;
X	    }
X	    pline(buf);
X	} else
X	    parseoptions(buf, FALSE);
X
X	return(0);
X}
X
X#ifdef DGKMOD
Xdotogglepickup() {
X	flags.pickup = !flags.pickup;
X	pline("Pickup: %s.", flags.pickup ? "ON" : "OFF");
X	return (0);
X}
X#endif
END_OF_options.c
if test 8991 -ne `wc -c <options.c`; then
    echo shar: \"options.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 4 \(of 16\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 16 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0