games-request@tekred.TEK.COM (01/13/88)
Submitted by: nrcvax!kosman!kevin Comp.sources.games: Volume 3, Issue 35 Archive-name: crystal/Part03 #! /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 3 (of 5)." # Contents: cvact.c cvend.c cvmain.c cvocab.h # Wrapped by billr@tekred on Tue Jan 12 10:11:32 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f cvact.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"cvact.c\" else echo shar: Extracting \"cvact.c\" \(20904 characters\) sed "s/^X//" >cvact.c <<'END_OF_cvact.c' X/* cvact.c X * perform actions 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 juggle(); 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 Xint Xsuicide() X{ X pspeak(SELF,1); X die(); X return S_show; X} X Xstatic void Xdolight(object,state) Xregister struct cvobj *object; Xregister int state; X{ X if (object != LAMP) { X rspeak(180); X } else if (limit < 0) { X rspeak(184); X } else if (object->prop == state) { X rspeak(182-state); /* already in that state */ X } else { X rspeak(40 - state); X object->prop = state; X if (DARK) { X rspeak(16); X } X } X return; X} X Xint Xdrownch() X{ X if (loc->flags & DROWN) X { rspeak(120); /* You can't swim */ X oldlc2 = loc; /* and all your stuff gets lost in the water */ X die(); /* you guessed it! */ X return TRUE; X } else { X return FALSE; X } X} X Xvoid Xdidorc() X{ pspeak(ORCS,3); /* the orcs agree */ X ORCS->prop = 0; /* now kill THEM off */ X pspeak(IDOL,2); /* idol explodes (which is what kills the orcs) */ X IDOL->prop = 0; /* make idol toteable */ X destr2(IDOL); /* unfix the idol */ X pspeak(IDOL,0); /* report the new state of the (now small) idol */ X GIANT->prop = 1; /* Now for the BAD NEWS */ X pspeak(GIANT,1); /* He's after you for sure */ X X /* Now start giant (as the priest) and the balrog */ X PRIEST->dloc = PRIEST->oloc = loc; /* he's right with you */ X PRIEST->dseen = TRUE; /* of course */ X X BALLY->dloc = BALLY->oloc = &(cvloc[141]); /* anchor ledge */ X BALLY->dseen = FALSE; /* he'll get you later */ X return; X} X Xvoid Xnewcon(object,p,liquid) Xregister struct cvobj *object; Xregister int p, liquid; X{ pspeak(object,p); /* tell what the new contents are */ X if (HERE(ORCS) && (ORCS->prop == 1) && (liquid == _COLA)) didorc(); X} X Xint Xdrunkbear(object) Xregister struct cvobj *object; X{ X BEAR->prop = 0; X object->prop = (object == KEG) ? 1 : 0; X move(object,loc); X juggle(BEAR); X move2(object,FIXED); X YOGI->dseen = FALSE; X YOGI->dloc = DEAD; X if (AXE->prop == 1 && AXE->conn2.where == FIXED) { X AXE->prop = 0; X destr2(AXE); X } X return S_show; X} X Xint Xwakeking() X{ HELM->prop = 0; X destry(HELM); X ARTHUR->dseen = TRUE; X ARTHUR->dloc = loc; X pspeak(HELM, 2); /* oops, he's after you */ X return S_okay; X} X Xint Xunicorn() X{ pspeak(UNICRN,UNICRN->prop + 2); X if (UNICRN->prop == 1) { X destr2(UNICRN); X UNICRN->prop = 0; X EINHORN->dseen = FALSE; X EINHORN->dloc = EINHORN->oloc = DEAD; X pspeak(UNICRN,0); X } X return S_okay; X} X Xint Xcvact(verb,obj,object) register int verb, obj; Xregister struct cvobj *object; X{ X register int k; X X switch ((!!obj*10000) + verb) X { X case TRANS DROP: X case TRANS THROW: /* a few cases handled elsewhere */ X case INTRANS FEED: X case TRANS FEED: X case INTRANS POUR: X case TRANS POUR: X case INTRANS FILL: X case TRANS FILL: X return cvatt(verb,obj,object); X X case INTRANS SAVE: X cvsave(); X OKAY(54); X X case INTRANS RESTOR: X cvrest(); X rspeak(54); X return S_show; X X case INTRANS TAKE: X /* take what? I can figure it out if there's only one thing here, X but otherwise, I complain. */ X if ((loc->atloc.link == NULL) || (loc->atloc.link->link != NULL)) X { return S_what; } X X /* if there's liquid here, too, I get confused, which may just X confuse the adventurer, or may give him the hint he needs */ X if (LIQLOC(loc)) { return S_what; } X X /* if the one object is the skeleton in attack mode, there's a X cutlass too, so we treat it as confusing, too */ X if (HERE(SKELTN) && (SKELTN->prop == 1)) { return S_what; } X X /* if any creatures are here, they confuse things, too */ X { register struct monster *cre; X X for (cre = orcs; cre->iloc != -1; ++cre) X { if (cre->dloc == loc) { return S_what; } } X } X X object = loc->atloc.link->who ; X obj = (object - cvobj) + 1000 ; X X case TRANS TAKE: X /* taking something X * artifacts get destroyed (this should annoy the usual greedy X players X * liquids are treated specially, since they are shown as X properties of places and vessels. X * there are some other interesting side-effects, too! X */ X X if ((object >= MINART) && (object <= MAXART)) BREAKIT ; X X if (HERE(DRAGON) && DRAGON->prop ) OKAY(203); X X if (object == SHOWER) X { pspeak(SHOWER,1); X CRAP->prop = 0 ; X return S_okay; X } X X if ((object == ROPE) X && (TOTING(ROPE) || (ROPE->prop % 2) ) X && HERE(ROPE2)) X { obj = _ROPE2; object = ROPE2; } X X if (TOTING(object)) DEFMSG ; X X if (DARK) OKAY(202); X X if ((object == WINE) || (object == COLA) || (object == WATER)) X { register int k; X k = obj; obj = 0; X if (AT(BOTTLE) && (LIQ(BOTTLE) == k )) obj = _BOTTLE ; X if (AT(CUP) && (LIQ(CUP) == k)) obj = obj*100 + _CUP ; X if (obj > 4000) { return S_what; } X if (LIQLOC(loc) == k) X { if (obj) { return S_what; } /* quibble about ambiguity */ X if (TOTING(BOTTLE) && !(BOTTLE->prop)) obj = _BOTTLE ; X if (TOTING(CUP) && !(CUP->prop)) obj = obj*100 + _CUP ; X if (obj > 4000) X { fputs("Into what?\n",stdout) ; X mltcmd = FALSE ; X return S_obj; X } X if (obj) X { object = OBJ(obj); X FILLIT(object,k); X newcon(object, object->prop + 7, k); X } else { X rspeak(104) ; /* nothing to put it in */ X } X return S_okay ; X } X X if (!obj) OKAY(24); X object = OBJ(obj); X } X X if (holding >= 9) OKAY(92); /* too many */ X X if (object == TOAD) X { pspeak(TOAD,1); /* all this for fun and games! */ X destry(TOAD); /* he oughtta get points just for reading this*/ X return S_okay; X } X X if (object == HANG) { X pspeak(HANG,HANG->prop + 1); X if (HANG->prop == 0) { X HANG->prop = 2; X juggle(HANG); X } X return S_show; X } X X if ((object == UNICRN) && UNICRN->prop) X { pspeak(UNICRN,UNICRN->prop + 2); X if (UNICRN->prop != 1) return S_okay; X destr2(UNICRN); /* make it not fixed any more */ X EINHORN->dseen = FALSE ; X EINHORN->dloc = EINHORN->oloc = DEAD; X pspeak(UNICRN, (UNICRN->prop = 0)); /* make it just a collar */ X return S_okay; X } X X if (object == BOAT) object->prop += 2; X X /* if the object has a second location, you can't touch it! */ X /* the reason given is it's beyond your power or just ridiculous */ X if (object->conn2.where != LOST) OKAY(IFTREAS(object) ? 146 : 25); X X if ((object == RING) && (JEANNIE->dloc != DEAD)) X { if (JEANNIE->dloc != loc) X OKAY(146); /* beyond YOUR power (need jinni) */ X carry(object); X JEANNIE->oloc = JEANNIE->dloc = DEAD; X JEANNIE->dseen = FALSE; X OKAY(209); /* explain what happened to jinni */ X } X X carry(object); X X if ((object == CROWN) && (HELM->prop)) return wakeking(); X X if ((object == CHEST) && (SKELTN->prop)) X { rspeak(54); /* okay, but ... */ X rspeak(96); /* it DOES have a side effect! */ X SKELTN->prop = 1; X rspeak(101); /* he always misses the first swing */ X return S_miss; /* of course, everything else is just FINE! */ X } X X OKAY(54); X X case INTRANS UNLOC: X obj = 0; X if (HERE(HELM) & HELM->prop) obj = _HELM; X if (AT(DOOR)) { X if (obj) return S_what; X else obj = _DOOR; X } X if (HERE(CHAIN) && CHAIN->prop) { X if (obj) return S_what; X else obj = _CHAIN; X } X if (!obj) return S_what; X object = OBJ(obj); X case TRANS UNLOC: X if (object == HELM) return wakeking(); X if (object == BEAR && HERE(CHAIN) && CHAIN->prop == 2) { X obj = _CHAIN; X object = OBJ(obj); X } X if (object == CHAIN) { X if (!HERE(KEY)) OKAY(31); X if (CHAIN->prop == 0) OKAY(37); X CHAIN->prop = 0; X destr2(CHAIN); X if (!HERE(BEAR) || BEAR->prop <= 2) OKAY(54); X BEAR->prop -= 2; X YOGI->dseen = TRUE; X YOGI->dloc = loc; X return S_show; X } X goto Leave; X X case INTRANS LOCK: X if (AT(DOOR)) obj = _DOOR; X if (HERE(CHAIN)) { X if (obj) return S_what; X else obj = _CHAIN; X } X if (!obj) return S_what; X object = OBJ(obj); X case TRANS LOCK: X if (object == CHAIN) { X if (!HERE(KEY)) OKAY(31); X if (TOTING(CHAIN)) move(CHAIN,loc); X CHAIN->prop = 1; X move2(CHAIN,FIXED); X return S_okay; X } XLeave: X if (object == NULL) DEFMSG; X if (object == DOOR && HERE(KEY)) { X if (closing) { X if (!panic) clock2 = 15; X panic = TRUE; X OKAY(130); X } else { X k = 34 + DOOR->prop; X DOOR->prop = (verb == LOCK) ? 0 : 1; X OKAY(k + 2*(DOOR->prop)); X } X } else { X if (object == DOOR) OKAY(31); X if (object == KEY) OKAY(55); X OKAY(33); X } X X case INTRANS PAY: X if (loc == O_GATE->conn1.where) X object = O_GATE; X else OKAY(8); X case TRANS PAY: X if (object != O_GATE) OKAY(8); X if (TOTING(RUG) && RUG->prop == 1) OKAY(117); X if (!HERE(WALLET)) OKAY(20); X if (WALLET->prop > 3) OKAY(21); X if (O_GATE->prop == 2) OKAY(46); X if (CRAP->prop) OKAY(113); X (WALLET->prop)++; X loc++; X return S_show; X X case TRANS BREAK: X if (object <= MINART && object >= MAXART) BREAKIT; X if (object == MIRROR) { X pspeak(object,object->prop + 3); X bonus = !(object->prop); X finish = TRUE; X return S_show; X } else if (object == DAM) { X if (DAM->prop) return S_what; X BRIDGE->prop = DAM->prop = 1; X O_GATE->prop = 2; X rspeak(41); X if (BOAT->prop % 2) { X move(BOAT,BOATPLC); X k = BOAT->prop; X BOAT->prop = 4; X move2(BOAT,FIXED); X rspeak(32); X if (k == 3) { X rspeak(45); X die(); X } X } X return S_show; X } else DEFMSG; X X case INTRANS TEST: X case TRANS TEST: X if (object == ROPE) { X if (HERE(ROPE) && (ROPE->prop == 4 || ROPE->prop == 6)) { X ROPE->prop = 6; X OKAY(54); X } else OKAY(29); X } X if (!HERE(LAMP)) DEFMSG; X printf("%d turns of life left in your lamp batteries.",limit); X return S_okay; X X case INTRANS CUT: X object = ROPE; X if (!HERE(ROPE) && HERE(ROPE2)) X object = ROPE2; X else if (!HERE(ROPE) && HERE(EROPE)) X object = EROPE; X else if (!HERE(ROPE)) X return S_what; X case TRANS CUT: X if (!HERE(AXE) && !HERE(SWORD)) DEFMSG; X if (object != ROPE && object != ROPE2 && object != EROPE) X return S_what; X k = ROPE->prop > 3 ? 167 : 54; /* untie it sometimes */ X if (object == EROPE) { X if (object->prop <3) OKAY(108); /* It's gotta be long */ X ROPE->prop = 3; /* anchored 60-foot rope */ X EROPE->prop = 0; /* end of 60-foot rope */ X ROPE2->prop = 2; /* loose 60-foot rope */ X move(ROPE2,loc); /* bring it here */ X destry(EROPE2); X } else { X if (object->prop % 2) OKAY(168); /* not at anchor */ X if (object->prop == 2) OKAY(108); /* too short */ X ROPE->prop = ROPE2->prop = 2; X move(ROPE2,loc); X } X rspeak(k); X return S_show; X X case INTRANS TIE: X if (HERE(ROPE)) object = ROPE; X if (HERE(ROPE2)) object = ROPE2; X if (HERE(BOAT)) { X if (object != NULL) return S_what; X object = BOAT; X } X case TRANS TIE: X if (object == BOAT) { X if (object->prop == 4) OKAY(30); X if (!(object->prop % 2)) OKAY(27); X object->prop--; X OKAY(54); X } X if (HERE(ROPE) && HERE(ROPE2) && ROPE->prop == 2) { X ROPE->prop = 4; X destry(ROPE2); X destry(EROPE2); /* just in case it was rigged */ X OKAY(54); X } X /* NOTE: fall through to RIG when tying complete rope */ X case INTRANS RIG: X case TRANS RIG: X object = NULL; X if (HERE(ROPE) && !(ROPE->prop % 2)) object = ROPE; X else if (HERE(ROPE2) && ROPE2->prop == 2) object = ROPE2; X else OKAY(205); /* You have no rope */ X { register struct rtr *rtr; X register struct cvobj *obj2; X X obj2 = object + 2; /* EROPE object */ X k = loc - cvloc; X for (rtr = rtrav; rtr->top != -1; rtr++) X if (k == rtr->top) break; X if (rtr->top == -1) X OKAY(204); /* nothing to tie it to */ X if (rtr->mid == 0 && object->prop == 2) X rspeak(206); /* It won't reach */ X object->prop ++; /* tie it */ X if (TOTING(object)) move(object,loc); /* drop it */ X move2(object,FIXED); /* fix it */ X move(obj2, &(cvloc[rtr->mid])); /* move the end */ X move2(obj2,FIXED); /* fix the end */ X obj2->prop = 0; /* assume the bottom */ X if (object==ROPE && !(rtr->bot) && ROPE->prop!=3) { X if (rtr->mid == DUNGEON) { X obj2->prop = 3; /* show the rest of the rope */ X } X else { X obj2->prop = 4; /* show the rest of the rope */ X } X } X if (rtr->bot && object == ROPE && object->prop != 3) { X if (rtr->mid) { X obj2 = EROPE2; X EROPE->prop = (int)(ROPE->prop/4) +1; X } else obj2 = EROPE; X move(obj2,&(cvloc[rtr->bot])); X move2(obj2,FIXED); X } X return S_show; X } X X case INTRANS UNTIE: X if (HERE(BOAT)) { X if (HERE(ROPE) || HERE(ROPE2)) return S_what; X object = BOAT; X } else if (HERE(ROPE)) object = ROPE; X else if (HERE(ROPE2)) object = ROPE2; X case TRANS UNTIE: X if (object == BOAT) { X if (object->prop == 4) OKAY(30); X if (object->prop % 2) OKAY(26); X object->prop ++ ; X OKAY(54); X } X if (HERE(ROPE) && (ROPE->prop == 4 || ROPE->prop == 6)) { X ROPE->prop = ROPE2->prop = 2; X move(ROPE2,loc); X rspeak(54); X return S_show; X } X if (HERE(EROPE) && (ROPE->prop > 3) && (EROPE->prop > 2)) { X /* dividing a long rope while it's rigged */ X ROPE->prop = 3; /* make it short */ X EROPE->prop = 0; /* make the end short, too */ X ROPE2->prop = 2; /* create a short coil */ X destry(EROPE2); /* with no end */ X move(ROPE2,loc); /* bring it here */ X rspeak(54); X return S_show; X } X /* now try this as an "unrig" */ X if (HERE(ROPE) && (ROPE->prop % 2)) object = ROPE; X else if (HERE(ROPE2) && ROPE2->prop == 3) object = ROPE2; X else DEFMSG; X object->prop--; X destr2(object); X if (object == ROPE && EROPE->prop) destry(EROPE2); X destry(object+2); /* destroy the end */ X return S_show; X X /* rubbing the helm gets you in trouble (but you gotta do it), X rubbing the lamp gives you a ribbing, rubbing anything else is X just useless */ X case TRANS RUB: X if (object == LAMP) DEFMSG; X if (object == HELM && HELM->prop) return wakeking(); X OKAY(76); X X case TRANS INVENT: X case TRANS FIND: X if (object == UNICRN && UNICRN->prop && HERE(UNICRN)) X return unicorn(); X if (TOTING(object)) OKAY(24); X if (closed) OKAY(138); X if (obj == _DWARF) { X register struct monster *cre; X for (cre = MINDWR; cre <= MAXDWR; ++cre) { X if (cre->dloc == loc && dflag >= 2) { X OKAY(94); X } X } X } X if (AT(object) X || (LIQ(BOTTLE) == obj && AT(BOTTLE)) X || (LIQLOC(loc) == obj)) { X OKAY(94); X } X X case INTRANS INVENT: X k = FALSE; X for (object = cvobj; object->desc != NULL; object++) { X if (strlen(object->desc) && TOTING(object)) { X if (!k) {rspeak(99); k = TRUE; } X blklin = FALSE; X fputs(" ",stdout); X putcode(object->desc); X putchar('\n'); X if ((object == CUP || object == BOTTLE) X && object->prop) { X pspeak(object, object->prop + 3); X } X blklin = TRUE; X } X } X if (!k) rspeak(98); X return S_okay; X X case TRANS CALM: X if (object == UNICRN && UNICRN->prop) return unicorn(); X DEFMSG; X X case INTRANS KILL: X obj = 0; X if (ME->dloc == loc) obj = _SELF; X if (YOGI->dloc == loc) { X if (obj) return S_what; X else obj = _BEAR; X } X if (!obj) { X register struct monster *cre; X for (cre = orcs; cre->iloc != -1; ++cre) { X if (cre->dloc == loc) OKAY(49); X } X OKAY(44); X } X object = OBJ(obj); X case TRANS KILL: X if (object >= MINART && object <= MAXART) BREAKIT; X if (object == SELF) return suicide(); X if (object == BEAR) OKAY(165); X OKAY(49); X X case INTRANS EAT: X if (HERE(FOOD)) { X destry(FOOD); X OKAY(72); X } else { X return S_what; X } X X case TRANS EAT: X if (object == FOOD) { X destry(FOOD); X OKAY(72); X } X X if (object == BEAR X || object == SPIDER X || object == SELF X || object == DRAGON X || object == SKELTN X || object == BALROG X || object == DWARF) OKAY(71); X DEFMSG; X X case INTRANS DRINK: X obj = LIQLOC(loc); X if (HERE(CUP)) { X if (obj) return S_what; X else obj = LIQ(CUP); X } X if (HERE(BOTTLE)) { X if (obj) return S_what; X else obj = LIQ(BOTTLE); X } X if (!obj) return S_what; X object = OBJ(obj); X case TRANS DRINK: X if (object != BOTTLE && object != CUP) { X k = obj; X obj = 0; X if (HERE(CUP) && OBJ(LIQ(CUP)) == object) obj = _CUP; X if (HERE(BOTTLE) && OBJ(LIQ(BOTTLE)) == object) { X if (obj) OKAY(143); /* From what? (2 possibilities) */ X obj = _BOTTLE; X } X if (OBJ(LIQLOC(loc)) == object) { X if (obj) OKAY(143); /* From what? (2 possibilities) */ X OKAY(object == WATER ? 73 : 72); X } X if (!obj) OKAY(143); /* from what? no possibilities */ X } X object = OBJ(obj); /* object is now the container */ X if ((k=LIQ(object)) == 0) {pspeak(object,11); return S_okay; } X rspeak(object == WATER ? 73 : 72); /* take the drink */ X object->prop = 0; X newcon(object, 7, k); X return S_okay; X X case INTRANS SIT: X if (!HERE(THRONE) || THRONE->prop == 0) { X if ((HERE(BOAT) && BOAT->prop/2 == 1) X || (TOTING(RUG) && RUG->prop == 1)) X rspeak(192); X else DEFMSG; X return S_okay; X } X k = 0; X if (HERE(SCEPT)) k++; X if (HERE(CROWN)) k++; X if (HERE(CAPE)) k++; X if (HERE(ORB)) k++; X pspeak(THRONE,2); X pspeak(THRONE,k+3); X oldlc2 = loc; X if (k == 0) die(); X if (k != 4) return S_show; X /* He got it right -- cast him into new universe of adventures */ X THRONE->prop = 0; X destr2(THRONE); /* throne is now a treasure */ X newloc = &(cvloc[124]); X /* start some new monsters */ X JEANNIE->dloc = RING->conn1.where; X SLASHER->dloc = JEWLRY->conn1.where; X EINHORN->dloc = RUG->conn1.where; X return S_move; X X case INTRANS FLY: X if (!TOTING(RUG)) DEFMSG; X if (RUG->prop) OKAY(154); X if (loc > &(cvloc[137])) OKAY(136); X if (loc < &(cvloc[63])) OKAY(136); X RUG->prop = 1; X OKAY(54); X X case TRANS WAVE: X if (!TOTING(object)) OKAY(29); X if (closing) DEFMSG; X if (object != SCEPT) OKAY(42); X if (HERE(HELM) && HELM->prop) return wakeking(); X if (ARTHUR->dloc != loc) OKAY(76); X ARTHUR->dloc = DEAD; X ARTHUR->dseen = FALSE; X move(HELM,loc); /* bring helm here (was destroyed while Arthur X was walking around */ X destr2(HELM); /* make it takeable */ X pspeak(HELM,6); /* crumble Arthur to dust */ X newloc = loc; X return S_move; X X case INTRANS BRIEF: X abbnum = 10000; X detail = 99; X OKAY(156); X X case INTRANS READ: X if (DARK) return S_what; X if (HERE(SCROLL)) object = SCROLL; X else return S_what; X case TRANS READ: X if (DARK) return S_dark; X if (object != SCROLL) DEFMSG; X OKAY(126); X X case INTRANS SCORE: X getscore(); X printf("\nIf you were to quit now (after %d moves), you would \ Xscore %d\nout of a possible %d points.\n",turns,score,mxscore); X return S_okay; X X case TRANS BLAST: X case INTRANS BLAST: X if (!closed) DEFMSG; X finish = TRUE; X return S_show; X X case INTRANS ON: X if (!HERE(LAMP)) DEFMSG; X object = LAMP; X case TRANS ON: X dolight(object,1); X return S_light; X X case INTRANS OFF: X if (!HERE(LAMP)) DEFMSG; X object = LAMP; X case TRANS OFF: X dolight(object,0); X return S_light; X X case INTRANS DESCRB: X case INTRANS TOUCH: X if (detail++<3) rspeak(15); X wzdark = FALSE; X loc->abb = 0; X newloc = loc; X return S_move; X X case TRANS TOUCH: X if (object == TOAD) { X pspeak(TOAD,1); X destry(TOAD); X return S_okay; X } X if (object >= MINART && object <= MAXART) BREAKIT; X if (object == UNICRN && HERE(object) && object->prop) X return unicorn(); X /* fall through to describe */ X case TRANS DESCRB: X k = vocab(oword,3); X if (k > 0) OKAY(k%1000); X rspeak(15); X wzdark = FALSE; X loc->abb = 0; X newloc = loc; X return S_move; X X case INTRANS PLAY: X if (!HERE(HARP)) return S_what; X object = HARP; X case TRANS PLAY: X if (object != HARP) DEFMSG; X pspeak(object,1); X if (UNICRN->prop == 2 && HERE(UNICRN)) { X UNICRN->prop = 1; X OKAY(222); X } X if (UNICRN->prop != -1 && UNICRN->prop != 2) X return S_okay; X if ((loc >= &(cvloc[62])) X && (dflag >= 2) X && (EINHORN->dloc != DEAD) X && (!(EINHORN->dseen)) X && (!(BADPLC(loc)))) { X move(UNICRN,loc); X EINHORN->dloc = EINHORN->oloc = loc; X EINHORN->dseen = TRUE; X rspeak(222); X } X return S_okay; X X case INTRANS DROP: X case INTRANS SAY: X case INTRANS RUB: X case INTRANS FIND: X case INTRANS BREAK: X case INTRANS THROW: X case INTRANS WAVE: X case INTRANS CALM: X case INTRANS WAKE: X case TRANS SIT: X return S_what; X X case INTRANS HELP: X rspeak(157); X while (getchar() != '\n') ; X rspeak(158); X return S_okay; X X case INTRANS QUIT: X if (!(gaveup = yes(22,54,54))) return S_okay; X finish = TRUE; X return S_show; X X case TRANS QUIT: X case TRANS SCORE: X case TRANS SAVE: X case TRANS RESTOR: X case TRANS BRIEF: X case TRANS WALK: X case TRANS FLY: X case TRANS WAKE: X case TRANS HELP: X DEFMSG; X X case INTRANS NOTHI: X case TRANS NOTHI: X OKAY(54); X X default: X fputs("Unknown verb.\n",stdout); X return S_okay; X } /* end of verb switch */ X} END_OF_cvact.c if test 20904 -ne `wc -c <cvact.c`; then echo shar: \"cvact.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f cvend.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"cvend.c\" else echo shar: Extracting \"cvend.c\" \(1628 characters\) sed "s/^X//" >cvend.c <<'END_OF_cvend.c' X/* cvend.c X * do stuff about the end of the game. X *************************************************************************/ X X#include <stdio.h> X#include "cvmisc.h" X#include "cvobj.h" X#include "cvlocs.h" X#include "cvocab.h" X Xvoid Xgetscore() X{ register struct cvobj *object; X register struct hint *hint; X X score = 0; X /* get a first impression of how far the adventurer went */ X if (RICK->prop > 0) score = 10; X if (DAM->prop > 0) score = 25; X if (dflag != 0) score = 30; X if (THRONE->prop == 0) score = 35; X mxscore = 35; X X /* tally treasures. Full points if in barn and not broken. X 2 points each for treasures seen. */ X for (object = MINTRS; object < ENDTRS; ++object) { X register int value; X mxscore += X (value = (object < RUG) ? 12 : ((object == RUG) ? 14 : 16)); X if (object->prop >= 0) { X if (INBARN(object) X && (object->prop == 0 || object == CUP)) X score += value; X else score += 2; X } X } X X /* Now look at how he finished, and how far he got. X * "maxdie" and "numdie" tell us how well he survived. X * "gaveup" says whether he is using "QUIT". X * "dflag" will tell us if he ever got suitably deep into the cave. X * "closing" still indicates whether he reached the endgame. X * if he got as far as "CAVE CLOSED" then bonus will be false for X * mundane exits. X */ X score += (maxdie - numdie)*10; mxscore += maxdie * 10; X if (!scoring && !gaveup) score += 10; mxscore += 10; X if (closing) score += 30; mxscore += 30; X if (closed) { X score += 5; X if (bonus) score += 15; X } X mxscore += 20; X X for (hint = hints; hint->turns >= 0; ++hint) { X if (hint->hinted) score -= hint->points; X } X return; X} END_OF_cvend.c if test 1628 -ne `wc -c <cvend.c`; then echo shar: \"cvend.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f cvmain.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"cvmain.c\" else echo shar: Extracting \"cvmain.c\" \(23773 characters\) sed "s/^X//" >cvmain.c <<'END_OF_cvmain.c' X/* cvmain.c X ************************************************************************/ X X#define SHORT 50 X X#include <stdio.h> X#include <string.h> X#include <fcntl.h> X#include "cvobj.h" X#include "cvlocs.h" X#include "cvocab.h" X#include "cvmsg.h" X#include "random.h" X#include "cvorcs.h" X#include "cvmisc.h" X#include "cvcode.h" X Xextern char etext; Xextern char edata; Xextern char end; Xextern char _etext; Xextern char _edata; Xextern char _end; X Xextern char *rmsg[] ; Xextern int actspk[] ; Xextern struct cmsg ctext[] ; Xextern struct cvocab vtab [] ; Xextern int maxloc ; Xextern void exit(); Xextern void carry(); Xextern void move(); Xextern void move2(); Xextern void destry(); Xextern void getin(); Xextern void juggle(); Xextern void juggl2(); Xextern void checkobj(); Xextern void checkloc(); Xextern void fixrmsg(); Xextern void motd(); Xextern void rspeak(); Xextern void pspeak(); Xextern void mspeak(); Xextern void putcode(); Xextern int yes(); Xextern struct cvloc *moveme(); X Xint saved = 0; /* this defines the un-initialized state */ X Xchar *word1, *word2; Xchar *vword, *oword; X Xstruct cvobj *lastobj ; Xstruct cvloc *loc = NULL; Xstruct cvloc *newloc, *oldloc, *knfloc, *oldlc2; Xint dflag = 0, X demo = 0, X score = 0, X mxscore = 0, X limit = 0, /* how long his lamp will last on current power */ X setup = 0, /* state of setup */ X tally = 0, /* count of treasures yet to see */ X tally2 = 0, /* count of treasures you'll never see */ X inorth = 0, /* # of times he said NORTH instead of N */ X detail = 0, /* # of times we said "not allowed . . */ X numdie = 0, /* # of times he died so far */ X maxdie = 0, /* # of ways to resurrect him */ X holding = 0, /* # objects he's carrying */ X dkill = 0, /* # of dwarves killed */ X turns = 0, X nxtchr = 0, X abbnum = 0, /* how often he gets long description */ X clock1 = 0, /* time from last treasure to closing */ X clock2 = 0, /* time from closing to closed */ X /* LOGICALS FOLLOW */ X bonus = FALSE, /* gets bonus for correct finish */ X closing = FALSE, /* are we closing? */ X panic = FALSE, /* has he panicked */ X wzdark = FALSE, X closed = FALSE, X gaveup = FALSE, X scoring = FALSE, X mltcmd = FALSE, X blklin = FALSE, X samvrb = FALSE, X finish = FALSE, X lmwarn = FALSE; X X Xstruct monster orcs[] = { X {0}, /* spider */ /* monsters first */ X {0}, /* dragon */ X {0}, /* king */ X {0}, /* djinni */ X {0}, /* kobold */ X {0}, /* bugbear */ X {0}, /* unicorn */ X {0}, /* giant orc */ X {0}, /* balrog */ X {62,1}, /* dwarf in pool hall */ /* dwarves next */ X {78,1}, /* dwarf in privy chamber */ X {85,1}, /* dwarf at window in secret passage */ X {100,1}, /* dwarf in the time maze */ X {126,1}, /* dwarf in the harem */ X {130,1}, /* dwarf at the shelf */ X {87}, /* pirate at where he hides his chest */ /* then these */ X {0}, /* *YOU* */ X {-1}}; X X Xvoid Xlocchg() X{ X if (dodwarf()) die(); X} X Xstatic void Xdohint(hint) register struct hint *hint; X{ X switch (hint-hints) { X case 4: if (O_GATE->prop != 0 || HERE(WALLET)) hint->lc = 0; X break; X case 5: if (DAM->prop != 0) hint->lc = 0; X break; X case 6: if (holding <= 1 || loc->atloc.link != NULL || X oldlc2->atloc.link != NULL || oldloc->atloc.link != NULL) X hint->lc = 0; X break; X } /* end of switch for special tests */ X if (hint->lc == 0) return; X hint->lc = 0; X if (!yes(hint->quest,0,54)) return; X printf("I am prepared to give you a hint, but it will cost you %d \ Xpoints.",hint->points); X hint->hinted = yes(175,hint->hmsg,54); X if (hint->hinted && limit>30) limit += 30*hint->points; X return; X} Xvoid Xbug(num) int num; X{ register long a; X (void) printf("\nFatal error number %d, see source code for\n\ Xinterpretation.\n",num); X a = *((long *) 1); X exit(1); X} X Xvoid Xmkill(monster,object) register struct monster *monster; X register struct cvobj *object; X{ X object->prop = 0; X move(object,loc); X object->conn2.where = FIXED ; X monster->dseen = FALSE ; X monster->dloc = DEAD ; X} X Xvoid Xshowroom() { X putcode(( !(loc->abb++ % abbnum) || (loc->sdesc == NULL)) X ? loc->ldesc : loc->sdesc); X} X Xvoid Xwhat(word) register int word; X{ if (word && PCT(60)) {rspeak(60); return;} X if (PCT(20)) {rspeak(61); return;} X rspeak(13); return; X} X Xstatic void Xcapchk(word) register char *word; X{ X if (!strcmp(word,"indian") X || !strcmp(word,"persian") X || !strcmp(word,"coke") X || !strcmp(word,"kobold") X || !strcmp(word,"balrog") X || !strcmp(word,"sears") X || !strcmp(word,"rick") ) X { *word = toupper(*word); X } X} X Xmain(argc, argv) Xint argc; Xchar * argv[]; X{ X { register int r; X if (!saved && argc == 2) { X cvinit(argc,argv); X exit(0); X } else if (argc != 1 || saved != 1) { X exit(1); X } X } X/********** X * do initialization (some of it just in case): X * set all objects X * nowhere (both ways) X * to their initial properties X * not linked to any location X * set all locations X * to get long message next X * to have flags = C_FORCED if there's a forced motion X ***********/ X { register struct cvobj *object; X for (object = &(cvobj[1]); object->desc != NULL ; object++ ) X { object->conn1.where = object->conn2.where = LOST ; X object->prop = object->iprop ; X object->conn1.link = object->conn2.link = NULL ; X object->conn1.who = object->conn2.who = object ; X object->conn1.where = object->conn2.where = LOST ; X } X lastobj = object - 1 ; X } X X { register struct cvloc *curloc; X X for (curloc = &cvloc[1]; curloc->travel != NULL; curloc++ ) X { register struct cvtrav *curtrv; X curloc->abb = 0; X curloc->atloc.link = NULL ; X curtrv = curloc->travel ; X if (curtrv->word == 1) X curloc->flags = C_FORCED ; X } X } X X/************ X * set up the location arrays to that objects are at their indicated X * places. We use drop, which puts things on the head of the list, so X * we run this backwards. Things with two locations are dropped twice, X * and since these are normally best described last, we do them first. X ************/ X { register struct cvobj *object; X#define ILOC(obj) (((obj)->iloc) ? (&(cvloc[(obj)->iloc])) : LOST ) X for (object = lastobj; ONUM(object); object--) X { if (object->iloc2 > 0 ) X { move2(object,&(cvloc[object->iloc2])); X move(object, ILOC(object) ); X } X } X X for (object = lastobj; ONUM(object); object-- ) X { if (object->iloc2 <= 0 ) X { move(object, ILOC(object) ); X object->conn2.where = object->iloc2 ? FIXED : LOST; X } X } X } X X/************************************************************************* X * clear the hint stuff. loc is how long he's been at a loc with the X * cond bit set. hinted is true if the hint has already been given. X *************************************************************************/ X { register struct hint *hint; X X for (hint = hints; hint->turns >= 0; ++hint) X { hint->lc = 0; X hint->hinted = FALSE ; X } X } X X/************************************************************************* X * initialize the monsters. X * they are all known generically as dwarves because they all move like X * dwarves, though the adventurer never really knows this. X * X * dloc is current location X * oloc is old location X * dseen is a flag. If on, this dwarf has the adventurer in sight and X * is in hot pursuit. X * dflag indicates the level of activity: X * 0 no monster stuff yet (wait until pool hall is reached) X * 1 no monsters met yet (thus, no axe) X * 2 have axe, but no knives yet. most dwarves moving. X * 3 first knives thrown (first set always miss) X * 3+ dwarves are mad (and thus more accurate) X * some dwarves don't look much like dwarves X * 1 is grendl the spider X * 2 is the dragon X * 3 is the king X * 4 is the djinni X * 5 is the kobold X * 6 is the bugbear X * 7 is the unicorn X * 8 is the giant orc X * 9 is the balrog X * 10-15 are just dwarves X * 16 is the pirate. X * 17 is *you* X * no two of the initial locations for 10-16 are adjacent. The others X * only start as part of a pre-set encounter. X *************************************************************************/ X X dflag = 0; X X { register struct monster *cre; X X for (cre = orcs ; (cre->iloc) != -1; cre++) { X cre->dloc = &cvloc[cre->iloc] ; X cre->dseen = FALSE ; X } X } X X/************************************************************************* X * 'tally' keeps track of how many treasures are yet to be found so we X * know when to close the cave. 'tally2' keeps track of how many can X * never be found because the adventurer klutzed out (e.g. lost the X * scroll in the maze). X * ***** tally2 is not yet implemented ***** X * the objects must be assigned numbers in the following order X * treasures X * end-game weapons X * artifacts in outer cave X * other objects X *************************************************************************/ X tally = tally2 = 0 ; X X { register struct cvobj *object; X for (object = MINTRS ; object != ENDTRS ; ++object ) { X object->prop = -1 ; X ++tally ; X } X } X X BATTER->prop = -1 ; X oldlc2 = X knfloc = LOST ; X X inorth = /* # of times he said NORTH instead of N */ X detail = /* # of times we said "not allowed . . */ X numdie = /* # of times he died so far */ X holding = /* # objects he's carrying */ X dkill = /* # of dwarves killed */ X turns = X nxtchr = 0; X X abbnum = 5 ; /* how often he gets long description */ X X clock1 = 30 ; /* time from last treasure to closing */ X clock2 = 50 ; /* time from closing to closed */ X X bonus = /* gets bonus for correct finish */ X closing = /* are we closing? */ X panic = /* has he panicked */ X closed = X gaveup = X scoring = X mltcmd = X samvrb = X finish = X lmwarn = FALSE ; X X { register int i; X for (i=0 ; i<=4; ++i) X if ( rmsg[2*i+81] != NULL ) maxdie = i+1 ; X } X X saved = saved == 1 ? -1 : 2 ; X/************************************************************************* X * OK, we're close now. Get a couple more things set. X *************************************************************************/ X demo = FALSE; /* everyone's a class 1 user here */ X motd(FALSE); /* message of the day? */ X hints[3].hinted = yes(65,1,0); /* instructions? */ X newloc = &(cvloc[1]) ; /* start here */ X oldloc = DEAD ; /* make lint happy */ X wzdark = FALSE ; X setup = 3 ; /* in full swing */ X limit = hints[3].hinted ? 1000 : 330 ; X juggl2(O_GATE); X juggle(BEAR); X juggle(HANG); X X/************************************************************************* X * begin the real stuff X *************************************************************************/ X X dodwarf(); X while (!finish) /* motion loop */ X { register struct cvobj *object; X int verb, oldvrb, obj ; X X blklin = TRUE ; X if (loc == DEAD) {die(); continue; } ; X if (FORCED(loc)) { X showroom(); X verb = 1; /* for the benefit of a later switch */ X } else { /* motion not forced */ X if (DARK) { X if (wzdark && PCT(35)) { X rspeak(23); X oldlc2 = loc; X {die(); continue; }; X } else rspeak(16); X } else { /* not dark: describe objects found here */ X register struct conn *curcon, *lastcon; X if (DARKRM) X pspeak(UNICRN,6); /* that must be the light */ X showroom(); X if (TOTING(BOAT)) pspeak(BOAT,BOAT->prop); X if (TOTING(RUG) && (RUG->prop == 1)) pspeak(RUG,1); X curcon = &(loc->atloc); X while (curcon->link != NULL) { X register struct cvobj *adobj; X register int i; X lastcon = curcon; X curcon = curcon->link ; X adobj = curcon->who ; X if (curcon->where != loc) bug(32); X if (adobj->prop < 0) { X adobj->prop = adobj->iprop; X if (IFTREAS(adobj)) --tally; X if ((tally == tally2) && tally) X limit = MIN(limit,35); X } X i = adobj->prop ; X/* handle special cases */ X/* tell about the inside of the gate, if the dummy's there */ X if ((adobj == O_GATE) X && (O_GATE->conn2.where == loc)) X i = 1; X/* funny way to tell what happened to the container */ X if (((adobj == CUP) || (adobj == BOTTLE)) X && (adobj->conn2.where == FIXED) X && (BEAR->prop == 0) X && (HERE(BEAR)) ) i = 13 ; X pspeak(adobj,i) ; X blklin = FALSE ; X/* seeing the poo close up means there are footprints in it */ X if (adobj == CRAP) adobj->prop = 1 ; X/* remove ranger from gate after the first time he's seen */ X if (adobj == RICK) { X RICK->prop++ ; X destry(RICK); X curcon = lastcon; X } X } /* end showing adobjs */ X } /* end describing objects here */ X goto okay; X X/* stuff for when you can't find the indicated object (it may be too dark) X*/ Xdark: ; X capchk(word1); /* capitalize some proper nouns */ X (void) printf("I see no %s here.\n",word1); X mltcmd = FALSE ; X/* loop here when you say "okay" and such -- less dangerous place than X * most, but still must watch the skeleton, the lamp, etc. X */ Xokay: ; X blklin = TRUE ; X/* if the skeleton's active, it can kill you */ X if (SKELTN->prop == 1) { X if (PCT(25)) { X rspeak(102); X oldlc2 = loc ; X {die(); continue; }; X } X rspeak(101); X } X Xmiss: if (TOTING(MEDAL) && (loc->flags & SECRET)) rspeak(112); X X if ((loc->flags & RANGER) X && (RICK->prop == 0) X && (DAM->prop == 0) X && (PCT(25) || (loc->atloc.link != NULL)) X ) { X pspeak(RICK,6); X RICK->prop = 3; X destry(RICK); X loc = &(cvloc[O_GATE->iloc]); X break; X } X X/* finds you hanging in there? */ X if ((LNUM(loc) == 144) && PCT(25)) { X rspeak(217) ; X if (PCT(50)) rspeak(218); X } X X/* when we don't understand, we come back here for a relatively safe retry. X */ Xhuh: oldvrb = verb ; X verb = 0; Xnewobj: obj = 0; X object = NULL ; X/* if he left off the verb, we let him come back here to say it. X */ Xgetvrb: ; X/* check if this place is eligible for any hints. If the sucker has been X * here long enough, perform the help section. X */ X { register struct hint *hint; X for (hint = hints+4; hint->turns != -1; ++hint) { X if (!(hint->hinted)) { X if (!(loc->flags & hint->bit)) hint->lc = -1 ; X ++(hint->lc); X if (hint->lc >= hint->turns) dohint(hint); X } X } X } /* end of hint block */ X X/* if closing this turn, check for any objects being toted with prop<0. X * set the prop to -1-prop. This way objects won't be described until X * they've been picked up and put down separate from their respective X * piles. Don't let any of this happen unless well into the cave. X */ X if (closed) { X register struct cvobj *adobj; X for (adobj=cvobj;adobj->desc != NULL; ++adobj) X if (TOTING(adobj) && (adobj->prop < 0)) X adobj->prop = -adobj->prop - 1; X } X X wzdark = DARK ; X X if ((knfloc != LOST) & (knfloc != loc)) knfloc = FIXED; X X/* get input */ X getin() ; /* set word1, word2 */ X X if (!(turns++) X && !strcmp("magic",word1) X && !strcmp("mode",word2) ) X { maint(argv[0]); } X X/* demo games are ended by the wizard */ X if (demo && (turns >= SHORT)) X { mspeak(1); X {finish = TRUE; continue; }; X } X X if (samvrb) verb = oldvrb ; X X if ((verb == SAY) && (word2 != NULL)) verb = 0 ; X if (verb == SAY) goto process ; X X/* detect closing, closed, etc */ X if ((LNUM(loc) >= 31) && !tally && !(--clock1)) X { register struct monster *cre; X X DOOR->prop = 0; X if (O_GATE->prop != 2) O_GATE->prop = 3; X for (cre = orcs; cre->iloc != -1; ++cre) X { cre->dloc = DEAD ; X cre->dseen = FALSE ; X } X if (BEAR->prop) destry(BEAR); X if (CHAIN->prop == 2) CHAIN->prop = 1; X AXE->prop = 0 ; X AXE->conn2.where = DEAD; X rspeak(129); X clock1 = -1; X closing = TRUE ; X } X X if (clock1 < 0 && !(--clock2)) X { register struct cvobj *curobj; X loc = oldloc = newloc = OFFICE ; X /* Put him there "naked" except for compass */ X for (curobj=cvobj; curobj->desc != NULL; ++curobj) { X if (TOTING(curobj) && curobj != COMPASS) X destry(curobj); X } X move(AXE,REPOS); X rspeak(132); X closed = TRUE; X {locchg(); continue; }; X } X X/* one way to get to the end of the game is for the lamp to give out. X * When it gets close, we warn him. If the lamp and fresh batteries are X * handy, we replace the batteries for him. Otherwise, he may be in X * trouble, depending on where he is. X */ X if ((LAMP->prop == 1) X && (--limit <= 30) X && HERE(BATTER) X && !(BATTER->prop) X && HERE(LAMP) ) X { rspeak(188); X BATTER->prop = 1 ; X if (TOTING(BATTER)) move(BATTER,loc) ; X limit += 500 ; X lmwarn = FALSE ; X } X X/* if lamp runs out */ X if (!limit) X { limit = -1; X LAMP->prop = 0 ; X if (HERE(LAMP)) rspeak(184) ; X } X X/* if it's dark and he's outside the cave proper, he just gives up */ X if ((limit < 0) && (LNUM(loc) <= 30)) X { rspeak(185) ; X gaveup = TRUE; X {finish = TRUE; continue; } ; X } X X/* give warning about dim lamp */ X if ((limit <= 30) && HERE(LAMP) && !lmwarn) X { lmwarn = TRUE ; X if ((BATTER->prop == 1) || (BATTER->conn1.where == LOST)) X rspeak(189); X else if (BATTER->prop == 0) X rspeak(183); X else X rspeak(187); X } X X/* now for the real work: we have to figure out what he means by what X * he just said. X */ X for ( ; word1 != NULL; word1=word2, word2=NULL) X { register int i; X X if (!strcmp(word1,"north")) X if (++inorth == 10) rspeak(17); X i = vocab(word1,-1); X if (i == -1) X { what(TRUE); /* some form of not understanding */ X goto huh; X } X/* if he says ENTER, he may not really go anywhere because of some special X * cases. Going into the water just gets him wet. Going into the boat X * is treated as "take boat", so we change his verb. X */ X if ((i == ENTER) X && (word2 != NULL)) X { if (!strcmp(word2,"stream") X || !strcmp(word2,"water") X || !strcmp(word2,"river") ) X { if (LIQLOC(loc) == _WATER) X rspeak(70); /* wet feet! */ X else X rspeak(43); /* Where? */ X goto okay ; /* maybe this should just be moved */ X } X else if (!strcmp(word2,"boat")) X { obj = _BOAT; X object = OBJ(obj) ; X i = TAKE; X } X } X X switch(i/1000) X { X/* this is one of the big holes in the parser here. Motion words are X * hardly checked for syntax at all. The object is usually not even X * looked at, if given. There are just a few special cases, and they X * do not go through the normal vocabulary stuff. X */ X case 0: /* motion word */ X if (obj || (verb && (verb != WALK))) X {what(FALSE); goto huh; } X if ((i == OUT) && (!strcmp(word2,"boat"))) X { i = DROP ; } /* deal with word ambiguity here */ X if (i == OUT X && TOTING(BOAT) X && (word2 == NULL || !strcmp(word2,"")) X && obj == 0) { X i = DROP ; X object = OBJ(obj = _BOAT); X } X verb = i ; /* this sets dispatch switch */ X break; X X/* for objects, we make sure that there are not two objects being named, X * and that the object is here. Also, if there's another word, we clear X * 'verb' which may have been set by the operation of 'samvrb'. X */ X case 1: /* object */ X oword = word1; X if (obj != i) X { if (obj X || (verb && (word2 != NULL))) X { what(FALSE); /* don't understand */ X goto huh; X } X } X object = OBJ(obj = i) ; X if (word2 != NULL) verb = 0; /* defeat samvrb */ X X if ((object->conn2.where != loc) X && !HERE(object)) /* object maybe not here */ X { register int flag; X flag = FALSE ; X if ((obj == _DWARF) && (dflag > 1)) X { register struct monster *cre; X for (cre = orcs; cre->iloc >= 0; ++cre) X { if (cre->dloc == loc) X { flag = TRUE ; X break; X } X } X } X if (flag X || (obj == LIQLOC(loc)) X || ((obj == LIQ(BOTTLE)) && HERE(BOTTLE)) X || ((obj == LIQ(CUP)) && HERE(CUP) ) X || ((object == SPIDER) X && (GRENDL->dloc == loc)) X || ((object == DRAGON) X && (PUFF->dloc == loc)) X || ((object == DJINN) X && (JEANNIE->dloc == loc)) X || ((object == KOBOLD) X && (SLASHER->dloc == loc)) X || ((object == BALROG) X && (BALLY->dloc == loc)) X || ((object == SELF) X && (ME->dloc == loc)) X ) X ; /* okay to keep going */ X else if ((object == KNIFE) X && (knfloc == loc)) X { knfloc = LOST; X rspeak(116); /* sorry about them knives */ X goto okay ; X } else if ((object == ROPE) X && (HERE(ROPE2))) X { object = ROPE2 ; X ; /* substitute the "other" rope */ X } else if ((object == ROPE) X && (HERE(EROPE))) X { object = EROPE ; X } else if ((object == ROPE) X && (HERE(EROPE2))) X { object = EROPE2; X } else if ( (word2 == NULL) X && ((verb == FIND) X || (verb == INVENT) X || (verb == DESCRB) X || (verb == TOUCH) ) ) X { ; /* allow questions about things not here */ X } else { X if (!verb && (word2 == NULL)) X /* this test is sensitive to verb funnies */ X { register int k; X if ((k=vocab(word1,3)) > 0) X { rspeak(k%1000); /* word has msg num */ X goto okay ; X } X } X goto dark; X } X } /* end of the case the object is not here */ X X if ((object == TOMB) && (HELM->prop)) X object = HELM ; /* actually a synonym */ X if (word2 != NULL) break; X if (verb) break ; X { register int k; X if ((k=vocab(word1,3)) >0) X { rspeak(k%1000); /* word has msg num in it */ X goto okay; X } X } X capchk(word1); /* capitialize some proper nouns */ X (void) printf( X"What do you want to do with the %s?",word1); X mltcmd = FALSE ; X goto getvrb ; X X case 2: /* action (verb) */ X vword = word1; X if ((verb == TAKE) X && ((i == INVENT) X || (i == verb))) X { verb = 0; /* destroy old verb */ X } X if (verb && !obj && (word2 == NULL)) X { what(FALSE); /* two verbs */ X goto huh; X } X if (word2 != NULL) {obj = 0 ; object = NULL ; } X verb = i; X if (word2 != NULL) X if (verb == SAY) X { obj = 1; X goto process; X } X break; X X case 3: /* special (just gets message) */ X verb = i ; /* this sets dispatch switch */ X break; X } /* end of word-type switch */ X } /* end of word analysis */ X X } /* end of getting new instructions (motion not forced) */ Xprocess: X switch (verb/1000) X { X case 0: /* motion verb */ X newloc = moveme(loc,verb) ; X locchg(); X continue ; X X case 2: /* true verb */ X if (verb == SAY) { X if (word2 != NULL) word1 = word2; X obj = vocab(word1,-1); /* what would happen? */ X if (obj == HOPE || obj == BANIS || obj == MISFO) { X verb = obj; obj = 0; object = NULL; X } else { X printf("Okay, \"%s\".\n",word1); X goto okay; X } X } X switch (cvact(verb,obj,object)) X { X case S_okay: goto okay; X case S_miss: goto miss; X case S_move: break; X case S_obj: goto newobj; X case S_what: *vword = toupper(*vword); X printf("%s what?\n",vword); X mltcmd = FALSE; X goto newobj; X case S_light: if (!DARK && wzdark) continue; X goto okay; X case S_show: continue; X case S_dark: goto dark; X default: bug(40); X } X locchg(); X continue; X X case 3: /* magic word */ X rspeak(verb%1000); X goto okay; X X default: /* how could this be? */ X bug(1); X } X } /* end of motion loop */ X X getscore(); X (void) printf("\nYou scored %d out of a possible %d, using %d turns.\n", X score,mxscore,turns); X { register struct cmsg *cmsg; X for (cmsg = ctext;cmsg->score != -1; ++cmsg) ; X for (--cmsg; cmsg - ctext; --cmsg) { X if (cmsg->score <= 0) cmsg->score += mxscore ; X if (cmsg->score <= score) break; X } X (void) fputs(cmsg->msg,stdout); X if ((cmsg+1)->score == -1) { X (void) fputs("To achieve the next higher rating would be a\ X neat trick!\n\n Congratulations!\n",stdout); X }else{ X (void) printf("To achieve the next higher rating, you need %d \ Xmore point%s.\n",(cmsg+1)->score - score, ((cmsg+1)->score - score > 1) ? X "s" : ""); X } X } /* end of figuring the appropriate message */ X X puts("\nTouch ENTER to continue.\n"); X { auto char answer[5]; X fgets(answer,4,stdin); X } X} END_OF_cvmain.c if test 23773 -ne `wc -c <cvmain.c`; then echo shar: \"cvmain.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f cvocab.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"cvocab.h\" else echo shar: Extracting \"cvocab.h\" \(4846 characters\) sed "s/^X//" >cvocab.h <<'END_OF_cvocab.h' X/* cvocab.h X * the crystal cave vocabulary X ************************************************************************/ X Xstruct cvocab { X int cvcode ; X char *cvword ; } ; X X#define NORTH 2 X#define NE 3 X#define EAST 4 X#define SE 5 X#define SOUTH 6 X#define SW 7 X#define WEST 8 X#define NW 9 X#define UP 10 X#define DOWN 11 X#define OUT 12 X#define IN 13 X#define ENTER 14 X#define JUMP 15 X#define BARN 16 X#define PRIVY 17 X#define SHAFT 18 X#define SINKH 19 X#define PIGPE 20 X#define BLUFF 21 X#define HEADQ 22 X#define M_GATE 23 X#define LAKE 24 X#define FIELD 25 X#define BACK 27 X#define WAIT 28 X#define CROSS 29 X#define HOPE 30 X#define UPSTR 31 X#define DOWNS 32 X#define CLIMB 33 X#define PATH 34 X#define PAST 35 X#define FUTUR 36 X#define BANIS 37 X#define MISFO 38 X X/* some objects */ X X#define MINTRS (&(cvobj[1])) X#define _JEWLRY 1003 X#define _CHEST 1005 X#define _CAPE 1006 X#define _CROWN 1007 X#define _SCEPT 1008 X#define _ORB 1010 X#define _IDOL 1011 X#define _RUG 1012 X#define _UNICRN 1013 X#define _CHAIN 1014 X#define _RING 1015 X#define _HELM 1016 X#define _THRONE 1018 X#define _SWORD 1019 X#define _HAMMER 1020 X#define _CUP 1021 X#define _MEDAL 1022 X#define _SCROLL 1023 X#define _HARP 1024 X#define _STONE 1025 X#define _KEG 1026 X#define ENDTRS OBJ(1027) X#define IFTREAS(o) ((o) < ENDTRS) X X#define MINWPN OBJ(1027) X#define MAXWPN OBJ(1034) X X#define MINART OBJ(1040) X#define _COLUMN 1040 X#define MAXART OBJ(1047) X X#define _COMPASS 1050 X#define _KEY 1051 X#define _LAMP 1052 X#define _RICK 1053 X#define _SEARS 1054 X#define _WALLET 1055 X#define _DOOR 1056 X#define _BRIDGE 1057 X#define _BOAT 1058 X#define _DAM 1059 X#define _O_GATE 1060 X#define _ROPE 1061 X#define _ROPE2 (_ROPE+1) X#define _EROPE (_ROPE+2) X#define _EROPE2 (_ROPE+3) X#define _SPICE 1067 X#define _KNIFE 1068 X#define _FOOD 1069 X#define _BOTTLE 1070 X#define _WATER 1071 X#define _WINE 1072 X#define _COLA 1073 X#define _MIRROR 1074 X#define _GIANT 1075 X#define _ORCS 1076 X#define _TOMB 1077 X#define _AXE 1078 X#define _TOAD 1079 X#define _SAND 1080 X#define _SHELF 1081 X#define _HANG 1082 X#define _CRAP 1086 X#define _SHOWER 1087 X#define _VEND 1088 X#define _BATTER 1089 X#define _DWARF 1090 X#define _BEAR 1091 X#define _SKELTN 1092 X#define _SPIDER 1093 X#define _DRAGON 1094 X#define _DJINN 1095 X#define _KOBOLD 1096 X#define _BALROG 1097 X#define _SELF 1098 X X/* verb section */ X X#define TAKE 2001 X#define DROP 2002 X#define ON 2003 X#define OFF 2004 X#define UNLOC 2005 X#define LOCK 2006 X#define SAY 2007 X#define RUB 2008 X#define FIND 2009 X#define INVENT 2010 X#define QUIT 2011 X#define SCORE 2012 X#define NOTHI 2013 X#define SAVE 2014 X#define BRIEF 2015 X/* HOURS not implemented */ X#define THROW 2017 X#define WALK 2018 X#define PAY 2019 X#define BREAK 2020 X#define DRINK 2021 X#define EAT 2022 X#define READ 2023 X#define TIE 2024 X#define UNTIE 2025 X#define FEED 2026 X#define POUR 2027 X#define KILL 2028 X#define RIG 2029 X#define CUT 2030 X#define FILL 2031 X#define TEST 2032 X#define BLAST 2033 X#define WAVE 2034 X#define SIT 2035 X#define CALM 2036 X#define FLY 2037 X#define WAKE 2038 X#define DESCRB 2039 X#define TOUCH 2040 X#define PLAY 2041 X#define RESTOR 2042 X#define HELP 2043 X X/* define object references */ X X#define OBJ(o) (&(cvobj[(o) % 1000])) X X#define JEWLRY OBJ(_JEWLRY) X#define CHEST OBJ(_CHEST) X#define CAPE OBJ(_CAPE) X#define CROWN OBJ(_CROWN) X#define SCEPT OBJ(_SCEPT) X#define ORB OBJ(_ORB) X#define IDOL OBJ(_IDOL) X#define RUG OBJ(_RUG) X#define UNICRN OBJ(_UNICRN) X#define CHAIN OBJ(_CHAIN) X#define RING OBJ(_RING) X#define HELM OBJ(_HELM) X#define THRONE OBJ(_THRONE) X#define SWORD OBJ(_SWORD) X#define HAMMER OBJ(_HAMMER) X#define CUP OBJ(_CUP) X#define MEDAL OBJ(_MEDAL) X#define SCROLL OBJ(_SCROLL) X#define HARP OBJ(_HARP) X#define STONE OBJ(_STONE) X#define KEG OBJ(_KEG) X#define COLUMN OBJ(_COLUMN) X#define COMPASS OBJ(_COMPASS) X#define KEY OBJ(_KEY) X#define LAMP OBJ(_LAMP) X#define RICK OBJ(_RICK) X#define SEARS OBJ(_SEARS) X#define WALLET OBJ(_WALLET) X#define DOOR OBJ(_DOOR) X#define BRIDGE OBJ(_BRIDGE) X#define BOAT OBJ(_BOAT) X#define DAM OBJ(_DAM) X#define O_GATE OBJ(_O_GATE) X#define ROPE OBJ(_ROPE) X#define ROPE2 OBJ(_ROPE2) X#define EROPE OBJ(_EROPE) X#define EROPE2 OBJ(_EROPE2) X#define SPICE OBJ(_SPICE) X#define KNIFE OBJ(_KNIFE) X#define FOOD OBJ(_FOOD) X#define BOTTLE OBJ(_BOTTLE) X#define WATER OBJ(_WATER) X#define WINE OBJ(_WINE) X#define COLA OBJ(_COLA) X#define MIRROR OBJ(_MIRROR) X#define GIANT OBJ(_GIANT) X#define ORCS OBJ(_ORCS) X#define TOMB OBJ(_TOMB) X#define AXE OBJ(_AXE) X#define TOAD OBJ(_TOAD) X#define SAND OBJ(_SAND) X#define SHELF OBJ(_SHELF) X#define HANG OBJ(_HANG) X#define CRAP OBJ(_CRAP) X#define SHOWER OBJ(_SHOWER) X#define VEND OBJ(_VEND) X#define BATTER OBJ(_BATTER) X#define DWARF OBJ(_DWARF) X#define BEAR OBJ(_BEAR) X#define SKELTN OBJ(_SKELTN) X#define SPIDER OBJ(_SPIDER) X#define DRAGON OBJ(_DRAGON) X#define DJINN OBJ(_DJINN) X#define KOBOLD OBJ(_KOBOLD) X#define BALROG OBJ(_BALROG) X#define SELF OBJ(_SELF) END_OF_cvocab.h if test 4846 -ne `wc -c <cvocab.h`; then echo shar: \"cvocab.h\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 3 \(of 5\). cp /dev/null ark3isdone 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