[comp.sources.games] v03i036: crystal - another adventure game, Part04/05

games-request@tekred.TEK.COM (01/13/88)

Submitted by: nrcvax!kosman!kevin
Comp.sources.games: Volume 3, Issue 36
Archive-name: crystal/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 5)."
# Contents:  MAKEflop cvatt.c cvdie.c cvdwrf.c cvgo.c cvmove.c cvocab.c
#   cvsave.c
# Wrapped by billr@tekred on Tue Jan 12 10:11:35 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f MAKEflop -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"MAKEflop\"
else
echo shar: Extracting \"MAKEflop\" \(122 characters\)
sed "s/^X//" >MAKEflop <<'END_OF_MAKEflop'
Xecho "you must be root for this one ... crystal is 111 owned by bin ..\c"
Xread xyzzy
Xcat Files | cpio -ocBv > /dev/rfp021
END_OF_MAKEflop
if test 122 -ne `wc -c <MAKEflop`; then
    echo shar: \"MAKEflop\" unpacked with wrong size!
fi
chmod +x MAKEflop
# end of overwriting check
fi
if test -f cvatt.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cvatt.c\"
else
echo shar: Extracting \"cvatt.c\" \(9165 characters\)
sed "s/^X//" >cvatt.c <<'END_OF_cvatt.c'
X/* cvatt.c
X *	attacks, droping things, feeding and other such stuff
X ************************************************************************/
X
X#include	<stdio.h>
X#include	"cvobj.h"
X#include	"cvocab.h"
X#include	"cvlocs.h"
X#include	"cvmisc.h"
X#include	"cvorcs.h"
X#include	"cvcode.h"
X#include	"random.h"
X
Xextern int actspk[]; /* cvocab.c */
Xextern char *oword;
Xextern void cvsave();
Xextern void putcode();
Xextern int mutilate();
Xextern void newcon();
Xextern int drunkbear();
Xextern int wakeking();
X
X#define	OKAY(msg)	{rspeak(msg); return S_okay;}
X#define	DEFMSG	OKAY(actspk[verb%1000])
X#define	BREAKIT	{register int i; if (i = mutilate(object)) {\
X					newloc = &(cvloc[i]); return S_move;\
X				} else return S_okay; }
X#define	FILLIT(object,liquid)	{(object)->prop = (liquid) - _WATER + 1;}
X#define	INTRANS
X#define	TRANS	10000 + 
X
Xstatic int
Xdropit(verb,object) register struct cvobj *object;
X{
X	if ((object == ROPE)
X		&& TOTING(ROPE2)
X		&& !TOTING(ROPE)) object = ROPE2;
X
X	if (TOTING(BOTTLE) && (OBJ(LIQ(BOTTLE))==object)) object = BOTTLE;
X	
X	if (TOTING(CUP) && (OBJ(LIQ(CUP))==object)) object = CUP;
X
X	if (!TOTING(object)) DEFMSG;
X
X	if ((object == WALLET) && (HERE(VEND)) && (VEND->prop == 0))
X	{	if (object->prop == 4)
X		{	pspeak(object,4);
X			rspeak(54);
X		} else {
X			object->prop++;
X			VEND->prop = 1;
X			move(BOTTLE,loc);
X			pspeak(BOTTLE,BOTTLE->prop);
X			return S_okay;
X		}
X	} else if (object == RUG)
X	{	register int k;
X		k = RUG->prop;
X		RUG->prop = 0;
X		if (k) {
X			if ((loc - cvloc) > 30)
X			{	if (drownch()) {
X					return S_move;
X				} else {
X					rspeak(54);
X				}
X			} else {
X				destry(RUG);
X				pspeak(RUG,2);
X				return S_okay;
X			}
X		} else {
X			rspeak(54);
X		}
X	} else if (object == BOAT)
X	{	object->prop -= 2;
X		if (loc->flags & DROWN)
X		{	rspeak(120);
X			oldlc2 = loc;
X			die();
X			return S_move;
X		}
X		rspeak(54);
X	} else if ((object == SEARS)
X			&& (((loc - cvloc) == SEARS->iloc)
X				|| ((loc - cvloc) == 78) ) )
X	{	object->prop = 1;
X		move2(SEARS,&(cvloc[78 + (SEARS->iloc) - (loc - cvloc)]));
X		pspeak(object,1);
X	} else if (object == FOOD && HERE(DRAGON)) {
X		rspeak(166);	/* tell him the dragon doesn't eat that */
X	} else {
X		rspeak(54);		/* okay */
X	}
X
X	move(object,loc);
X	if (HERE(ORCS) && ORCS->prop)
X	{	if (((object == CUP) || (object == BOTTLE))
X				&& (LIQ(object) == _COLA))
X		{	didorc();
X			return S_okay;
X		}
X		pspeak(ORCS,2); /* the orcs don't like that */
X	}
X
X	if ((object == CHEST) && (SKELTN->prop == 1))
X	{	SKELTN->prop = 2;
X		rspeak(97); /* skeleton crumples */
X	}
X
X	return S_okay;
X}
X
Xint
Xcvatt(verb,obj,object) register int verb,obj;
Xregister struct cvobj *object;
X{	register int k;
X
X	switch ((!!obj*10000) + verb) {
X
X	case TRANS DROP:
X		return dropit(verb,object);
X
X	case TRANS THROW:
X/* throw is like pour for liquids.  For axe, something might get killed.
X   Otherwise, it is the same as "drop".
X	The axe is the only way to deal with some things, and is special for
X	the bugbear (as is the keg, food, keys.)
X	Sand is special for the Balrog.
X	Spice is special for the dragon.
X*/
X		if ((object == WATER) || (object == WINE) ||(object == COLA))
X		{	goto L9130;
X		}
X
X		if ((object == ROPE) && TOTING(ROPE2) && !TOTING(object)) {
X			object = ROPE2;
X		}
X
X		if (!TOTING(object)) DEFMSG;
X
X		if (BEAR->prop && HERE(BEAR)) {
X			if ((object == KEY) && (CHAIN->prop == 2)) {
X				move(KEY,loc);
X				CHAIN->prop = 0;
X				destr2(CHAIN);
X				rspeak(151); /* the bugbear is no slouch */
X				BEAR->prop -= 2;
X				YOGI->dseen = TRUE;
X				YOGI->dloc = loc;
X				return S_show;
X			}
X			if ((object == KEG)
X				|| (((object == CUP) || (object == BOTTLE))
X						&& (LIQ(object) == _WINE))) {
X				return drunkbear(object);
X			}
X		}
X
X		if ((object == HAMMER) && HERE(SKELTN) && (SKELTN->prop == 1)) {
X			HAMMER->prop = SKELTN->prop = 0;
X			pspeak(HAMMER,2);
X			move(HAMMER,loc);
X			/* let's not be annoyed with curses or odd things about
X				"take" when pirate is really inactive */
X			PIRATE->dloc = PIRATE->oloc = DEAD;
X			PIRATE->dseen = FALSE;
X			newloc = loc;
X			return S_move;
X		}
X
X		if ((object == SPICE) && HERE(DRAGON)) {
X			destry(SPICE);
X			destry(DRAGON);
X			DRAGON->prop = 0;
X			
X			PUFF->dseen = TRUE; /* now for the really annoying dragon */
X			PUFF->dloc = loc;
X			OKAY(148); /* the bad news */
X		}
X
X		if ((object == SAND) && (BALLY->dloc = loc)) {
X			pspeak(SAND,1);
X			destry(SAND);
X			pspeak(BALROG,1);
X			BALROG->prop = 0;
X			move(BALROG,&(cvloc[62]));
X			BALLY->dseen = FALSE;
X			BALLY->dloc = DEAD;
X			return S_okay;
X		}
X
X		if (object == FOOD) {
X			goto L8210;		/* treat as FEED */
X		}
X
X		/* non-weapons just get dropped here and that's it */
X		if ((object != AXE) /* note: AXE is not among weapons */
X			&& ((object <= MINWPN) || (object >= MAXWPN))) {
X			return dropit(verb,object);
X		}
X
X		move(object,loc); /* weapons also end up here */
X/* he may kill any dwarf, the kobold, or sometimes even the giant */
X/* but with multiple targets, we hit the easy ones first */
X		if (SLASHER->dloc == loc) {
X			KOBOLD->prop = 3;
X			move(KOBOLD,loc);
X			KOBOLD->conn2.where = FIXED;
X			SLASHER->dseen = FALSE;
X			SLASHER->dloc = DEAD;
X			rspeak(150);
X			newloc = loc;
X			return S_move;
X		}
X
X		{	register struct monster *cre;
X			for (cre = MINDWR; cre <= MAXDWR; cre++) {
X				if (cre->dloc == loc) {
X					if (PCT(67) && (saved == -1)) {
X						cre->dseen = FALSE;
X						cre->dloc = DEAD;
X						dflag++; /* annoy them some more */
X						rspeak(++dkill == 1 ? 149 : 47);
X					} else {
X						rspeak(48);
X					}
X					newloc = loc;
X					return S_move;
X				}
X			}
X		}
X
X		if (HERE(GIANT) && GIANT->prop) {
X			pspeak(GIANT,3);
X			oldlc2 = loc;
X			die();
X			return S_show;
X		}
X
X		if (HERE(BEAR) && BEAR->prop) {
X			move2(AXE,FIXED);
X			AXE->prop = 1;
X			if (HERE(CHAIN) && !TOTING(CHAIN)) juggle(CHAIN);
X			juggle(BEAR);
X			OKAY(164);
X		}
X
X		if (SKELTN->prop == 1) {
X			rspeak(141);
X			newloc = loc;
X			return S_show;
X		}
X
X		if (ME->dloc == loc) return suicide();
X
X		{	register struct monster *cre;
X			for (cre = orcs; cre->iloc >= 0; ++cre) {
X				if (cre->dloc == loc) {
X					rspeak(141);
X					newloc = loc;
X					return S_show;
X				}
X			}
X		}
X
X		carry(object); /* well, pick it up again */
X		return dropit(verb,object); /* and just drop the damned thing */
X
X	case INTRANS FEED:
XL8210:	obj = 0;
X		if (HERE(BEAR)
X			&& (BEAR->prop == 2 || BEAR->prop == 4)) obj = _BEAR;
X		if (dflag >= 2) {
X			register struct monster *cre;
X			if (HERE(UNICRN)
X				&& (UNICRN->prop)
X				&& (!obj || PCT(75))) obj = _UNICRN;
X			for (cre = MINDWR; cre <= MAXDWR; ++cre) {
X				if ((cre->dloc == loc) && ( !obj || PCT(50))) obj = _DWARF;
X			}
X		}
X		if (!obj) { /* nobody here to feed */
X			if (verb != THROW) return S_what; /* normally, just complain */
X			obj = _FOOD;		/* but if he said "throw food" */
X			object = OBJ(obj);	/* we instead . . . */
X			return dropit(verb,object);	/* just drop it */
X		}
X		object = OBJ(obj);
X	case TRANS FEED:
X		if (!HERE(FOOD)) DEFMSG;
X		if (object == DWARF) {
X			dflag += 8; /* get them mad */
X			OKAY(103);
X		}
X		if (object == UNICRN && UNICRN->prop) return unicorn();
X		if (object == BEAR
X			&& (BEAR->prop == 2 || BEAR->prop == 4)) {
X			pspeak(BEAR, --(BEAR->prop));
X			destry(FOOD);
X			return S_okay;
X		}
X		OKAY(14);
X
X	case INTRANS POUR:
X		obj = 0;
X		if (TOTING(BOTTLE) && LIQ(BOTTLE)) obj = LIQ(BOTTLE);
X		if (TOTING(CUP) && LIQ(CUP)) obj = (obj << 10) + LIQ(CUP);
X		if (!obj || (obj > 2000)) return S_what;
X		object = OBJ(obj);
X	case TRANS POUR:
XL9130:	k = 0;		/* from THROW (indirectly from FEED, too) */
X		if (TOTING(BOTTLE) && LIQ(BOTTLE) == obj) k = _BOTTLE;
X		if (TOTING(CUP) && LIQ(CUP) == obj) k = (k << 10) + _CUP;
X		if (k > 2000) OKAY(143);  /* from what? */
X		if (k) object = OBJ(obj=k);
X		if (!TOTING(object)) DEFMSG;
X		if (object != CUP && object != BOTTLE) OKAY(78); /* cannot */
X		k = LIQ(object);
X		if (!k) {
X			pspeak(object,11); /* but it's empty */
X			return S_okay;
X		}
X		if (verb == THROW) {
X			if (k == _WINE && HERE(BEAR) && BEAR->prop) {
X				return drunkbear(object);
X			} else {
X				rspeak(k == _WATER ? 77 : 79);
X			}
X		} else {
X			obj = object - cvobj;
X			obj = _CUP + _BOTTLE - obj;
X			if (OBJ(obj)->prop == 0 && HERE(OBJ(obj))) {
X				OBJ(obj)->prop = object->prop;
X				pspeak(OBJ(obj),object->prop + 7);
X			} else {
X				rspeak(k == _WATER ? 77 : 79);
X			}
X		}
X		object->prop = 0;
X		newcon(object,7,k);
X		return S_show;
X
X	case INTRANS FILL:
X		obj = 0;
X		if (TOTING(CUP)) {
X			if (TOTING(BOTTLE)) {
X				if (!(BOTTLE->prop) && !(CUP->prop)) {
X					return S_what; /* can't tell which one */
X				} else {
X					obj = CUP->prop ? _BOTTLE : _CUP;
X				}
X			} else obj = _CUP;
X		} else if (TOTING(BOTTLE)) obj = _BOTTLE;
X		if (!obj) return S_what;
X		object = OBJ(obj);
X	case TRANS FILL:
X		if (object != BOTTLE && object != CUP) DEFMSG;
X		if (!TOTING(object)) OKAY(29);
X		if (object->prop) {pspeak(object,12); return S_show; }
X		if (!(k = LIQLOC(loc))) {
X			obj = _CUP + _BOTTLE - obj;
X			if (HERE(OBJ(obj))) k = LIQ(OBJ(obj));
X			if (!k) OKAY(106);
X			pspeak(OBJ(obj),7); /* announce source is now empty */
X			OBJ(obj)->prop = 0;
X		}
X		newcon(object,(object->prop=k-_WATER+1)+7, k); /* announce result */
X		return S_show;
X
X	default:
X		fputs("Unknown verb in cvatt.\n",stdout);
X		return S_okay;
X	}
X}
X
END_OF_cvatt.c
if test 9165 -ne `wc -c <cvatt.c`; then
    echo shar: \"cvatt.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cvdie.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cvdie.c\"
