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