598 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			598 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /*	program ITVERB.C					*/
 | |
| 
 | |
| 
 | |
| #include	<stdio.h>
 | |
| #include	"advent.h"
 | |
| #include	"advdec.h"
 | |
| 
 | |
| _PROTOTYPE(void needobj, (void));
 | |
| _PROTOTYPE(void ivtake, (void));
 | |
| _PROTOTYPE(void ivopen, (void));
 | |
| _PROTOTYPE(void ivkill, (void));
 | |
| _PROTOTYPE(void ivdrink, (void));
 | |
| _PROTOTYPE(void ivquit, (void));
 | |
| _PROTOTYPE(void ivfoo, (void));
 | |
| _PROTOTYPE(void inventory, (void));
 | |
| _PROTOTYPE(void addobj, (int obj));
 | |
| _PROTOTYPE(void ivpour, (void));
 | |
| _PROTOTYPE(void ivfill, (void));
 | |
| _PROTOTYPE(void ivbrief, (void));
 | |
| _PROTOTYPE(void ivread, (void));
 | |
| _PROTOTYPE(void ivcombo, (void));
 | |
| _PROTOTYPE(void iveat, (void));
 | |
| /*
 | |
|   Routines to process intransitive verbs
 | |
| */
 | |
| void itverb()
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     newtravel = FALSE;
 | |
|     switch (verb) {
 | |
|     case DROP:
 | |
|     case SAY:
 | |
|     case WAVE:
 | |
|     case CALM:
 | |
|     case RUB:
 | |
|     case THROW:
 | |
|     case FIND:
 | |
|     case FEED:
 | |
|     case BREAK:
 | |
|     case WAKE:
 | |
|     case WEAR:
 | |
|     case HIT:
 | |
|     case DIAL:
 | |
|     case PLAY:
 | |
|     case PICK:
 | |
|     case PUT:
 | |
|     case TURN:		needobj();	break;
 | |
|     case TAKE:
 | |
|     case YANK:
 | |
|     case GET:
 | |
|     case INSRT:
 | |
|     case REMOVE:
 | |
|     case BURN:		ivtake();	break;
 | |
|     case OPEN:
 | |
|     case CLOSE:
 | |
|     case LOCK:
 | |
|     case UNLOCK:	ivopen();	break;
 | |
|     case NOTHING:	rspeak(54);	break;
 | |
|     case ON:
 | |
|     case OFF:		trverb();	break;
 | |
|     case WALK:		actspk(verb);	break;
 | |
|     case KILL:		ivkill();	break;
 | |
|     case POUR:		ivpour();	break;
 | |
|     case EAT:		iveat();	break;
 | |
|     case DRINK:		ivdrink();	break;
 | |
|     case QUIT:		ivquit();	break;
 | |
|     case INVENTORY:	inventory();	break;
 | |
|     case FILL:		ivfill();	break;
 | |
|     case BLAST:		ivblast();	break;
 | |
|     case SCORE:		score(TRUE);	break;
 | |
|     case FOO:		ivfoo();	break;
 | |
|     case BRIEF:		ivbrief();	break;
 | |
|     case READ:		ivread();	break;
 | |
|     case SUSPEND:
 | |
| 	if (g.closing)
 | |
| 	    rspeak(378);
 | |
| 	else
 | |
| 	    saveadv("advent.sav");
 | |
| 	break;
 | |
|     case RESTORE:	restore("advent.sav");	break;
 | |
|     case ANSWER:
 | |
| 	if ((g.loc != 189) || (g.prop[PHONE] != 0))
 | |
| 	    needobj();
 | |
| 	else {
 | |
| 	    object = PHONE;
 | |
| 	    itverb();
 | |
| 	}
 | |
| 	break;
 | |
|     case BLOW:		rspeak(268);	break;
 | |
| 	/* Action verb 'LEAVE' has no object */
 | |
|     case LEAVE:		bug(29);	break;
 | |
| 	/* Call if no phone is handy, yell. */
 | |
|     case YELL:
 | |
| 	if (!here(PHONE))
 | |
| 	    needobj();
 | |
| 	else if (!g.closed)
 | |
| 	    rspeak(271);
 | |
| 	else {
 | |
| 	    rspeak(283);
 | |
| 	    normend();
 | |
| 	}
 | |
| 	break;
 | |
| 	/* Health. give him a diagnosis. */
 | |
|     case HEALTH:
 | |
| 	if (g.numdie)
 | |
| 	    fprintf(stdout, "You have been killed %d times otherwise\n",
 | |
| 		    g.numdie);
 | |
| 	if (g.health >= 95) {
 | |
| 	    if (pct(50))
 | |
| 		rspeak(348);
 | |
| 	    else
 | |
| 		rspeak(349);
 | |
| 	} else {
 | |
| 	    fprintf(stdout,
 | |
| 	       "Your health rating is %2d out of a possible 100.\n",
 | |
| 		    g.health);
 | |
| 	    rspeak(381 + (100 - g.health) / 20);
 | |
| 	}
 | |
| 	break;
 | |
|     case LOOK:		ivlook();	break;
 | |
|     case COMBO:
 | |
| 	if (at(SAFE))
 | |
| 	    ivcombo();
 | |
| 	break;
 | |
|     case SWEEP:
 | |
| 	/* Dust/sweep */
 | |
| 	if (!at(CARVNG) || !athand(BRUSH) || (g.prop[CARVNG] == 1))
 | |
| 	    rspeak(342);
 | |
| 	else {
 | |
| 	    g.prop[CARVNG] = 1;
 | |
| 	    rspeak(363);
 | |
| 	    rspeak(372);
 | |
| 	}
 | |
| 	break;
 | |
|     case TERSE:
 | |
| 	/* Terse/unterse. supress all long_form descriptions. */
 | |
| 	g.terse = !g.terse;
 | |
| 	g.detail = 3;
 | |
| 	rspeak(54);
 | |
| 	break;
 | |
|     case WIZ:
 | |
| 	is_wiz = !is_wiz;
 | |
|     case MAP:
 | |
| 	rspeak(54);
 | |
| 	break;
 | |
|     case GATE:
 | |
| 	if (is_wiz) {
 | |
| 	    static char buf[INPUTBUFLEN];
 | |
| 	    sscanf(ask("Location ? ", buf, sizeof(buf)), "%d", &g.loc);
 | |
| 	}
 | |
| 	rspeak(54);
 | |
| 	break;
 | |
|     case PIRLOC:
 | |
| 	if (is_wiz) {
 | |
| 	    fprintf(stdout, "The dwarfs are at locations:\n");
 | |
| 	    for (i = 1; i < DWARFMAX; i++)
 | |
| 		fprintf(stdout, "  %4d", g.dloc[i]);
 | |
| 	    fprintf(stdout, "\nThe pirate is at location %4d\n",
 | |
| 		    g.dloc[DWARFMAX]);
 | |
| 	}
 | |
| 	rspeak(54);
 | |
| 	break;
 | |
|     default:
 | |
| 	printf("This intransitive not implemented yet\n");
 | |
|     }
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /*
 | |
|   Routine to indicate no reasonable
 | |
|   object for verb found.  Used mostly by
 | |
|   intransitive verbs.
 | |
| */
 | |