else
echo shar: Extracting \"cvdie.c\" \(2825 characters\)
sed "s/^X//" >cvdie.c <<'END_OF_cvdie.c'
X/* cvdie.c
X ************************************************************************/
X
X#include <stdio.h>
X#include	<string.h>
X#include	"cvobj.h"
X#include	"cvorcs.h"
X#include	"cvocab.h"
X#include	"cvlocs.h"
X#include	"cvmisc.h"
X
X/* "You're dead, Jim."  You got yourself killed somehow, clown.  The
X * easiest way is to go to location DEAD, which is the destination of
X * some entries in travel structures.  We allow this 'maxdie' times,
X * where maxdie is automatically initialized based on the number of
X * snide messages we have available (and how much orange smoke...) in
X * messages around rmsg[81].  Each death results in a message (81,83,...)
X * which offers reincarnation; if accepted, this results in message 82, 84,
X * etc.  The last time, if he wants another chance, he gets a snide
X * remark (what else? so what's new?) as we exit.  When reincarnated,
X * all objects being carried get moved to 'oldlc2' (presumably the last
X * place prior to getting killed) without change of prop number.  The lamp
X * is turned off and left outside the building (only if he was carrying
X * it, of course).  He himself is left outside the privy (and heaven help
X * him if he tries to "hope" back into the cave without the lamp!).
X *
X * 'oldlc2' is zapped so he can't just "retreat".
X */
X
Xvoid
Xdie()
X{
X	register int yea;
X	register struct cvobj *curobj ;
X
X	blklin = TRUE ;
X	if ( (UNICRN->conn1.where == oldlc2)
X		&& (loc == oldlc2)
X		&& (UNICRN->prop) ) {
X		pspeak(UNICRN,5); /* very lucky! */
X		UNICRN->prop = 1 ;
X		loc = oldlc2;
X	} else {
X		if (closing || demo) {
X			rspeak(131);
X			++numdie;
X			finish = TRUE;
X			return ;
X		}
X		yea = yes(81+numdie*2,82+numdie*2,54) ;
X		++numdie;
X		if ((numdie == maxdie) || !yea) {finish = TRUE; return; }
X		if (TOTING(LAMP)) {
X			move(LAMP,LAMPLOC);
X			LAMP->prop = 0 ;
X		}
X		loc = LAMPLOC;
X		move(COMPASS,LAMPLOC);
X			/* the following may be confusing. GIANT and PRIEST
X			 * represent the same thing to the adventurer, but
X			 * here they are represented by an 'object' and a
X			 * 'monster'.
X			 */
X		if ((GIANT->prop == 1) && PRIEST->dseen) destry(GIANT);
X	} /* may or may not be dead; objects still get dropped */
X	/* drop all objects (still) being carried.
X		Throw away if over water. */
X	newloc = (oldlc2->flags & DROWN) ? LOST : oldlc2 ;
X	for (curobj = cvobj; curobj->desc != NULL; ++curobj)
X		if (TOTING(curobj)) move(curobj,newloc); /* drop them */
X	if (RUG->prop == 1) RUG->prop = 0 ; /* get off the rug */
X	if ((BOAT->prop/2) == 1) BOAT->prop -= 2; /* leave the boat */
X	if ( ( LNUM(SCROLL->conn1.where) == 91)
X		|| INMAZE(SCROLL->conn1.where))
X		move(SCROLL,&(cvloc[SCROLL->iloc]));
X	if ( (LNUM(MEDAL->conn1.where) == CAPE->iloc)
X		|| (LNUM(MEDAL->conn1.where) == SPICE->iloc) )
X		move(MEDAL,&(cvloc[MEDAL->iloc]));
X	if (SKELTN->prop == 1) SKELTN->prop = 2;
X	newloc = oldloc = loc ;
X}
END_OF_cvdie.c
if test 2825 -ne `wc -c <cvdie.c`; then
    echo shar: \"cvdie.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cvdwrf.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cvdwrf.c\"
