xref: /openbsd/games/battlestar/cypher.c (revision f3c23159)
1*f3c23159Sop /*	$OpenBSD: cypher.c,v 1.21 2022/08/08 17:57:05 op Exp $	*/
2df930be7Sderaadt /*	$NetBSD: cypher.c,v 1.3 1995/03/21 15:07:15 cgd Exp $	*/
3df930be7Sderaadt 
4df930be7Sderaadt /*
5df930be7Sderaadt  * Copyright (c) 1983, 1993
6df930be7Sderaadt  *	The Regents of the University of California.  All rights reserved.
7df930be7Sderaadt  *
8df930be7Sderaadt  * Redistribution and use in source and binary forms, with or without
9df930be7Sderaadt  * modification, are permitted provided that the following conditions
10df930be7Sderaadt  * are met:
11df930be7Sderaadt  * 1. Redistributions of source code must retain the above copyright
12df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer.
13df930be7Sderaadt  * 2. Redistributions in binary form must reproduce the above copyright
14df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer in the
15df930be7Sderaadt  *    documentation and/or other materials provided with the distribution.
167a09557bSmillert  * 3. Neither the name of the University nor the names of its contributors
17df930be7Sderaadt  *    may be used to endorse or promote products derived from this software
18df930be7Sderaadt  *    without specific prior written permission.
19df930be7Sderaadt  *
20df930be7Sderaadt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21df930be7Sderaadt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22df930be7Sderaadt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23df930be7Sderaadt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24df930be7Sderaadt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25df930be7Sderaadt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26df930be7Sderaadt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27df930be7Sderaadt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28df930be7Sderaadt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29df930be7Sderaadt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30df930be7Sderaadt  * SUCH DAMAGE.
31df930be7Sderaadt  */
32df930be7Sderaadt 
33ea24c44aSmestre #include <ctype.h>
34ea24c44aSmestre #include <err.h>
35ea24c44aSmestre #include <limits.h>
361a5bc921Sray #include <stdarg.h>
37ea24c44aSmestre #include <stdio.h>
38ea24c44aSmestre #include <stdlib.h>
39ea24c44aSmestre #include <string.h>
401a5bc921Sray 
4149d23a04Sderaadt #include "extern.h"
422e86f363Spjanzen #include "pathnames.h"
43df930be7Sderaadt 
44f3c3a9c6Smillert static void verb_with_all(unsigned int *, int, int (*)(void), const char *);
4576104c94Spjanzen 
461a5bc921Sray /*
471a5bc921Sray  * Prompt user to input an integer, which is stored in *value.
481a5bc921Sray  * On failure prints a warning, leaves *value untouched, and returns -1.
491a5bc921Sray  */
501a5bc921Sray int
getnum(int * value,const char * fmt,...)511a5bc921Sray getnum(int *value, const char *fmt, ...)
521a5bc921Sray {
531a5bc921Sray 	char buffer[BUFSIZ];
541a5bc921Sray 	va_list ap;
551a5bc921Sray 	const char *errstr;
561a5bc921Sray 	int n;
571a5bc921Sray 
581a5bc921Sray 	va_start(ap, fmt);
591a5bc921Sray 	vprintf(fmt, ap);
601a5bc921Sray 	fflush(stdout);
611a5bc921Sray 	va_end(ap);
621a5bc921Sray 
631a5bc921Sray 	if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
641a5bc921Sray 		warnx("error reading input");
651a5bc921Sray 		return (-1);
661a5bc921Sray 	}
671a5bc921Sray 	buffer[strcspn(buffer, "\n")] = '\0';
681a5bc921Sray 
691a5bc921Sray 	n = strtonum(buffer, INT_MIN, INT_MAX, &errstr);
701a5bc921Sray 	if (errstr) {
711a5bc921Sray 		warnx("number %s: %s", errstr, buffer);
721a5bc921Sray 		return (-1);
731a5bc921Sray 	}
741a5bc921Sray 	*value = n;
751a5bc921Sray 	return (0);
761a5bc921Sray }
771a5bc921Sray 
7876104c94Spjanzen /* returns 0 if error or no more commands to do,
7976104c94Spjanzen  *         1 if there are more commands remaining on the current input line
8076104c94Spjanzen  */
8149d23a04Sderaadt int
cypher(void)82ff8320a7Sderaadt cypher(void)
83df930be7Sderaadt {
84897c4254Spjanzen 	int     n;
85df930be7Sderaadt 	int     junk;
86df930be7Sderaadt 	int     lflag = -1;
87*f3c23159Sop 	char   *line = NULL, *filename;
88*f3c23159Sop 	size_t  linesize = 0;
89*f3c23159Sop 	ssize_t linelen;
90df930be7Sderaadt 
91df930be7Sderaadt 	while (wordnumber <= wordcount) {
9276104c94Spjanzen 		if (wordtype[wordnumber] != VERB &&
9376104c94Spjanzen 		    !(wordtype[wordnumber] == OBJECT &&
9476104c94Spjanzen 		    wordvalue[wordnumber] == KNIFE)) {
9576104c94Spjanzen 			printf("%s: How's that?\n",
9676104c94Spjanzen 			    (wordnumber == wordcount) ? words[wordnumber - 1] : words[wordnumber]);
9776104c94Spjanzen 			return (0);
9824df90aeSpjanzen 		}
9924df90aeSpjanzen 
100df930be7Sderaadt 		switch (wordvalue[wordnumber]) {
101df930be7Sderaadt 
10276104c94Spjanzen 		case AUXVERB:
10376104c94Spjanzen 			/* Take the following word as the verb */
10476104c94Spjanzen 			wordnumber++;
10576104c94Spjanzen 			return(cypher());
10676104c94Spjanzen 			break;
10776104c94Spjanzen 
108df930be7Sderaadt 		case UP:
10984f04a3eStedu 			if (location[position].access || tempwiz) {
110df930be7Sderaadt 				if (!location[position].access)
111df930be7Sderaadt 					puts("Zap!  A gust of wind lifts you up.");
112adfbbee1Spjanzen 				if (!moveplayer(location[position].up, AHEAD))
11376104c94Spjanzen 					return (0);
114df930be7Sderaadt 			} else {
1158b0a2b13Spjanzen 				puts("There is no way up.");
11676104c94Spjanzen 				return (0);
117df930be7Sderaadt 			}
118df930be7Sderaadt 			lflag = 0;
119df930be7Sderaadt 			break;
120df930be7Sderaadt 
121df930be7Sderaadt 		case DOWN:
122adfbbee1Spjanzen 			if (!moveplayer(location[position].down, AHEAD))
12376104c94Spjanzen 				return (0);
124df930be7Sderaadt 			lflag = 0;
125df930be7Sderaadt 			break;
126df930be7Sderaadt 
127df930be7Sderaadt 		case LEFT:
128adfbbee1Spjanzen 			if (!moveplayer(left, LEFT))
12976104c94Spjanzen 				return (0);
130df930be7Sderaadt 			lflag = 0;
131df930be7Sderaadt 			break;
132df930be7Sderaadt 
133df930be7Sderaadt 		case RIGHT:
134adfbbee1Spjanzen 			if (!moveplayer(right, RIGHT))
13576104c94Spjanzen 				return (0);
136df930be7Sderaadt 			lflag = 0;
137df930be7Sderaadt 			break;
138df930be7Sderaadt 
139df930be7Sderaadt 		case AHEAD:
140adfbbee1Spjanzen 			if (!moveplayer(ahead, AHEAD))
14176104c94Spjanzen 				return (0);
142df930be7Sderaadt 			lflag = 0;
143df930be7Sderaadt 			break;
144df930be7Sderaadt 
145df930be7Sderaadt 		case BACK:
146adfbbee1Spjanzen 			if (!moveplayer(back, BACK))
14776104c94Spjanzen 				return (0);
148df930be7Sderaadt 			lflag = 0;
149df930be7Sderaadt 			break;
150df930be7Sderaadt 
151df930be7Sderaadt 		case SHOOT:
15276104c94Spjanzen 			verb_with_all(location[position].objects, OBJ_PERSON,
15376104c94Spjanzen 			    shoot, "shoot at");
154df930be7Sderaadt 			break;
155df930be7Sderaadt 
156df930be7Sderaadt 		case TAKE:
157df930be7Sderaadt 			if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
1588b0a2b13Spjanzen 				int things;
1598b0a2b13Spjanzen 				things = 0;
160df930be7Sderaadt 				for (n = 0; n < NUMOFOBJECTS; n++)
1612e86f363Spjanzen 					if (TestBit(location[position].objects, n) && objsht[n]) {
1628b0a2b13Spjanzen 						things++;
163df930be7Sderaadt 						wordvalue[wordnumber + 1] = n;
164897c4254Spjanzen /* Some objects (type NOUNS) have special treatment in take().  For these
165897c4254Spjanzen  * we must set the type to NOUNS.  However for SWORD and BODY all it does
166897c4254Spjanzen  * is find which of many objects is meant, so we need do nothing here.
167897c4254Spjanzen  * BATHGOD must become NORMGOD as well.  NOUNS with no special case must be
168897c4254Spjanzen  * included here to get the right error.  DOOR cannot occur as an object so
169897c4254Spjanzen  * need not be included.
170897c4254Spjanzen  */
171897c4254Spjanzen 						switch (n) {
172897c4254Spjanzen 						case BATHGOD:
173897c4254Spjanzen 							wordvalue[wordnumber + 1] = NORMGOD;
1742e86f363Spjanzen 							/* FALLTHROUGH */
175897c4254Spjanzen 						case NORMGOD:
176897c4254Spjanzen 						case AMULET:
177897c4254Spjanzen 						case MEDALION:
178897c4254Spjanzen 						case TALISMAN:
179897c4254Spjanzen 						case MAN:
180897c4254Spjanzen 						case TIMER:
181897c4254Spjanzen 						case NATIVE:
18249d23a04Sderaadt 							wordtype[wordnumber + 1] = NOUNS;
183897c4254Spjanzen 							break;
184897c4254Spjanzen 						default:
185897c4254Spjanzen 							wordtype[wordnumber + 1] = OBJECT;
186897c4254Spjanzen 						}
187df930be7Sderaadt 						wordnumber = take(location[position].objects);
18876104c94Spjanzen 						wordnumber += 2;
189df930be7Sderaadt 					}
1908b0a2b13Spjanzen 				if (!things)
1918b0a2b13Spjanzen 					puts("Nothing to take!");
192897c4254Spjanzen 			} else
193df930be7Sderaadt 				take(location[position].objects);
194df930be7Sderaadt 			break;
195df930be7Sderaadt 
196df930be7Sderaadt 		case DROP:
197df930be7Sderaadt 			if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
1988b0a2b13Spjanzen 				int things;
1998b0a2b13Spjanzen 				things = 0;
200df930be7Sderaadt 				for (n = 0; n < NUMOFOBJECTS; n++)
2012e86f363Spjanzen 					if (TestBit(inven, n)) {
2028b0a2b13Spjanzen 						things++;
203df930be7Sderaadt 						wordvalue[wordnumber + 1] = n;
204df930be7Sderaadt 						wordnumber = drop("Dropped");
205df930be7Sderaadt 					}
206df930be7Sderaadt 				wordnumber++;
207df930be7Sderaadt 				wordnumber++;
2088b0a2b13Spjanzen 				if (!things)
2098b0a2b13Spjanzen 					puts("Nothing to drop!");
210897c4254Spjanzen 			} else
211df930be7Sderaadt 				drop("Dropped");
212df930be7Sderaadt 			break;
213df930be7Sderaadt 
214df930be7Sderaadt 
215df930be7Sderaadt 		case KICK:
216df930be7Sderaadt 		case THROW:
217df930be7Sderaadt 			if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
2188b0a2b13Spjanzen 				int things, wv;
2198b0a2b13Spjanzen 				things = 0;
2208b0a2b13Spjanzen 				wv = wordvalue[wordnumber];
221df930be7Sderaadt 				for (n = 0; n < NUMOFOBJECTS; n++)
2222e86f363Spjanzen 					if (TestBit(inven, n) ||
2232e86f363Spjanzen 					  (TestBit(location[position].objects, n) && objsht[n])) {
2248b0a2b13Spjanzen 						things++;
225df930be7Sderaadt 						wordvalue[wordnumber + 1] = n;
226df930be7Sderaadt 						wordnumber = throw(wordvalue[wordnumber] == KICK ? "Kicked" : "Thrown");
227df930be7Sderaadt 					}
228df930be7Sderaadt 				wordnumber += 2;
2298b0a2b13Spjanzen 				if (!things)
2308b0a2b13Spjanzen 					printf("Nothing to %s!\n", wv == KICK ? "kick" : "throw");
231df930be7Sderaadt 			} else
232df930be7Sderaadt 				throw(wordvalue[wordnumber] == KICK ? "Kicked" : "Thrown");
233df930be7Sderaadt 			break;
234df930be7Sderaadt 
235df930be7Sderaadt 		case TAKEOFF:
23676104c94Spjanzen 			verb_with_all(wear, 0, takeoff, "take off");
237df930be7Sderaadt 			break;
238df930be7Sderaadt 
239df930be7Sderaadt 		case DRAW:
24076104c94Spjanzen 			verb_with_all(wear, 0, draw, "draw");
241df930be7Sderaadt 			break;
242df930be7Sderaadt 
243df930be7Sderaadt 		case PUTON:
24476104c94Spjanzen 			verb_with_all(location[position].objects, 0, puton, "put on");
245df930be7Sderaadt 			break;
246df930be7Sderaadt 
247df930be7Sderaadt 		case WEARIT:
24876104c94Spjanzen 			verb_with_all(inven, 0, wearit, "wear");
249df930be7Sderaadt 			break;
250df930be7Sderaadt 
251df930be7Sderaadt 		case EAT:
25276104c94Spjanzen 			verb_with_all(inven, 0, eat, "eat");
253df930be7Sderaadt 			break;
254df930be7Sderaadt 
255df930be7Sderaadt 		case PUT:
256df930be7Sderaadt 			put();
257df930be7Sderaadt 			break;
258df930be7Sderaadt 
259df930be7Sderaadt 		case INVEN:
260df930be7Sderaadt 			if (ucard(inven)) {
261df930be7Sderaadt 				puts("You are holding:\n");
262df930be7Sderaadt 				for (n = 0; n < NUMOFOBJECTS; n++)
2632e86f363Spjanzen 					if (TestBit(inven, n))
264df930be7Sderaadt 						printf("\t%s\n", objsht[n]);
2659dbccdebSpjanzen 				printf("\n= %d kilogram%s ", carrying,
2669dbccdebSpjanzen 				    (carrying == 1 ?  "." : "s."));
2679dbccdebSpjanzen 				if (WEIGHT)
2689dbccdebSpjanzen 					printf("(%d%%)\n", carrying * 100 / WEIGHT);
2699dbccdebSpjanzen 				else
2709dbccdebSpjanzen 					printf("(can't lift any weight%s)\n",
2719dbccdebSpjanzen 					    (carrying ? " or move with what you have" : ""));
2729dbccdebSpjanzen 				if (CUMBER)
2739dbccdebSpjanzen 					printf("Your arms are %d%% full.\n",
2749dbccdebSpjanzen 					    encumber * 100 / CUMBER);
2759dbccdebSpjanzen 				else
2769dbccdebSpjanzen 					printf("You can't pick anything up.\n");
277897c4254Spjanzen 			} else
278df930be7Sderaadt 				puts("You aren't carrying anything.");
279df930be7Sderaadt 
280df930be7Sderaadt 			if (ucard(wear)) {
281df930be7Sderaadt 				puts("\nYou are wearing:\n");
282df930be7Sderaadt 				for (n = 0; n < NUMOFOBJECTS; n++)
2832e86f363Spjanzen 					if (TestBit(wear, n))
284df930be7Sderaadt 						printf("\t%s\n", objsht[n]);
285897c4254Spjanzen 			} else
286df930be7Sderaadt 				puts("\nYou are stark naked.");
287df930be7Sderaadt 			if (card(injuries, NUMOFINJURIES)) {
288df930be7Sderaadt 				puts("\nYou have suffered:\n");
289df930be7Sderaadt 				for (n = 0; n < NUMOFINJURIES; n++)
290df930be7Sderaadt 					if (injuries[n])
291df930be7Sderaadt 						printf("\t%s\n", ouch[n]);
292df930be7Sderaadt 				printf("\nYou can still carry up to %d kilogram%s\n", WEIGHT, (WEIGHT == 1 ? "." : "s."));
293897c4254Spjanzen 			} else
294df930be7Sderaadt 				puts("\nYou are in perfect health.");
295df930be7Sderaadt 			break;
296df930be7Sderaadt 
297df930be7Sderaadt 		case USE:
298df930be7Sderaadt 			lflag = use();
299df930be7Sderaadt 			break;
300df930be7Sderaadt 
3018b0a2b13Spjanzen 		case OPEN:
3028b0a2b13Spjanzen 			dooropen();
3038b0a2b13Spjanzen 			break;
3048b0a2b13Spjanzen 
305df930be7Sderaadt 		case LOOK:
3062e86f363Spjanzen 			if (!notes[CANTSEE] || TestBit(inven, LAMPON) ||
3072e86f363Spjanzen 			    TestBit(location[position].objects, LAMPON)
308897c4254Spjanzen 			    || matchlight) {
309df930be7Sderaadt 				beenthere[position] = 2;
310df930be7Sderaadt 				writedes();
311df930be7Sderaadt 				printobjs();
312df930be7Sderaadt 				if (matchlight) {
313df930be7Sderaadt 					puts("\nYour match splutters out.");
314df930be7Sderaadt 					matchlight = 0;
315df930be7Sderaadt 				}
316df930be7Sderaadt 			} else
317df930be7Sderaadt 				puts("I can't see anything.");
31876104c94Spjanzen 			return (0);	/* No commands after a look */
319df930be7Sderaadt 			break;
320df930be7Sderaadt 
321df930be7Sderaadt 		case SU:
32284f04a3eStedu 			if (tempwiz) {
3231a5bc921Sray 				getnum(&position, "\nRoom (was %d) = ", position);
3241a5bc921Sray 				getnum(&ourtime, "Time (was %d) = ", ourtime);
3251a5bc921Sray 				getnum(&fuel, "Fuel (was %d) = ", fuel);
3261a5bc921Sray 				getnum(&torps, "Torps (was %d) = ", torps);
3271a5bc921Sray 				getnum(&CUMBER, "CUMBER (was %d) = ", CUMBER);
3281a5bc921Sray 				getnum(&WEIGHT, "WEIGHT (was %d) = ", WEIGHT);
3291a5bc921Sray 				getnum(&ourclock, "Clock (was %d) = ", ourclock);
33084f04a3eStedu 				if (getnum(&junk, "Wizard (was %d) = ", tempwiz) != -1 && !junk)
33184f04a3eStedu 					tempwiz = 0;
332df930be7Sderaadt 				printf("\nDONE.\n");
33376104c94Spjanzen 				return (0);	/* No commands after a SU */
334897c4254Spjanzen 			} else
335df930be7Sderaadt 				puts("You aren't a wizard.");
336df930be7Sderaadt 			break;
337df930be7Sderaadt 
338df930be7Sderaadt 		case SCORE:
339df930be7Sderaadt 			printf("\tPLEASURE\tPOWER\t\tEGO\n");
340df930be7Sderaadt 			printf("\t%3d\t\t%3d\t\t%3d\n\n", pleasure, power, ego);
341897c4254Spjanzen 			printf("This gives you the rating of %s in %d turns.\n", rate(), ourtime);
342df930be7Sderaadt 			printf("You have visited %d out of %d rooms this run (%d%%).\n", card(beenthere, NUMOFROOMS), NUMOFROOMS, card(beenthere, NUMOFROOMS) * 100 / NUMOFROOMS);
343df930be7Sderaadt 			break;
344df930be7Sderaadt 
34576104c94Spjanzen 		/* case KNIFE: */
346df930be7Sderaadt 		case KILL:
347df930be7Sderaadt 			murder();
348df930be7Sderaadt 			break;
349df930be7Sderaadt 
350df930be7Sderaadt 		case UNDRESS:
35176104c94Spjanzen 			undress();
35276104c94Spjanzen 			break;
35376104c94Spjanzen 
354df930be7Sderaadt 		case RAVAGE:
355df930be7Sderaadt 			ravage();
356df930be7Sderaadt 			break;
357df930be7Sderaadt 
358df930be7Sderaadt 		case SAVE:
3592e86f363Spjanzen 			printf("\nSave file name (default %s):  ",
3602e86f363Spjanzen 			    DEFAULT_SAVE_FILE);
361*f3c23159Sop 			linelen = getline(&line, &linesize, stdin);
362*f3c23159Sop 			if (linelen == -1 || *line == '\n')
363*f3c23159Sop 				filename = save_file_name(DEFAULT_SAVE_FILE);
3642e86f363Spjanzen 			else {
365*f3c23159Sop 				if (line[linelen - 1] == '\n')
366*f3c23159Sop 					line[linelen - 1] = '\0';
367*f3c23159Sop 				filename = save_file_name(line);
3682e86f363Spjanzen 			}
369*f3c23159Sop 			save(filename);
370*f3c23159Sop 			free(filename);
371df930be7Sderaadt 			break;
372df930be7Sderaadt 
3738b0a2b13Spjanzen 		case VERBOSE:
3748b0a2b13Spjanzen 			verbose = 1;
3758b0a2b13Spjanzen 			printf("[Maximum verbosity]\n");
3768b0a2b13Spjanzen 			break;
3778b0a2b13Spjanzen 
3788b0a2b13Spjanzen 		case BRIEF:
3798b0a2b13Spjanzen 			verbose = 0;
3808b0a2b13Spjanzen 			printf("[Standard verbosity]\n");
3818b0a2b13Spjanzen 			break;
3828b0a2b13Spjanzen 
383df930be7Sderaadt 		case FOLLOW:
384df930be7Sderaadt 			lflag = follow();
385df930be7Sderaadt 			break;
386df930be7Sderaadt 
387df930be7Sderaadt 		case GIVE:
388df930be7Sderaadt 			give();
389df930be7Sderaadt 			break;
390df930be7Sderaadt 
391df930be7Sderaadt 		case KISS:
392df930be7Sderaadt 			kiss();
393df930be7Sderaadt 			break;
394df930be7Sderaadt 
395df930be7Sderaadt 		case LOVE:
396df930be7Sderaadt 			love();
397df930be7Sderaadt 			break;
398df930be7Sderaadt 
399df930be7Sderaadt 		case RIDE:
400df930be7Sderaadt 			lflag = ride();
401df930be7Sderaadt 			break;
402df930be7Sderaadt 
403df930be7Sderaadt 		case DRIVE:
404df930be7Sderaadt 			lflag = drive();
405df930be7Sderaadt 			break;
406df930be7Sderaadt 
407df930be7Sderaadt 		case LIGHT:
408df930be7Sderaadt 			light();
409df930be7Sderaadt 			break;
410df930be7Sderaadt 
411df930be7Sderaadt 		case LAUNCH:
412df930be7Sderaadt 			if (!launch())
41376104c94Spjanzen 				return (0);
414df930be7Sderaadt 			else
415df930be7Sderaadt 				lflag = 0;
416df930be7Sderaadt 			break;
417df930be7Sderaadt 
418df930be7Sderaadt 		case LANDIT:
419df930be7Sderaadt 			if (!land())
42076104c94Spjanzen 				return (0);
421df930be7Sderaadt 			else
422df930be7Sderaadt 				lflag = 0;
423df930be7Sderaadt 			break;
424df930be7Sderaadt 
425df930be7Sderaadt 		case TIME:
426df930be7Sderaadt 			chime();
427df930be7Sderaadt 			break;
428df930be7Sderaadt 
429df930be7Sderaadt 		case SLEEP:
430df930be7Sderaadt 			zzz();
431df930be7Sderaadt 			break;
432df930be7Sderaadt 
433df930be7Sderaadt 		case DIG:
434df930be7Sderaadt 			dig();
435df930be7Sderaadt 			break;
436df930be7Sderaadt 
437df930be7Sderaadt 		case JUMP:
438df930be7Sderaadt 			lflag = jump();
439df930be7Sderaadt 			break;
440df930be7Sderaadt 
441df930be7Sderaadt 		case BURY:
442df930be7Sderaadt 			bury();
443df930be7Sderaadt 			break;
444df930be7Sderaadt 
445df930be7Sderaadt 		case SWIM:
446df930be7Sderaadt 			puts("Surf's up!");
447df930be7Sderaadt 			break;
448df930be7Sderaadt 
449df930be7Sderaadt 		case DRINK:
450df930be7Sderaadt 			drink();
451df930be7Sderaadt 			break;
452df930be7Sderaadt 
453df930be7Sderaadt 		case QUIT:
4543565abd9Sangelos 			die(0);
455df930be7Sderaadt 
456df930be7Sderaadt 		default:
457df930be7Sderaadt 			puts("How's that?");
45876104c94Spjanzen 			return (0);
459df930be7Sderaadt 			break;
460df930be7Sderaadt 
461df930be7Sderaadt 		}
46276104c94Spjanzen 		if (!lflag)
46376104c94Spjanzen 			newlocation();
464*f3c23159Sop 
465*f3c23159Sop 		free(line);
466*f3c23159Sop 
46776104c94Spjanzen 		if (wordnumber < wordcount && !stop_cypher &&
46876104c94Spjanzen 		    (*words[wordnumber] == ',' || *words[wordnumber] == '.')) {
46976104c94Spjanzen 			wordnumber++;
47076104c94Spjanzen 			return (1);
47176104c94Spjanzen 		} else
47276104c94Spjanzen 			return (0);
473df930be7Sderaadt 	}
47476104c94Spjanzen 	return (0);
47576104c94Spjanzen }
47676104c94Spjanzen 
47776104c94Spjanzen int
inc_wordnumber(const char * v,const char * adv)478ff8320a7Sderaadt inc_wordnumber(const char *v, const char *adv)
47976104c94Spjanzen {
48076104c94Spjanzen 	wordnumber++;
48176104c94Spjanzen 	if (wordnumber >= wordcount) {
48201869f28Smmcc 		printf("%c%s %s?\n",
48301869f28Smmcc 		    toupper((unsigned char)v[0]), v + 1, adv);
48476104c94Spjanzen 		return(-1);
48576104c94Spjanzen 	}
48676104c94Spjanzen 	return(0);
48776104c94Spjanzen }
48876104c94Spjanzen 
48976104c94Spjanzen static void
verb_with_all(unsigned int * testarray,int objflg,int (* verbfunc)(void),const char * verbname)490ff8320a7Sderaadt verb_with_all(unsigned int *testarray, int objflg, int (*verbfunc)(void),
491ff8320a7Sderaadt               const char *verbname)
49276104c94Spjanzen {
49376104c94Spjanzen 	int things, n;
49476104c94Spjanzen 
49576104c94Spjanzen 	things = 0;
49676104c94Spjanzen 	if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
49776104c94Spjanzen 		for (n = 0; n < NUMOFOBJECTS; n++)
49876104c94Spjanzen 			if (TestBit(testarray, n) &&
49976104c94Spjanzen 			    (objsht[n] || (objflg & objflags[n]))) {
50076104c94Spjanzen 				things++;
50176104c94Spjanzen 				wordvalue[wordnumber + 1] = n;
50276104c94Spjanzen 				/* Assume it's a NOUN if no short description */
50376104c94Spjanzen 				if (objsht[n])
50476104c94Spjanzen 					wordtype[wordnumber + 1] = OBJECT;
50576104c94Spjanzen 				else
50676104c94Spjanzen 					wordtype[wordnumber + 1] = NOUNS;
50776104c94Spjanzen 				wordnumber = verbfunc();
50876104c94Spjanzen 			}
50976104c94Spjanzen 		wordnumber += 2;
51076104c94Spjanzen 		if (!things)
51176104c94Spjanzen 			printf("Nothing to %s!\n", verbname);
51276104c94Spjanzen 	} else
51376104c94Spjanzen 		verbfunc();
514df930be7Sderaadt }
515