| void needobj()
 | |
| {
 | |
|     printf("%s what?\n", vtxt[vrbx]);
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /*
 | |
|   CARRY, TAKE etc.
 | |
| */
 | |
| void ivtake()
 | |
| {
 | |
|     int anobj, item;
 | |
| 
 | |
|     anobj = 0;
 | |
|     for (item = 1; item < MAXOBJ; ++item)
 | |
| 	if (g.place[item] == g.loc)
 | |
| 	    if (anobj == 0)
 | |
| 		anobj = item;
 | |
| 	    else {
 | |
| 		needobj();
 | |
| 		return;
 | |
| 	    }
 | |
| 
 | |
|     if (anobj == 0 || (dcheck() && g.dflag >= 2) || blind())
 | |
| 	needobj();
 | |
|     else {
 | |
| 	object = anobj;
 | |
| 	if (verb == YANK)
 | |
| 	    vyank();
 | |
| 	else if (verb == WEAR)
 | |
| 	    vwear();
 | |
| 	else
 | |
| 	    vtake();
 | |
|     }
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /*
 | |
|   OPEN, LOCK, UNLOCK
 | |
| */
 | |
| void ivopen()
 | |
| {
 | |
|     int obj_cnt, item;
 | |
| 
 | |
|     for (item = 1, obj_cnt = 0; item < MAXOBJ; item++) {
 | |
| 	if ((g.place[item] == g.loc) && (hinged(item))) {
 | |
| 	    object = item;
 | |
| 	    obj_cnt++;
 | |
| 	}
 | |
|     }
 | |
|     if (obj_cnt != 1)
 | |
| 	needobj();
 | |
|     else if (verb == LOCK)
 | |
| 	vlock();
 | |
|     else if (verb == UNLOCK)
 | |
| 	vunlock();
 | |
|     else if (verb == SHUT)
 | |
| 	vclose();
 | |
|     else
 | |
| 	vopen();
 | |
| }
 | |
| 
 | |
| /*
 | |
|   ATTACK, KILL etc
 | |
| */
 | |
| boolean previous_obj;
 | |
| 
 | |
| void ivkill()
 | |
| {
 | |
|     previous_obj = FALSE;
 | |
|     if (dcheck() && g.dflag >= 2)
 | |
| 	object = DWARF;
 | |
|     if (here(SNAKE))
 | |
| 	addobj(SNAKE);
 | |
|     if (at(DRAGON) && g.prop[DRAGON] == 0)
 | |
| 	addobj(DRAGON);
 | |
|     if (at(TROLL))
 | |
| 	addobj(TROLL);
 | |
|     if (here(GNOME))
 | |
| 	addobj(GNOME);
 | |
|     if (here(BEAR) && g.prop[BEAR] == 0)
 | |
| 	addobj(BEAR);
 | |
|     if (here(WUMPUS) && g.prop[WUMPUS] == 0)
 | |
| 	addobj(WUMPUS);
 | |
|     /* Can't attack bird by throwing axe */
 | |
|     if (here(BIRD) && verb != THROW)
 | |
| 	addobj(BIRD);
 | |
|     /* Clam and oyster both treated as clam for intransitive case; no
 | |
|        harm done. */
 | |
|     if (here(CLAM) || here(OYSTER))
 | |
| 	addobj(CLAM);
 | |
| 
 | |
|     if ((previous_obj) || (object == 0))
 | |
| 	rspeak(44);
 | |
|     else
 | |
| 	vkill();
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /*
 | |
|   POUR if no object, assume liq in container, if holding one.
 | |
| */
 | |
| void ivpour()
 | |
| {
 | |
|     if ((holding(BOTTLE)) && (liq(BOTTLE) != 0) && !holding(CASK))
 | |
| 	object = BOTTLE;
 | |
|     if ((holding(CASK)) && (liq(CASK) != 0) && !holding(BOTTLE))
 | |
| 	object = CASK;
 | |
| 
 | |
|     if (object == 0)
 | |
| 	needobj();
 | |
|     else
 | |
| 	trverb();
 | |
| }
 | |
| 
 | |
| /*
 | |
|   EAT. intransitive: assume edible if present, else ask what.
 | |
|   If he as more than one edible, or none, 'EAT' is ambiguous
 | |
|   without an explicit object.
 | |
| */
 | |
| void iveat()
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     previous_obj = FALSE;
 | |
|     for (i = 1; i < MAXOBJ; i++) {
 | |
| 	if ((here(i)) && (edible(i)))
 | |
| 	    addobj(i);
 | |
|     }
 | |
|     if ((previous_obj) || (object == 0))
 | |
| 	needobj();
 | |
|     else
 | |
| 	trverb();
 | |
| }
 | |
| 
 | |
| /*
 | |
|   DRINK.  If no object, assume water or wine and look for them here.
 | |
|   If potable is in bottle or cask, drink that.  If not, see if there
 | |
|   is something drinkable nearby (stream, lake, wine fountain, etc.),
 | |
|   and drink that.  If he has stuff in both containers, ask which.
 | |
| */
 | |
| void ivdrink()
 | |
| {
 | |
|     int ll;
 | |
| 
 | |
|     previous_obj = FALSE;
 | |
|     ll = liqloc(g.loc);
 | |
|     if ((ll == WATER) || (ll == WINE)) {
 | |
| 	object = ll;
 | |
| 	iobj = -1;
 | |
|     }
 | |
|     ll = liq(BOTTLE);
 | |
|     if ((athand(BOTTLE)) && ((ll == WATER) || (ll == WINE))) {
 | |
| 	object = ll;
 | |
| 	iobj = BOTTLE;
 | |
|     }
 | |
|     ll = liq(CASK);
 | |
|     if ((athand(CASK)) && ((ll == WATER) || (ll == WINE))
 | |
| 	&& iobj != BOTTLE) {
 | |
| 	object = ll;
 | |
| 	iobj = CASK;
 | |
|     } else
 | |
| 	object = 0;
 | |
| 
 | |
|     if (object == 0)
 | |
| 	needobj();
 | |
|     else
 | |
| 	trverb();
 | |
| }
 | |
| 
 | |
| /*
 | |
|   QUIT intransitive only. Verify intent and exit if that's what he wants
 | |
| */
 | |
| void ivquit()
 | |
| {
 | |
|     gaveup = yes(22, 54, 54);
 | |
|     if (gaveup)
 | |
| 	normend();
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /*
 | |
|   INVENTORY
 | |
| */
 | |
| void inventory()
 | |
| {
 | |
|     int i, msg;
 | |
|     boolean init_msg;
 | |
| 
 | |
|     init_msg = TRUE;
 | |
|     msg = 98;
 | |
|     for (i = 1; i < MAXOBJ; i++) {
 | |
| 	if (!holding(i) || wearng(i) || i == BEAR || i == BOAT)
 | |
| 	    continue;
 | |
| 	if (init_msg)
 | |
| 	    rspeak(99);
 | |
| 	pspeak(i, -1);
 | |
| 	init_msg = FALSE;
 | |
| 	msg = 0;
 | |
| 	lookin(i);
 | |
|     }
 | |
| 
 | |
|     /* Tell him what he is wearing */
 | |
|     init_msg = TRUE;
 | |
|     for (i = 1; i < MAXOBJ; i++) {
 | |
| 	if (wearng(i)) {
 | |
| 	    if (init_msg)
 | |
| 		fprintf(stdout, "\nYou are wearing:\n");
 | |
| 	    fprintf(stdout, "     ");
 | |
| 	    pspeak(i, -1);
 | |
| 	    msg = 0;
 | |
| 	    init_msg = FALSE;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     if (holding(BOAT)) {
 | |
| 	rspeak(221);
 | |
| 	lookin(BOAT);
 | |
|     }
 | |
|     if (holding(BEAR))
 | |
| 	msg = 141;
 | |
| 
 | |
|     if (msg)
 | |
| 	rspeak(msg);
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /*
 | |
|   FILL bottle or cask must be empty, and some liquid avaible
 | |
| */
 | |
| void ivfill()
 | |
| {
 | |
|     if ((g.prop[CASK] == 1) && !here(CASK))
 | |
| 	object = CASK;
 | |
|     if ((g.prop[BOTTLE] == 1) && !here(BOTTLE))
 | |
| 	object = BOTTLE;
 | |
| 
 | |
|     if ((here(BOTTLE) && here(CASK)) || (object == 0))
 | |
| 	needobj();
 | |
|     else
 | |
| 	trverb();
 | |
| }
 | |
| 
 | |
| /*
 | |
|   BLAST etc.
 | |
| */
 | |
| void ivblast()
 | |
| {
 | |
|     if (!g.closed)
 | |
| 	actspk(verb);
 | |
|     else {
 | |
| 	g.bonus = 135;
 | |
| 	if (g.place[ROD2] == 212 && g.loc == 116)
 | |
| 	    g.bonus = 133;
 | |
| 	if (g.place[ROD2] == 116 && g.loc != 116)
 | |
| 	    g.bonus = 134;
 | |
| 	rspeak(g.bonus);
 | |
| 	normend();
 | |
|     }
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /*
 | |
|   Handle fee fie foe foo...
 | |
| */
 | |
| void ivfoo()
 | |
| {
 | |
|     int k;
 | |
|     int msg;
 | |
| 
 | |
|     k = VAL(vocab(vtxt[vrbx], MISC));
 | |
|     if (g.foobar != 1 - k) {
 | |
| 	if (g.foobar == 0)
 | |
| 	    msg = 42;
 | |
| 	else
 | |
| 	    msg = 151;
 | |
| 	rspeak(msg);
 | |
| 	return;
 | |
|     }
 | |
|     g.foobar = k;
 | |
|     if (k != 4)
 | |
| 	return;
 | |
|     g.foobar = 0;
 | |
|     if (g.place[EGGS] == plac[EGGS] ||
 | |
| 	(toting(EGGS) && g.loc == plac[EGGS])) {
 | |
| 	rspeak(42);
 | |
| 	return;
 | |
|     }
 | |
|     /* Bring back troll if we steal the eggs back from him before
 | |
|        crossing */
 | |
|     if (g.place[EGGS] == 0 && g.place[TROLL] == 0 && g.prop[TROLL] == 0)
 | |
| 	g.prop[TROLL] = 1;
 | |
| 
 | |
|     if (here(EGGS))
 | |
| 	k = 1;
 | |
|     else if (g.loc == plac[EGGS])
 | |
| 	k = 0;
 | |
|     else
 | |
| 	k = 2;
 | |
|     move(EGGS, plac[EGGS]);
 | |
|     pspeak(EGGS, k);
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /*
 | |
|   brief/unbrief. intransitive only.
 | |
|   suppress long descriptions after first time.
 | |
| */
 | |
| void ivbrief()
 | |
| {
 | |
|     int msg;
 | |
| 
 | |
|     g.detail = 3;
 | |
|     g.terse = FALSE;
 | |
|     if (g.abbnum != 10000) {
 | |
| 	msg = 156;
 | |
| 	g.abbnum = 10000;
 | |
|     } else {
 | |
| 	msg = 374;
 | |
| 	g.abbnum = 5;
 | |
|     }
 | |
|     rspeak(msg);
 | |
| }
 | |
| 
 | |
| /*
 | |
|   read etc...
 | |
| */
 | |
| void ivread()
 | |
| {
 | |
|     previous_obj = FALSE;
 | |
|     if (here(BOOK))
 | |
| 	object = BOOK;
 | |
|     if (here(BOOK2))
 | |
| 	addobj(BOOK2);
 | |
|     if (here(BILLBD))
 | |
| 	addobj(BILLBD);
 | |
|     if (here(CARVNG))
 | |
| 	addobj(CARVNG);
 | |
|     if (here(MAGAZINE))
 | |
| 	addobj(MAGAZINE);
 | |
|     if (here(MESSAGE))
 | |
| 	addobj(MESSAGE);
 | |
|     if (here(OYSTER))
 | |
| 	addobj(OYSTER);
 | |
|     if (here(POSTER))
 | |
| 	addobj(POSTER);
 | |
|     if (here(TABLET))
 | |
| 	addobj(TABLET);
 | |
| 
 | |
|     if (previous_obj || object == 0 || dark())
 | |
| 	needobj();
 | |
|     else
 | |
| 	vread();
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /*
 | |
|    LOOK. can't give more detail. Pretend it wasn't dark (though it may "now"
 | |
|    be dark) so he won't fall into a pit staring into the gloom.
 | |
| */
 | |
| void ivlook()
 | |
| {
 | |
|     if (g.detail++ < 3)
 | |
| 	rspeak(15);
 | |
|     g.wzdark = FALSE;
 | |
|     g.visited[g.loc] = 0;
 | |
|     g.newloc = g.loc;
 | |
|     newtravel = TRUE;
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /*
 | |
|   COMBO: trying to open safe. (see comments for fee fie foe foo)
 | |
| */
 | |
| void ivcombo()
 | |
| {
 | |
|     int k, msg;
 | |
| 
 | |
|     k = VAL(vocab(vtxt[vrbx], MISC)) - 10;
 | |
|     msg = 42;
 | |
|     if (g.combo != 1 - k) {
 | |
| 	if (g.combo != 0)
 | |
| 	    msg = 366;
 | |
| 	rspeak(msg);
 | |
| 	return;
 | |
|     }
 | |
|     g.combo = k;
 | |
|     if (k != 3)
 | |
| 	rspeak(371);
 | |
|     else {
 | |
| 	g.combo = 0;
 | |
| 	bitoff(SAFE, LOCKBT);
 | |
| 	biton(SAFE, OPENBT);
 | |
| 	g.prop[SAFE] = 1;
 | |
| 	if (g.prop[BOOK] < 0) {
 | |
| 	    g.tally--;
 | |
| 	    g.prop[BOOK] = 0;
 | |
| 	    /* If remaining treasures too elusive, zap his lamp. this
 | |
| 	       duplicates some code, must be done here since book is
 | |
| 	       contained ins safe & tally stuff only works for thing
 | |
| 	       deposited at a location. */
 | |
| 	    if ((g.tally == g.tally2) && (g.tally != 0))
 | |
| 		g.limit = (g.limit < 35) ? g.limit : 35;
 | |
| 	}
 | |
| 	rspeak(365);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /*
 | |
|   ensure uniqueness as objects are searched
 | |
|   out for an intransitive verb
 | |
| */
 | |
| void addobj(obj)
 | |
| int obj;
 | |
| {
 | |
|     if (!previous_obj) {
 | |
| 	if (object != 0)
 | |
| 	    previous_obj = TRUE;
 | |
| 	else
 | |
| 	    object = obj;
 | |
|     }
 | |
|     return;
 | |
| }
 | 