else
echo shar: Extracting \"cvdwrf.c\" \(11495 characters\)
sed "s/^X//" >cvdwrf.c <<'END_OF_cvdwrf.c'
X/*	cvdwrf.c
X *		performs dwarf-motion stuff once per turn.  Considers all moving
X *		creatures except the adventurer to be "dwarves" in some sense,
X *		because their motion rules are all very similar.
X *		As long as they are not dead, all dwarves move about randomly in
X *		much the same way that adventurers do, but the dwarves are smart
X *		enough to skip the usual hazards -- they never go to fatal
X *		places.
X *************************************************************************/
X
X#include	<stdio.h>
X#include	<string.h>
X
X#include	"cvobj.h"
X#include	"cvlocs.h"
X#include	"cvocab.h"
X#include	"cvorcs.h"
X#include	"cvmisc.h"
X#include	"random.h"
X
Xextern struct rtr rtrav[];	/* rug and rope travel array */
Xextern int maxloc;			/* test for legal locs */
X
Xextern void carry();		/* pick up object */
Xextern void destry();		/* destroy an object (at first location) */
Xextern void mkill();		/* kill monster */
Xextern void move();			/* place an object at a location */
Xextern void move2();		/* place an object at a second location,
X								or make it unmoveable */
Xextern void pspeak();		/* announce a property message of an object */
Xextern void rspeak();		/* utter one of the random messages */
Xextern void putcode();		/* used in debugging */
X
Xextern int tally, tally2;	/* counts of objects seen */
X
Xint
Xdodwarf()
X{	register struct cvobj *curobj;
X	register struct cvtrav *curtrv;
X	register struct monster *cre;
X	register int i;
X
X	if (closing && ( (newloc - cvloc) < 31 || newloc == DEAD) ) {
X		rspeak(130);	/* you can't get out */
X		newloc = loc;	/* make him stay put */
X		if (!panic) clock2 = 15;	/* if this is his first attempt */
X		panic = TRUE;	/* remember he has paniced already */
X	}
X
X/* If monsters are following, the adventurer is not allowed to back up,
X * because there's a monster in the way.
X */
X
X	if (loc != newloc				/* he's moving */
X			&& (loc - cvloc) >=62	/* he's moving inside the cave */
X			&& dflag >= 2			/* dwarf stuff going */
X			&& !FORCED(loc) ) {		/* he could be coming from there */
X		for (cre = MINDWR; cre->dw; ++cre) {
X			if ( cre->dseen
X					&& (newloc == cre->oloc || newloc == oldloc) ) {
X				newloc = loc;		/* prevent him */
X				rspeak(2);			/* tell him why */
X				break;				/* skip checking other dwarves */
X			} /* end if dseen */
X		} /* end dwarf check */
X	} /* end of backup loop */
X
X	loc = newloc;	/* assign the possibly new place */
X
X/*  If he gets as far as the pool hall, start up the dwarf stuff.  Things
X *	then stay quiet for a random amount of time.  At some point a (fake)
X *	dwarf spots him, and misses him with an axe.  This encounter just
X *	scares him, and provides the axe he will need, but never does any harm.
X *	At this point, the dwarves all start moving from their (hard-wired)
X *	starting points.
X *
X *	Some dwarves (those awakened by a special encounter: the King, the
X *	dragon, the bugbear), plus all those below the throne start later at
X *	the time they are called for.
X *
X *	No dwarf starts where the axe is thrown, because a dwarf who might
X *	otherwise start there is assigned an alternate starting point.
X *
X */
X	if (loc != DEAD
X			&& (loc - cvloc) >= 62
X			&& !FORCED(loc) )
X		switch (dflag) {
X		auto int dtotal, attack, stick, destj;
X#define	MAXDEST	20
X		auto struct cvloc *ddest[MAXDEST];
X
X	case 0:	dflag = 1; break;	/* allow things to start */
X	case 1: if ( !HERE(IDOL)		/* could start orcs? */
X				&& !HERE(CHAIN)	/* could start bugbear? */
X				&& !HERE(ORB)	/* could start Grendl? */
X				&& !HERE(CROWN)	/* could start king? */
X				&& !HERE(SCEPT)	/* could start dragon? */
X				&& (PCT(85) || DARK) )
X			break;	/* Don't start in the dark unless he's sneaking
X					up on one of the vital encounters */
X		dflag = 2;	/* Go into full swing now */
X		for ( i = 0; i < 3; ++i ) {
X			cre = MINDWR + RAN(MAXDWR-MINDWR+1);	/* pick a real dwarf */
X			if (PCT(50) && saved == -1)
X				cre->dloc = DEAD;	/* may kill it off */
X		} /* end of dwarf-killing loop */
X
X		for (cre = MINDWR; cre->dw; ++cre) {
X			if (loc == cre->dloc)
X				cre->dloc = DALTLC;	/* start no real dwarf here */
X			cre->oloc = cre->dloc;
X		}
X
X		rspeak(3);	/* Throw the axe */
X		move(AXE,loc);
X		break;
X
X	default:
X/*	Things are in full swing now.  Move each dwarf at random, except that
X *	if he's seen the adventurer, he follows.  Dwarves never go to locations
X *	outside the cave.  If wandering at random, they don't back up unless
X *	that's the only way to go.  If they don't have to move, they attack.
X *	Of course, dead dwarves don't do much of anything.
X */
X		dtotal = attack = stick = 0;
X		if ( PIRATE->dloc != DEAD		/* Is Pirate still alive? */
X				&& loc != CHLOC			/* But we're not at chest loc */
X				&& CHEST->prop < 0		/* And never saw chest */
X				&& tally == tally2+1)	/* And that's the last one */
X			PIRATE->dseen = TRUE;		/* Give adventurer a hand */
X		for (cre = orcs; cre->iloc >= 0; ++cre) {
X			if (cre->dloc == DEAD || cre->dloc == cvloc) continue; /*dead*/
X			destj = 0;
X			ddest[destj] = cre->oloc;	/* pad the list (could back up) */
X			for (curtrv = cre->dloc->travel; curtrv->word != -1; ++curtrv){
X				if (curtrv->s) {
X					for ( ;curtrv->s; curtrv++) ;	/* skip sequence */
X					continue;	/* then go try the next entry */
X				}
X				i = curtrv->l;
X				if ( i >= 62			/* in the cave */
X					&& i <= maxloc		/* not message or magic */
X					&& ((newloc = &(cvloc[i])) != cre->oloc || cre->dseen)
X						/* don't back up when wandering */
X					&& ( ! destj || newloc != ddest[destj - 1] )
X					&& destj < MAXDEST	/* room in array */
X					&& newloc != cre->dloc
X					&& !FORCED(&(cvloc[i]))	/* don't enter danger */
X					&& ( cre != PIRATE || !BADPLC(newloc)) ) {
X					ddest[destj++] = newloc;	/* enter possible move */
X				}
X			} /* end of testing travel array */
X			i = destj;			/* remember how many */
X			if (destj) destj = RAN(destj); else i++; /* make a selection */
X			cre->oloc = cre->dloc;
X			cre->dloc = ddest[destj];
X
X			if (loc == cre->oloc) {
X				cre->dloc = loc;	/* pass in the hall */
X				destj = 0;			/* flag that he's following */
X			} else {
X				for (destj = 0; destj < i; ++destj) {
X					if (ddest[destj] == loc) {
X						destj = 0;	/* flag that he could follow */
X						break;
X					}
X				}
X			}
X#ifdef	DEBUG
X			if (cre == BALLY) {
X				printf("\nBALLY to loc %d: ",cre->dloc - cvloc);
X				putcode(cre->dloc->ldesc);
X				putchar('\n');
X			}
X#endif
X			if ( loc == cre->dloc	/* it's here, or */
X				|| (cre->dseen 		/* it's following, and */
X				&& ((destj < i)		/* it could follow (priest special ) */
X					|| ( cre == PRIEST && LNUM(loc) == 134 ) ) ) ) {
X				cre->dloc = loc;
X				cre->dseen = TRUE;
X				switch (cre - orcs) {
X				case IPIRAT:
X#ifdef	DEBUG
X					puts("\nThe pirate is here.");
X#endif
X					if (loc == CHLOC || FOUND(CHEST)) break;
X					for (i = 0, curobj = MINTRS;
X						curobj != ENDTRS; ++curobj) {
X						if (TOTING(curobj)) break;
X						if (HERE(curobj)) i=1;
X					}
X					if (curobj == ENDTRS) {
X					/* nothing to steal, but we'll hear from him anyway */
X						if (tally == (tally2 + 1)
X							&& i == 0
X							&& CHEST->conn1.where == LOST
X							&& HERE(LAMP)
X							&& LAMP->prop == 0 ) {
X							rspeak(186);
X							move(CHEST,CHLOC);
X						} else {
X							if (cre->oloc != cre->dloc
X								&& PCT(20))
X								rspeak(127);
X							break;
X						}
X					} else { /* he's gonna get something */
X						rspeak(128);
X						if (CHEST->conn1.where == LOST)
X							move(CHEST,CHLOC);
X						for (curobj = MINTRS; curobj != ENDTRS; ++curobj) {
X							if (HERE(curobj)) {
X								if (curobj == ORB && INMAZE(loc)) {
X									if (LNUM(loc) != 92
X										&& curobj->conn2.where == LOST)
X										move(curobj,&(cvloc[92]));
X								} else {
X									if (curobj->conn2.where == LOST)
X										move(curobj,CHLOC);
X								}
X							} /* end handling toted treasure */
X						} /* end of stealing loop */
X						PIRATE->dloc = PIRATE->oloc = CHLOC;
X						PIRATE->dseen = FALSE;
X					} /* end of any-treasure-here case */
X					/* end of the pirate's wickedness (for now) */
X					break; /* switch break */
X
X				case IGRENDL:
X					pspeak(SPIDER,1);	/* he's after you */
X					if (PCT(50)) break;	/* half the time he does no more */
X					if (TOTING(SWORD)) {
X						rspeak(137);	/* sorry about that, Grendl */
X						mkill(&(orcs[IGRENDL]),SPIDER);
X					} else {
X						rspeak(135);
X						oldlc2 = loc;
X						goto dead;
X					}
X					break;
X
X				case IDRAGON:
X					pspeak(DRAGON,2+RAN(8)); /* just keep bitchin' */
X					break;
X
X				case IKING:
X					pspeak(HELM,1);		/* he's after you! */
X					if (cre->dloc == PUFF->dloc) {
X						pspeak(HELM,3);	/* can't stand complaints */
X						mkill(PUFF,DRAGON);
X					} else {
X						if (( loc == oldloc || loc == oldlc2) && PCT(40)) {
X							pspeak(HELM,5);	/* sorry 'bout that */
X							oldlc2 = loc;
X							goto dead;
X						}
X					}
X					break;
X
X				case IDJINN:
X					pspeak(DJINN,0);	/* he's here */
X					break;
X
X				case IKOBOLD:
X					pspeak(KOBOLD,0);	/* he's here */
X					if (( loc == oldloc || loc == oldlc2) && PCT(25)) {
X						pspeak(KOBOLD,2);
X						oldlc2 = loc;
X						goto dead;
X					} else {
X						pspeak(KOBOLD,1);
X					}
X					break;
X
X				case IBEAR:
X					move(BEAR,loc);
X					if (( loc == oldloc || loc == oldlc2) && PCT(25)) {
X						rspeak(196);
X						oldlc2 = loc;
X						goto dead;
X					}
X					break;
X
X				case IUNICRN:
X					move(UNICRN,loc);
X					break;
X
X				case IPRIEST:
X					move(GIANT,loc);
X					if (( loc == oldloc || loc == oldlc2) && PCT(50)) {
X						rspeak(223);
X						oldlc2 = loc;
X						goto dead;
X					} else {
X						if (LNUM(loc) == 134) {
X							pspeak(GIANT,4);	/* bye, bye priest */
X							mkill(PRIEST,GIANT);
X						}
X					}
X					break;
X
X				case IBALROG:
X					pspeak(BALROG,2);
X					if (PCT(50)) {
X						pspeak(BALROG,3);
X						if (( loc == oldloc || loc == oldlc2 )==PCT(85)
X							&& RAN(limit+2) >= 10 ) {
X							pspeak(BALROG,4);
X							limit = (limit+9)/10;
X						}
X					}
X					break;
X
X				case ISELF:
X					pspeak(SELF,0);
X					if (PCT(17)) pspeak(SELF,RAN(3)+2);
X					break;
X
X				default:	/* normal dwarves are the rest */
X					if (!cre->dw) break;	/* in case I goofed */
X					++dtotal;				/* count him in the room */
X					if (cre->dloc == cre->oloc) {	/* if he can */
X						++attack;
X						if (knfloc != FIXED) knfloc = loc;
X						if (PCT((dflag-2)*5)) ++stick;
X					}
X
X				} /* end of switch */
X			} /* end of processing for being followed */
X			  else {
X#ifdef	DEBUG
X				if (cre->dseen) {
X					printf("Creature %d cannot follow.\n", cre - orcs);
X				}
X#endif
X				cre->dseen = FALSE;
X				switch (cre - orcs) {
X				case IBEAR:
X					destry(BEAR);
X					if (AXE->prop == 1 && AXE->conn2.where == FIXED) {
X						AXE->prop = 0;
X						AXE->conn2.where = NULL;
X					}
X					break;
X
X				case IPRIEST:
X					destry(GIANT);
X					break;
X
X				case IUNICRN:
X					if (UNICRN->prop != -1) UNICRN->prop = 2;
X					destry(UNICRN);
X					break;
X				}
X			}
X		} /* end of creature scan */
X
X		if (dtotal) {
X			if (dtotal > 1) {
X				(void) printf(
X"\nThere are %d threatening little dwarves in the room with you.\n",dtotal);
X			} else rspeak(4);
X			if (attack) {
X				if (dflag == 2) ++dflag;	/* After the first time */
X				if (saved != -1) dflag = 20;/* Catch copyists */
X				blklin = FALSE;
X				if (attack > 1) {
X					(void) printf(
X"%d of them throw knives at you!\n",attack);
X					i = 6;
X				} else {
X					rspeak(5);
X					i = 52;
X				}
X				if (stick <= 1)
X					rspeak(i+stick);
X				else (void) printf(
X"%d of them get you!\n",stick);
X				if (stick) {
X					oldlc2 = loc;
X					goto dead;
X				}
X			}
X		}
X	} /* end of switch for dwarf state */
X	return (FALSE);
X
Xdead:	return(TRUE);
X}
END_OF_cvdwrf.c
if test 11495 -ne `wc -c <cvdwrf.c`; then
    echo shar: \"cvdwrf.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cvgo.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cvgo.c\"
else
echo shar: Extracting \"cvgo.c\" \(9558 characters\)
sed "s/^X//" >cvgo.c <<'END_OF_cvgo.c'
X/* cvgo.c
X *	adventurer motion routine moveme()
X *************************************************************************/
X
X#include	<stdio.h>
X#include	"cvobj.h"
X#include	"cvocab.h"
X#include	"cvlocs.h"
X#include	"cvmisc.h"
X#include	"cvorcs.h"
X#include	"random.h"
X
Xextern struct cvobj *lastobj; /* cvmain.c */
X
Xstatic void
Xwrongway(verb) int verb ;
X{	if ((verb == FIND) || (verb == INVENT)) {rspeak(59); return; }
X	if (verb <= ENTER) {rspeak(9); return; }
X	if ((verb == HOPE) 
X		|| (verb == BANIS)
X		|| (verb == MISFO)) {rspeak(42); return; }
X	rspeak(12);
X	return;
X}
X
Xstatic struct cvloc *
Xleave(tr) register struct cvtrav *tr;
X{
X	if (tr->l <= 300) return &(cvloc[tr->l]) ;
X	if (tr->l <= 500)
X		switch (tr->l)
X	{
X	case 301: /* wrong magic word ! */
X		newloc = loc;
X		switch (SHELF->prop) {
X		case 0:
Xshakeit:	if (loc - cvloc == SHELF->iloc || loc - cvloc == SHELF->iloc+1)
X				rspeak(214);
X			else
X				rspeak(162);
X			SHELF->prop ++ ;
X			return loc;
X		case 1:
X			if (PCT(25)) goto shakeit;
X			if (PCT(33)) {
X				rspeak(42);
X				return loc;
X			}
X			SHELF->prop++;
X			{	register struct cvobj *ob;
X				register struct cvloc *shloc;
X				shloc = &(cvloc[SHELF->iloc]);
X
X				/* dump everything off of shelf */
X				for (ob = lastobj; ob != cvobj; ob--) {
X					if (ob->conn1.where == shloc) move(ob,shloc+1);
X				}
X				move2(SHELF,shloc); /* shelf stays, though */
X				if (!AT(SHELF)) {
X					rspeak(162);
X					return loc;
X				}
X				loc = shloc + 1;
X				newloc = &(cvloc[25]);
X				rspeak(163);
X				return loc;
X			}
X		case 3: /* already destroyed */
X			rspeak(42);
X			return loc;
X		}
X	case 302: /* down a clean column */
X		loc = COLUMN->conn1.where;
X		if (COLUMN->prop == 0) {
X			COLUMN->prop = 1;
X			if (DAM->prop == 0) {
X				loc = &(cvloc[getrick()]);
X			}
X		}
X		return loc;
X	case 303: /* out of maze .. activate grendl if carrying orb */
X		newloc = loc - 1;
X		SPIDER->prop = 0;
X		pspeak(SPIDER,2);
X		GRENDL->dseen = TRUE;
X		GRENDL->dloc = newloc;
X		return newloc;
X	case 305: /* jumped into bottomless fissure */
X		rspeak(224);
X		{	register struct cvobj *ob;
X			register int co;
X			co = 0;
X			for (ob = cvobj; ob->desc != NULL; ob++) {
X				if (TOTING(ob)) {co++; destry(ob);}
X			}
X			if (RUG->prop == 1) RUG->prop = 0;
X			rspeak(co ? 134 : 133);
X		}
X		loc = newloc = oldlc2 = &(cvloc[62]);
X		return loc;
X	case 306: /* leave repository */
X		newloc = &(cvloc[146]);
X		if (MIRROR->prop == 1) {
X			MIRROR->prop = 0;
X			pspeak(MIRROR,2);
X			ME->dloc = loc;
X			ME->dseen = TRUE;
X		}
X		return loc;
X	default: bug(20);
X	}
X	rspeak((int)(tr->l - 500)) ;
X	return loc ;
X}
X
X#define	SKIP	{ctrav = skip(ctrav); continue; }
X#define DOIT	{ register struct cvloc *temp; temp = leave(ctrav) ;\
X				if (ctrav->s) continue ; else return temp; }
Xstatic struct cvtrav *
Xskip(tr) register struct cvtrav *tr;
X{	while (tr->s) {++tr;} ;
X	return tr ;
X}
X
X/* given the current location in parameter "where" and a verb in parameter
X *	"verb", put the new location into the result.  The current loc is saved
X *	in "oldloc" in case he wants to retreat.  The current "oldloc" is saved
X *	in "oldlc2", in case he dies.  (If he does, "newloc" will be limbo, and
X *	"oldloc" will be what killed him, so we need "oldlc2", which is the
X *	last place he was safe.)
X *
X *	Each location (struct cvloc) has a travel array (struct cvtrav *travel)
X *	of entries, each of which contains a word-number (or -1 to end the
X *  array for this location) and maybe some other stuff.  If the location
X *	and continue parts are both zero, subsequent entries are examined until
X *	a useable one is found (this makes several motion words synonyms in the
X *	location).  The continue flag makes for concatenated decisions, or for
X *	messages then motions, all in one entry, without the need for fake
X *	forced-motion locations. (e.g. AHHHHHHHHH...You are at the bottom with
X *	a broken neck).
X */
X
Xstruct cvloc *
Xmoveme(where,verb) struct cvloc *where; int verb;
X{
X	register struct cvtrav *ctrav;
X	auto int rugrop;
X
X	/* if he tries to use the compass, make sure this makes sense */
X	if ( (verb >= NORTH) && (verb <= NW))
X	{	if (where > (&(cvloc[30])) && !TOTING(COMPASS) )
X		{	rspeak(58); return where; } /* need compass */
X
X		if (DARK)
X		{	rspeak(74) ; return where; } /* can't read compass */
X	}
X
X	if (verb == WAIT) { return where; }
X
X	if (verb == BACK)
X	{
X		/* look for a verb which goes from where to oldloc,
X			or if oldloc has forced motion, to oldlc2.  If one is found,
X			and the verb is not magic, and does not involve random motion,
X			he can go back. */
X
X		register struct cvloc *backto;
X		register struct cvtrav *forceto ;
X		register int fword;
X
X		backto = FORCED(oldloc) ? oldlc2 : oldloc ;
X		oldlc2 = oldloc ; oldloc = where ;
X
X		if ( (backto == where) || PCT(5) ) 
X		{	rspeak(91); return where; }
X
X		for (forceto = NULL,
X				ctrav = where->travel; ctrav->word >= 0; ++ctrav)
X		{	if ((&(cvloc[ctrav->l])) == backto) {forceto = ctrav; break ; }
X			if (ctrav->l < 300)
X			{	register struct cvloc *through;
X				through = &(cvloc[ctrav->l]) ;
X				if (FORCED(through)
X					&& ((&(cvloc[through->travel->l])) == backto))
X					forceto = ctrav ;
X			}
X		}
X
X		if (forceto == NULL)
X		{	rspeak(140); /* you can't get there from here */
X			return where;
X		}
X
X		fword = forceto->word ;
X		/* make him find his own magic words */
X		if ( (fword == HOPE)
X			|| (fword == BANIS)
X			|| (fword == MISFO) )
X		{	rspeak(91); return where; }
X
X		/* don't go back through probabilities, or other conditions */
X		for (ctrav = where->travel; ctrav->word >= 0; ++ctrav)
X		{	if ( (ctrav->word == fword) && (ctrav->n))
X			{ rspeak(91); return where; }
X		}
X		verb = fword ; /* change verb to the one that does it */
X	}
X
X	oldlc2 = oldloc; oldloc = where;
X
X	switch (verb)
X	{
X	case DOWN:	rugrop = 1 ; break ;
X	case UP:	rugrop = 2 ; break ;
X	case CLIMB:	rugrop = 3 ; break ;
X	default:	rugrop = 0 ; break ;
X	}
X
X	/* find an entry with this motion verb */
X	for (ctrav = where->travel; ctrav->word >= 0; ++ctrav)
X	{	if ((ctrav->word == 1) || (ctrav->word == verb)) break ;
X	}
X
X	if (ctrav->word < 0)
X	{	/* no such motion -- unless we can find a way to do it with the
X		rug or the rope */
X		if (rugrop) {
X			register int l, len;
X			register struct rtr *rtrp;
X			l = loc - cvloc;
X			len = 0;
X			for (rtrp = rtrav; rtrp->top > 0; rtrp++) {
X				switch (rugrop) {
X				case 3: /* he said "CLIMB" */
X					if (rtrp->top == l) goto down;
X					if (rtrp->bot == l) goto up;
X					if (rtrp->mid == l) goto up;
X				case 1: /* he said "DOWN" */
Xdown:
X					if (rtrp->mid == l) {
X						if (rtrp->bot) {
X							l = rtrp->bot;
X							len = 1;
X						}
X					} else if (rtrp->top == l) {
X						if (rtrp->mid) {
X							l = rtrp->mid;
X							len = 1;
X						} else {
X							l = rtrp->bot;
X							len = 2;
X						}
X					}
X					break;
X				case 2: /* he said "UP" */
Xup:
X					if (rtrp->mid == l) {
X						l = rtrp->top;
X						len = 1;
X					} else if (rtrp->bot == l) {
X						if (rtrp->mid) {
X							l = rtrp->mid;
X							len = 1;
X						} else {
X							l = rtrp->top;
X							len = 2;
X						}
X					}
X					break;
X				} /* end switch */
X				/* l = possible destination number */
X				/* len = # of 60-foot rope segments needed */
X				if (len) break;
X			} /* end for to find destination */
X			if (len) {
X				newloc = &(cvloc[l]);
X				if (RUG->prop == 1 && rugrop != 3) { /* flying? */
X					if (rtrp->rug) {
X						rspeak(199); /* flying where he shouldn't */
X						move(RUG, &(cvloc[RUG->iloc]));
X						oldlc2 = &(cvloc[rtrp->drop]);
X						die();
X					}
X					return newloc;
X				} /* end of flying */
X				if (ROPE->conn1.where - cvloc == rtrp->top) {
X					l = ROPE->prop;
X					if (l % 2) goto L6345;
X				}
X				if (ROPE2->conn1.where - cvloc == rtrp->top) {
X					l = ROPE2->prop;
X					if (l == 3) goto L6345;
X				}
X			/* check that you have the rope or carpet set up */
XL6340:			if (rtrp == rtrav) {
X					if (PCT(20)) return loc;
X					loc = DEAD;
X					newloc = &(cvloc[24]);
X					return newloc;
X				}
X				newloc = loc;
X				if (RUG->prop == 0 && PCT(67)) rspeak(198);
X				else rspeak(14);
X				return newloc;
XL6345:
X				switch (l) {
X				case 3: /* 60 foot rope */
X					if (len > 1) {
X						rspeak(153);
X						return loc;
X					}
X				case 1: /* 120 foot rope, uncut */
X				case 7: /* 120 foot rope, spliced and tested */
XL6350:					if (RUG->prop == 1) {
X						newloc = loc;
X						rspeak(117);
X					}
X					return newloc;
X				case 5: /* 120 foot rope with a dangerous knot */
X					if (RUG->prop == 1) {
X						rspeak(117);
X						return loc;
X					}
X					if (loc == &(cvloc[rtrp->bot]) ||
X							newloc == &(cvloc[rtrp->bot])) {
X						rspeak(208);
X						ROPE->prop = 3; /* broken rope */
X						EROPE->prop = 0;
X						destry(EROPE2);
X						move(ROPE2,&(cvloc[rtrp->drop]));
X						ROPE2->prop = 2;
X						oldlc2 = &(cvloc[rtrp->drop]);
X						die();
X						return newloc;
X					}
X					goto L6350;
X				default:
X					bug(55);
X				} /* end of rope-state switch */
X			} else {
X				newloc = loc;
X			}
X		} /* end of rug/rope possibilities */
X		wrongway(verb); return where;
X	}
X	
X	do
X	{
X		for (;!(ctrav->s) && !(ctrav->l) && !(ctrav->n);++ctrav) ;
X
X		switch (ctrav->m)
X		{
X		case 0:
X			if ((ctrav->n) && !PCT(ctrav->n)) SKIP ;
X			DOIT ;
X		case IF_HAVE:
X			if (!TOTING(OBJ(ctrav->n))) SKIP ;
X			DOIT ;
X		case IF_NHAVE:
X			if (TOTING(OBJ(ctrav->n))) SKIP ;
X			DOIT ;
X		case IF_WITH:
X			if (!HERE(OBJ(ctrav->n))) SKIP ;
X			DOIT ;
X		case IF_NWITH:
X			if (HERE(OBJ(ctrav->n))) SKIP ;
X			DOIT ;
X		case IF_PROP:
X			if (OBJ(ctrav->n)->prop != ctrav->v) SKIP ;
X			DOIT ;
X		case IF_NPROP:
X			if (OBJ(ctrav->n)->prop == ctrav->v) SKIP ;
X			DOIT ;
X		}
X		bug(29) ;
X	} while ((++ctrav)->word >= 0) ;
X
X	bug(25) ;
X	return where;
X}
END_OF_cvgo.c
if test 9558 -ne `wc -c <cvgo.c`; then
    echo shar: \"cvgo.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cvmove.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cvmove.c\"
else
echo shar: Extracting \"cvmove.c\" \(3523 characters\)
sed "s/^X//" >cvmove.c <<'END_OF_cvmove.c'
X/* cvmove.c
X *   various object motion subroutines
X *************************************************************************/
X
X#include <stdio.h>
X#include "cvobj.h"
X#include "cvlocs.h"
X
Xextern void bug() ;
Xextern int holding ;
X
X/* start toting an object, removing it from the list of things at its
X * former location.  Increment 'holding' unless it was already being
X * toted.
X * Primarily used by move().
X */
Xvoid
Xcarry(obj) register struct cvobj *obj;
X{	register struct cvloc *from;
X	register struct conn *this;
X
X	from = obj->conn1.where ;
X	obj->conn1.where = TAKEN ;
X	if (from == TAKEN) return ;
X	++holding ;
X	if (from != (struct cvloc *) NULL)
X	{	for ( this = &(from->atloc);
X			this->link != &(obj->conn1); this = this->link)
X			if (this->link == NULL) bug(30);
X		this->link = obj->conn1.link ;
X	}
X	obj->conn1.link = NULL ;
X	return;
X}
X
X/* pick up an object by its second location, removing it from the list
X * of things at its former location.
X * Primarily used by move2().
X */
Xstatic void
Xcarry2(obj) register struct cvobj *obj;
X{	register struct cvloc *from;
X	register struct conn *this;
X
X	from = obj->conn2.where ;
X	obj->conn2.where = TAKEN ;
X	if (from == TAKEN) return ;
X	if (from != (struct cvloc *) NULL)
X	{	for ( this = &(from->atloc);
X			this->link != &(obj->conn2); this = this->link)
X			if (this->link == NULL) bug(30);
X		this->link = obj->conn2.link ;
X	}
X	obj->conn2.link = NULL ;
X	return;
X}
X
X/* place any object anywhere by picking it up and dropping it.
X * may already be toting it, in which case the carry is a no-op.
X *
X * to move the second place of an object, use the object's number plus
X * OBJSIZ as the object.
X *
X * 'move' may be called regardless of where the object was, whether
X * it's being carried, is lost, is destroyed, or whatever.
X */
Xvoid
Xmove(obj,toloc)
X	register struct cvobj *obj;
X	register struct cvloc *toloc;
X{
X	register struct cvloc *from;
X
X	from = obj->conn1.where ;
X	if ((from != LOST) && (from != TAKEN)) carry(obj);
X
X	if (obj->conn1.where == TAKEN) --holding ;
X	obj->conn1.where = toloc ;
X	if (toloc == LOST) return ;
X	obj->conn1.link = toloc->atloc.link ;
X	toloc->atloc.link = &(obj->conn1) ;
X	return;
X}
X
X/* place any object anywhere by picking it up and dropping it by its
X * second location.  May already be toting it, in which case the carry
X * is a no-op.
X *
X * 'move2' may be called regardless of where the object was, whether
X * it's being carried, is lost, is destroyed, or whatever.
X */
Xvoid
Xmove2(obj,toloc)
X	register struct cvobj *obj;
X	register struct cvloc *toloc;
X{
X	register struct cvloc *from;
X
X	from = obj->conn2.where ;
X	if ((from != LOST) && (from != TAKEN)) carry2(obj);
X
X	if (obj->conn2.where == TAKEN) --holding ;
X	obj->conn2.where = toloc ;
X	if (toloc == LOST) return ;
X	obj->conn2.link = toloc->atloc.link ;
X	toloc->atloc.link = &(obj->conn2) ;
X	return;
X}
X
X
X/* juggle an object by picking it up and putting it down again, the
X * purpose being to get the object to the front of the chain of things
X * at its location.
X */
Xvoid
Xjuggle(obj) register struct cvobj *obj;
X{
X	register struct cvloc *where;
X
X	where = obj->conn1.where ;
X	if (where == NULL) bug(33);
X	move(obj,where);
X	return;
X}
X
Xvoid
Xjuggl2(obj) register struct cvobj *obj;
X{	register struct cvloc *where;
X
X	where = obj->conn2.where ;
X	if (where == NULL) bug(33);
X	move2(obj,where);
X	return;
X}
X
X
X/* destroy the object by dropping at an inaccessable place
X */
Xvoid
Xdestry(obj) register struct cvobj *obj;
X{	move(obj,LOST);
X}
X
Xvoid
Xdestr2(obj) register struct cvobj *obj ;
X{	move2(obj,LOST);
X}
END_OF_cvmove.c
if test 3523 -ne `wc -c <cvmove.c`; then
    echo shar: \"cvmove.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cvocab.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cvocab.c\"
else
echo shar: Extracting \"cvocab.c\" \(9543 characters\)
sed "s/^X//" >cvocab.c <<'END_OF_cvocab.c'
X/* cvocab.c
X *    the crystal cave vocabulary
X ************************************************************************/
X
X#include "cvocab.h"
X
X/*************************************************************************
X * action defaults:
X *	each line contains the message number of the default error
X *	message for one of the action verbs.
X *************************************************************************/
Xint actspk[] = {
X	0,
X	24,	/* carry */
X	29,	/* drop */
X	38,	/* on */
X	38,	/* off */
X	28,	/* open */
X	28,	/* lock */
X	0,	/* say */
X	75,	/* rub */
X	59,	/* find */
X	59,	/* inventory */
X	13,	/* quit */
X	13,	/* score */
X	0,	/* nothing */
X	13,	/* suspend */
X	155,	/* brief */
X	13,	/* hours */
X	29,	/* throw */
X	43,	/* go */
X	8,	/* pay */
X	146,	/* break */
X	110,	/* drink */
X	110,	/* eat */
X	195,	/* read */
X	12,	/* tie */
X	147,	/* untie */
X	174,	/* feed */
X	29,	/* pour */
X	110,	/* kill/attack */
X	110,	/* rig */
X	207,	/* cut */
X	109,	/* fill */
X	38,	/* test */
X	67,	/* blast */
X	42,	/* wave */
X	191,	/* sit */
X	14,	/* calm */
X	14,	/* fly */
X	110,	/* wake */
X	0,	/* describe */
X	0,	/* touch */
X	221,	/* play */
X	0,	/* restore */
X	13};	/* help */
X
X/*************************************************************************
X * vocabulary:
X *	each entry contains a code and a word.  The codes in uppercase
X *	are defined in cvocab.h, and are used in common with other
X *	parts of the program.  The thousands-position of the code
X *	indicates what "part of speech" we have here:
X *	0:	the word is a motion verb or location reference for
X *		use in travelling.  See cvlocs.c.
X *	1:	the word is an object.
X *	2:	the word is an action verb (such as "carry", "attack")
X *	3:	the word is a special case verb (such as "dig") and
X *		the low-order part of the code is an index into the
X *		message array.  These words may duplicate objects.
X *************************************************************************/
Xstruct cvocab vtab [] = {
X{NORTH,	"north"},
X{NORTH,	"n"},
X{NE,	"northeast"},
X{NE,	"ne"},
X{EAST,	"east"},
X{EAST,	"e"},
X{SE,	"southeast"},
X{SE,	"se"},
X{SOUTH,	"south"},
X{SOUTH,	"s"},
X{SW,	"southwest"},
X{SW,	"sw"},
X{WEST,	"west"},
X{WEST,	"w"},
X{NW,	"northwest"},
X{NW,	"nw"},
X{UP,	"up"},
X{UP,	"upward"},
X{UP,	"u"},
X{UP,	"above"},
X{UP,	"ascend"},
X{DOWN,	"down"},
X{DOWN,	"downward"},
X{DOWN,	"d"},
X{DOWN,	"descend"},
X{OUT,	"out"},
X{OUT,	"outside"},
X{OUT,	"exit"},
X{OUT,	"leave"},
X{IN,	"in"},
X{ENTER,	"enter"},
X{JUMP,	"jump"},
X{BARN,	"barn"},
X{BARN,	"building"},
X{PRIVY,	"privy"},
X{PRIVY,	"outhouse"},
X{SHAFT,	"shaft"},
X{SINKH,	"sink"},
X{SINKH,	"sinkhole"},
X{PIGPE,	"pig"},
X{PIGPE,	"pigs"},
X{PIGPE,	"pigpen"},
X{BLUFF,	"bluff"},
X{HEADQ,	"park"},
X{HEADQ,	"headquarters"},
X{M_GATE,	"gate"},	/* also appears as an object word as a rnager
X				synonym 1060 */
X{M_GATE,	"mouth"},
X{M_GATE,	"entrance"},
X{LAKE,	"lake"},
X{LAKE,	"rapids"},
X{FIELD,	"field"},
X{FIELD,	"pasture"},
X{FIELD,	"meadow"},
X{BACK,	"back"},
X{BACK,	"return"},
X{BACK,	"retreat"},
X{WAIT,	"null"},
X{WAIT,	"wait"},
X{WAIT,	"nowhere"},
X{CROSS,	"cross"},
X{HOPE,	"hope"},
X{UPSTR,	"upstream"},
X{DOWNS,	"downstream"},
X{CLIMB,	"climb"},
X{CLIMB,	"scale"},
X{PATH,	"path"},
X{PAST,	"p"},
X{PAST,	"past"},
X{FUTUR,	"f"},
X{FUTUR,	"future"},
X{BANIS,	"banish"},
X{MISFO,	"misfortune"},
X
X/* start of object section */
X
X{1001,	"diamonds"},
X{1002,	"silver"},
X{1002,	"sack"},
X{_JEWLRY,	"jewelry"},
X{1004,	"coins"},
X{_CHEST,	"chest"},
X{_CHEST,	"box"},
X{_CHEST,	"treasure"},
X{_CAPE,	"ermine"},
X{_CAPE,	"cape"},
X{_CAPE,	"cloak"},
X{_CROWN,	"crown"},
X{_SCEPT,	"scepter"},
X{1009,	"sapphire"},
X{_ORB,	"platinum"},
X{_ORB,	"orb"},
X{_IDOL,	"jade"},
X{_IDOL,	"idol"},
X{_RUG,	"rug"},
X{_RUG,	"persian"},
X{_RUG,	"carpet"},
X{_UNICRN,	"unicorn"},	/* also as special verb, 3226 */
X{_UNICRN,	"collar"},	/* also as special verb, 3226 */
X{_CHAIN,	"chain"},
X{_RING,	"ring"},
X{_RING,	"adamant"},
X{_HELM,	"helm"},
X{_HELM,	"helmet"},
X{_HELM,	"mithril"},
X{1017,	"gold"},
X{1017,	"nugget"},
X{_THRONE,	"throne"},
X{_THRONE,	"seat"},
X{_THRONE,	"chair"},
X{_SWORD,	"sword"},
X{_HAMMER,	"hammer"},
X{_CUP,	"cup"},
X{_MEDAL,	"ruby"},
X{_MEDAL,	"medallion"},
X{_SCROLL,	"parchment"},	/* also so special verb, 3126 */
X{_SCROLL,	"scroll"},	/* also as special verb, 3126 */
X{_HARP,	"harp"},
X{_HARP,	"ivory"},
X{_STONE,	"arkenstone"},
X{_STONE,	"stone"},
X{_KEG,	"keg"},
X{_KEG,	"beer"},
X{1027,	"long"},
X{1027,	"longsword"},
X{1028,	"broad"},
X{1028,	"broadsword"},
X{1029,	"spear"},
X{1030,	"short"},
X{1030,	"shortsword"},
X{1031,	"bow"},
X{1032,	"dagger"},
X{1033,	"quarterstaff"},
X{1033,	"staff"},
X{1034,	"halberd"},
X{1035,	"armor"},
X{1035,	"armour"},
X{1036,	"heater"},
X{1037,	"round shield"},
X{1038,	"tall"},
X{1039,	"cuirass"},
X{_COLUMN,	"column"},
X{1041,	"pearls"},
X{1042,	"helictites"},
X{1043,	"gypsum"},
X{1043,	"flowers"},
X{1044,	"bat"},
X{1044,	"bats"},
X{1046,	"crystal"},
X{1046,	"butterfly"},
X{1046,	"butterflies"},
X{1046,	"soda-straws"},
X{1046,	"soda"},
X{1046,	"sodastraws"},
X{1046,	"straw"},
X{1046,	"straws"},
X{1046,	"stalactites"},
X{1047,	"indian"},
X{1047,	"pot"},
X
X{_COMPASS,	"compass"},
X{_KEY,	"key"},
X{_KEY,	"keys"},
X{_LAMP,	"lamp"},
X{_LAMP,	"headlamp"},
X{_RICK,	"rick"},	/* the ranger? */
X{_SEARS,	"sears"},
X{_SEARS,	"catalog"},
X{_WALLET,	"change"},
X{_WALLET,	"wallet"},
X{_DOOR,	"door"},
X{_BRIDGE,	"bridge"},
X{_BOAT,	"boat"},
X{_DAM,	"rimstone"},
X{_DAM,	"dam"},
X{_O_GATE,	"gate"},	/* name of location -- only available to
X			program -- see word 23 */
X{_O_GATE,	"ranger"},
X{_ROPE,	"rope"},	/* objects 61 to 64 are various rope parts */
X{_ROPE, "knot"},
X
X{1065,	"guano"},
X
X{_SPICE,	"spices"},
X{_KNIFE,	"knife"},
X{_KNIFE,	"knives"},
X{_FOOD,	"food"},
X{_FOOD,	"rations"},
X{_BOTTLE,	"bottle"},
X{_BOTTLE,	"jar"},
X{_WATER,	"water"},
X{_WATER,	"h2o"},
X{_WINE,	"wine"},
X{_COLA,	"coke"},
X{_COLA,	"cola"},
X{_COLA,	"orca"},
X{_MIRROR,	"mirror"},
X{_GIANT,	"priest"},
X{_GIANT,	"giant"},
X{_GIANT,	"orc"},
X{_ORCS,	"orcs"},
X{_TOMB,	"tomb"},
X{_TOMB,	"figure"},
X{_AXE,	"axe"},
X{_TOAD,	"toad"},
X{_SAND,	"sand"},
X{_SAND,	"turquoise"},
X{_SHELF,	"shelf"},
X{_HANG,	"hangings"},
X{_HANG,	"silk"},
X
X{_CRAP,	"droppings"},
X{_CRAP,	"shit"},
X{_CRAP,	"crap"},
X{_CRAP,	"poo"},
X{_SHOWER,	"shower"},
X{_VEND,	"machine"},
X{_VEND,	"vending"},
X{_BATTER,	"batteries"},
X{_DWARF,	"dwarf"},
X{_DWARF,	"dwarves"},
X{_BEAR,	"bear"},	/* also action word 3095 */
X{_BEAR,	"bugbear"},	/* also action word 3095 */
X{_BEAR,	"bug"},		/* also action word 3095 */
X{_SKELTN,	"skeleton"},
X{_SPIDER,	"spider"},
X{_SPIDER,	"grendl"},
X{_DRAGON,	"dragon"},
X{_DJINN,	"djinni"},	/* also action word 3193 */
X{_KOBOLD,	"cobol"},	/* also action word 3194 */
X{_KOBOLD,	"kobold"},	/* also action word 3194 */
X{_BALROG,	"balrog"},	/* also action word 3160 */
X{_SELF,	"*you*"},
X{_SELF,	"*yourself*"},
X{_SELF,	"self"},
X{_SELF,	"me"},
X
X/* verb section */
X
X{TAKE,	"carry"},
X{TAKE,	"take"},
X{TAKE,	"keep"},
X{TAKE,	"catch"},
X{TAKE,	"steal"},
X{TAKE,	"capture"},
X{TAKE,	"get"},
X{TAKE,	"tote"},
X{DROP,	"drop"},
X{DROP,	"release"},
X{DROP,	"free"},
X{DROP,	"discard"},
X{DROP,	"dump"},
X{DROP,	"offer"},
X{DROP,	"abandon"},
X{ON,	"light"},
X{ON,	"on"},
X{OFF,	"off"},
X{OFF,	"extinguish"},
X{UNLOC,	"open"},
X{UNLOC,	"unlock"},
X{LOCK,	"close"},
X{LOCK,	"lock"},
X{SAY,	"say"},
X{SAY,	"chant"},
X{SAY,	"sing"},
X{SAY,	"utter"},
X{SAY,	"mumble"},
X{RUB,	"rub"},
X{FIND,	"find"},
X{INVENT,	"inventory"},
X{QUIT,	"quit"},
X{QUIT,	"qui"},
X{QUIT,	"qu"},
X{QUIT,	"q"},
X{SCORE,	"score"},
X{NOTHI,	"nothing"},
X{SAVE,	"save"},
X{BRIEF,	"brief"},
X{THROW,	"throw"},
X{THROW,	"toss"},
X{THROW,	"fling"},
X{WALK,	"walk"},
X{WALK,	"run"},
X{WALK,	"travel"},
X{WALK,	"go"},
X{WALK,	"proceed"},
X{WALK,	"continue"},
X{WALK,	"explore"},
X{WALK,	"goto"},
X{WALK,	"follow"},
X{WALK,	"turn"},
X{PAY,	"pay"},
X{BREAK,	"break"},
X{BREAK,	"smash"},
X{BREAK,	"destroy"},
X{DRINK,	"drink"},
X{EAT,	"eat"},
X{READ,	"read"},
X{TIE,	"tie"},
X{UNTIE,	"untie"},
X{FEED,	"feed"},
X{POUR,	"pour"},
X{KILL,	"kill"},
X{KILL,	"fight"},
X{KILL,	"hit"},
X{KILL,	"strike"},
X{KILL,	"attack"},
X{RIG,	"rig"},
X{RIG,	"anchor"},
X{CUT,	"cut"},
X{CUT,	"divide"},
X{FILL,	"fill"},
X{TEST,	"test"},
X{BLAST,	"blast"},
X{WAVE,	"wave"},
X{WAVE,	"shake"},
X{WAVE,	"swing"},
X{SIT,	"sit"},
X{CALM,	"calm"},
X{CALM,	"placate"},
X{CALM,	"tame"},
X{FLY,	"fly"},
X{FLY,	"rise"},
X{WAKE,	"wake"},
X{WAKE,	"disturb"},
X{DESCRB,	"look"},
X{DESCRB,	"examine"},
X{DESCRB,	"describe"},
X{TOUCH,	"touch"},
X{PLAY,	"play"},
X{PLAY,	"strum"},
X{PLAY,	"finger"},
X{PLAY,	"tune"},
X{RESTOR,	"restore"},
X{RESTOR,	"resume"},
X{HELP,	"help"},
X{HELP,	"?"},
X
X/* special action words */
X
X{3010,	"left"},
X{3010,	"right"},
X{3010,	"forward"},
X{3010,	"backward"},
X
X{3050,	"fee"},
X{3050,	"fie"},
X{3050,	"foe"},
X{3050,	"foo"},
X{3050,	"fum"},
X{3050,	"xyzzy"},
X{3050,	"plugh"},
X{3050,	"sesame"},
X{3050,	"opensesame"},
X{3050,	"abra"},
X{3050,	"abracadabra"},
X{3050,	"shazam"},
X{3050,	"hocus"},
X{3050,	"pocus"},
X
X{3064,	"tree"},
X{3064,	"trees"},
X{3064,	"wood"},
X{3064,	"woods"},
X{3064,	"forest"},
X
X{3066,	"dig"},
X{3066,	"excavate"},
X{3068,	"lost"},
X
X{3069,	"mist"},
X
X{3095,	"bugbear"},	/* also object 1091 */
X{3095,	"bug"},		/* also object 1091 */
X{3095,	"bear"},	/* also object 1091 */
X
X{3123,	"time"},
X{3123,	"timemaze"},
X
X{3126,	"parchment"},	/* also object 1023 */
X{3126,	"scroll"},	/* also object 1023 */
X
X{3139,	"stop"},
X
X{3142,	"info"},
X{3142,	"information"},
X
X{3147,	"swim"},
X
X{3152,	"y"},
X{3152,	"yes"},
X{3152,	"ye"},
X{3152,	"no"},
X{3152,	"okay"},
X{3152,	"ok"},
X
X{3160,	"balrog"},	/* also object 1097 */
X
X{3190,	"siege"},
X{3190,	"perilous"},
X
X{3193,	"djinni"},	/* also object 1095 */
X{3194,	"kobold"},	/* also object 1096 */
X{3194,	"cobol"},	/* also object 1096 */
X
X{3225,	"fuck"},
X
X{3226,	"unicorn"},	/* also object 1013 */
X
X
X{0}					/************* mark the end ***************/
X};
END_OF_cvocab.c
if test 9543 -ne `wc -c <cvocab.c`; then
    echo shar: \"cvocab.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cvsave.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cvsave.c\"
else
echo shar: Extracting \"cvsave.c\" \(3854 characters\)
sed "s/^X//" >cvsave.c <<'END_OF_cvsave.c'
X/*	cvsave.c
X *		routine to save or restore the user's game
X *		only one game per user name is allowed in this version
X *		what is saved:
X *			a time-stamp of the program version (not the game)
X *			all non-stack variables from cvmain.c
X *			all variable info from cvlocs.c, cvobj.c
X *************************************************************************/
X
X#include	<string.h>
X#include	<stdio.h>
X#include	<errno.h>
X#include	<fcntl.h>
X#include	<sys/stat.h>
X#include	"cvobj.h"
X#include	"cvlocs.h"
X
X#define	DIRNAME	"/usr/games/lib/crystal/"
X#define	DIRLEN	(sizeof DIRNAME)
Xextern char *cuserid();
Xextern char emain, datastart;
Xextern int saved;
Xstatic char savename[DIRLEN+L_cuserid] = DIRNAME;
Xstatic unsigned datalen ;
Xstatic unsigned conlen = sizeof(struct cvloc *) + sizeof(struct conn *);
X
Xlong ptime = -1;		/* program time-stamp */
X
Xvoid
Xcvsave()
X{	register struct cvloc *curloc;
X	register struct cvobj *curobj;
X	auto char userid[L_cuserid];
X	auto struct stat buf;
X	auto int save;
X
X	datalen = &emain-&datastart;
X
X	if (cuserid(userid) == NULL) {
X		puts("\nCannot save because I don't know who you are!");
X		return;
X	}
X	
X	(void) strcpy(savename+DIRLEN-1, userid);
X	if (stat(savename,&buf) == -1) {
X		if (errno != ENOENT) {
X			puts("\nCannot save because of directory trouble\n");
X			return;
X		}
X	} else {
X		if (yes(93,0,0)) {
X			if (unlink(savename) == -1) {
X				printf("\nCannot unlink %s\n",savename);
X				return;
X			}
X		} else { return; }
X	}
X	if ((save = open(savename,O_WRONLY|O_EXCL|O_CREAT,0600)) == -1) {
X		printf("\nCannot create %s\n",savename);
X		return;
X	}
X	if (write(save,&ptime,sizeof(long)) == -1
X		|| write(save,&datastart,datalen) == -1) {
X		perror("Saving cave:");
X		close(save);
X		unlink(savename);
X		return;
X	}
X	for (curobj = cvobj; curobj->desc != NULL; curobj++) {
X		if (write(save, &(curobj->prop), sizeof(int)) == -1
X			|| write(save, &(curobj->conn1.where),conlen) == -1
X			|| write(save, &(curobj->conn2.where),conlen) == -1) {
X			perror("Saving cave objects");
X			close(save);
X			unlink(savename);
X			return;
X		}
X	}
X	for (curloc = cvloc; curloc->travel != NULL; curloc++) {
X		if (write(save, &(curloc->abb), sizeof(int)) == -1
X			|| write(save, &(curloc->atloc.where),conlen) == -1) {
X			perror("Saving cave places");
X			close(save);
X			unlink(savename);
X			return;
X		}
X	}
X	(void) close(save);
X	return;
X}
X
Xvoid
Xcvrest()
X{	register struct cvloc *curloc;
X	register struct cvobj *curobj;
X	auto char userid[L_cuserid];
X	auto int save;
X	auto long ftime = -1;
X
X	datalen = &emain-&datastart;
X
X	if (cuserid(userid) == NULL) {
X		puts("\nCannot restore because I don't know who you are!");
X		return;
X	}
X	
X	(void) strcpy(savename+DIRLEN-1, userid);
X
X	if ((save = open(savename,O_RDONLY)) == -1) {
X		printf("\nCannot find %s\n",savename);
X		return;
X	}
X	if (read(save,&ftime,sizeof(long)) != sizeof(long)
X#ifdef	XVERSION
X		|| ftime != ptime
X#endif
X		|| read(save,&datastart,datalen) != datalen) {
X		if (ftime == -1) {
X			perror("Restoring cave:");
X		} else {
X			puts("\nSave file not created by this version");
X		}
X		close(save);
X		unlink(savename);
X		return;
X	}
X	for (curobj = cvobj; curobj->desc != NULL; curobj++) {
X		if (read(save, &(curobj->prop), sizeof(int)) != sizeof(int)
X			|| read(save, &(curobj->conn1.where),conlen) != conlen
X			|| read(save, &(curobj->conn2.where),conlen) != conlen) {
X			perror("Restoring cave objects");
X			close(save);
X			unlink(savename);
X			return;
X		}
X	}
X	for (curloc = cvloc; curloc->travel != NULL; curloc++) {
X		if (read(save, &(curloc->abb), sizeof(int)) != sizeof(int)
X			|| read(save, &(curloc->atloc.where),conlen) != conlen) {
X			perror("Restoring cave places");
X			close(save);
X			unlink(savename);
X			return;
X		}
X	}
X	if (read(save, &ftime, 1) != 0) {
X		puts("\nNot end of file");
X		close (save);
X		unlink(savename);
X		exit(1);
X	}
X	(void) close(save);
X	if (saved == 1) saved = -1;
X	return;
X}
END_OF_cvsave.c
if test 3854 -ne `wc -c <cvsave.c`; then
    echo shar: \"cvsave.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 4 \(of 5\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 5 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0