main.c revision 1.24 1 1.24 dholland /* $NetBSD: main.c,v 1.24 2009/08/12 08:04:05 dholland Exp $ */
2 1.11 christos
3 1.11 christos /* main.c */
4 1.11 christos #include <sys/cdefs.h>
5 1.3 mycroft #ifndef lint
6 1.24 dholland __RCSID("$NetBSD: main.c,v 1.24 2009/08/12 08:04:05 dholland Exp $");
7 1.11 christos #endif /* not lint */
8 1.3 mycroft
9 1.1 cgd #include <sys/types.h>
10 1.11 christos #include <stdio.h>
11 1.1 cgd #include <pwd.h>
12 1.11 christos #include <unistd.h>
13 1.11 christos #include <stdlib.h>
14 1.7 cgd #include <string.h>
15 1.11 christos #include "header.h"
16 1.11 christos #include "extern.h"
17 1.7 cgd
18 1.24 dholland static void showstr(void);
19 1.24 dholland static void t_setup(int);
20 1.24 dholland static void t_endup(int);
21 1.24 dholland static void showwear(void);
22 1.24 dholland static void showwield(void);
23 1.24 dholland static void showread(void);
24 1.24 dholland static void showeat(void);
25 1.24 dholland static void showquaff(void);
26 1.24 dholland static void show1(int, const char *[]);
27 1.24 dholland static void randmonst(void);
28 1.24 dholland static void parse(void);
29 1.24 dholland static void run(int);
30 1.24 dholland static void wield(void);
31 1.24 dholland static void ydhi(int);
32 1.24 dholland static void ycwi(int);
33 1.24 dholland static void wear(void);
34 1.24 dholland static void dropobj(void);
35 1.24 dholland static void readscr(void);
36 1.24 dholland static void eatcookie(void);
37 1.24 dholland static void quaff(void);
38 1.22 dholland static int whatitem(const char *);
39 1.22 dholland
40 1.11 christos static char copyright[] = "\nLarn is copyrighted 1986 by Noah Morgan.\n";
41 1.11 christos int srcount = 0; /* line counter for showstr() */
42 1.11 christos int dropflag = 0; /* if 1 then don't lookforobject() next round */
43 1.11 christos int rmst = 80; /* random monster creation counter */
44 1.11 christos int userid; /* the players login user id number */
45 1.21 dholland gid_t gid, egid; /* used for security */
46 1.11 christos u_char nowelcome = 0, nomove = 0; /* if (nomove) then don't
47 1.11 christos * count next iteration as a
48 1.11 christos * move */
49 1.11 christos static char viewflag = 0;
50 1.11 christos /*
51 1.11 christos * if viewflag then we have done a 99 stay here and don't showcell in the
52 1.11 christos * main loop
53 1.11 christos */
54 1.11 christos u_char restorflag = 0; /* 1 means restore has been done */
55 1.11 christos static char cmdhelp[] = "\
56 1.12 mikel Cmd line format: larn [-slicnh] [-o<optsfile>] [-##] [++]\n\
57 1.1 cgd -s show the scoreboard\n\
58 1.1 cgd -l show the logfile (wizard id only)\n\
59 1.1 cgd -i show scoreboard with inventories of dead characters\n\
60 1.1 cgd -c create new scoreboard (wizard id only)\n\
61 1.1 cgd -n suppress welcome message on starting game\n\
62 1.1 cgd -## specify level of difficulty (example: -5)\n\
63 1.1 cgd -h print this help text\n\
64 1.1 cgd ++ restore game from checkpoint file\n\
65 1.1 cgd -o<optsfile> specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
66 1.1 cgd ";
67 1.1 cgd #ifdef VT100
68 1.11 christos static char *termtypes[] = {"vt100", "vt101", "vt102", "vt103", "vt125",
69 1.1 cgd "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
70 1.11 christos "vt341"};
71 1.11 christos #endif /* VT100 */
72 1.1 cgd /*
73 1.1 cgd ************
74 1.1 cgd MAIN PROGRAM
75 1.1 cgd ************
76 1.1 cgd */
77 1.11 christos int
78 1.11 christos main(argc, argv)
79 1.11 christos int argc;
80 1.11 christos char **argv;
81 1.11 christos {
82 1.11 christos int i;
83 1.11 christos int hard;
84 1.13 mycroft const char *ptr = 0;
85 1.11 christos struct passwd *pwe;
86 1.1 cgd
87 1.15 blymn i = 0;
88 1.21 dholland egid = getegid();
89 1.21 dholland gid = getgid();
90 1.21 dholland setegid(gid); /* give up "games" if we have it */
91 1.11 christos /*
92 1.11 christos * first task is to identify the player
93 1.11 christos */
94 1.1 cgd #ifndef VT100
95 1.11 christos init_term(); /* setup the terminal (find out what type)
96 1.11 christos * for termcap */
97 1.11 christos #endif /* VT100 */
98 1.14 veego /* try to get login name */
99 1.14 veego if (((ptr = getlogin()) == 0) || (*ptr == 0)) {
100 1.14 veego /* can we get it from /etc/passwd? */
101 1.14 veego if ((pwe = getpwuid(getuid())) != NULL)
102 1.11 christos ptr = pwe->pw_name;
103 1.11 christos else if ((ptr = getenv("USER")) == 0)
104 1.11 christos if ((ptr = getenv("LOGNAME")) == 0) {
105 1.11 christos noone: write(2, "Can't find your logname. Who Are You?\n", 39);
106 1.11 christos exit(1);
107 1.11 christos }
108 1.14 veego }
109 1.11 christos if (ptr == 0)
110 1.11 christos goto noone;
111 1.11 christos if (strlen(ptr) == 0)
112 1.11 christos goto noone;
113 1.11 christos /*
114 1.11 christos * second task is to prepare the pathnames the player will need
115 1.11 christos */
116 1.11 christos strcpy(loginname, ptr); /* save loginname of the user for logging
117 1.11 christos * purposes */
118 1.11 christos strcpy(logname, ptr); /* this will be overwritten with the players
119 1.11 christos * name */
120 1.11 christos if ((ptr = getenv("HOME")) == NULL)
121 1.11 christos ptr = ".";
122 1.1 cgd strcpy(savefilename, ptr);
123 1.11 christos strcat(savefilename, "/Larn.sav"); /* save file name in home
124 1.11 christos * directory */
125 1.16 christos snprintf(optsfile, sizeof(optsfile), "%s/.larnopts", ptr);
126 1.16 christos /* the .larnopts filename */
127 1.11 christos
128 1.11 christos /*
129 1.11 christos * now malloc the memory for the dungeon
130 1.11 christos */
131 1.11 christos cell = (struct cel *) malloc(sizeof(struct cel) * (MAXLEVEL + MAXVLEVEL) * MAXX * MAXY);
132 1.11 christos if (cell == 0)
133 1.11 christos died(-285); /* malloc failure */
134 1.11 christos lpbuf = malloc((5 * BUFBIG) >> 2); /* output buffer */
135 1.11 christos inbuffer = malloc((5 * MAXIBUF) >> 2); /* output buffer */
136 1.11 christos if ((lpbuf == 0) || (inbuffer == 0))
137 1.11 christos died(-285); /* malloc() failure */
138 1.11 christos
139 1.11 christos lcreat((char *) 0);
140 1.11 christos newgame(); /* set the initial clock */
141 1.11 christos hard = -1;
142 1.1 cgd
143 1.1 cgd #ifdef VT100
144 1.11 christos /*
145 1.11 christos * check terminal type to avoid users who have not vt100 type terminals
146 1.11 christos */
147 1.1 cgd ttype = getenv("TERM");
148 1.11 christos for (j = 1, i = 0; i < sizeof(termtypes) / sizeof(char *); i++)
149 1.11 christos if (strcmp(ttype, termtypes[i]) == 0) {
150 1.11 christos j = 0;
151 1.11 christos break;
152 1.1 cgd }
153 1.11 christos if (j) {
154 1.17 snj lprcat("Sorry, Larn needs a VT100 family terminal for all its features.\n");
155 1.11 christos lflush();
156 1.11 christos exit(1);
157 1.11 christos }
158 1.11 christos #endif /* VT100 */
159 1.11 christos
160 1.11 christos /*
161 1.11 christos * now make scoreboard if it is not there (don't clear)
162 1.11 christos */
163 1.11 christos if (access(scorefile, 0) == -1) /* not there */
164 1.1 cgd makeboard();
165 1.1 cgd
166 1.11 christos /*
167 1.11 christos * now process the command line arguments
168 1.11 christos */
169 1.11 christos for (i = 1; i < argc; i++) {
170 1.1 cgd if (argv[i][0] == '-')
171 1.11 christos switch (argv[i][1]) {
172 1.11 christos case 's':
173 1.11 christos showscores();
174 1.11 christos exit(0); /* show scoreboard */
175 1.11 christos
176 1.11 christos case 'l': /* show log file */
177 1.11 christos diedlog();
178 1.11 christos exit(0);
179 1.11 christos
180 1.11 christos case 'i':
181 1.11 christos showallscores();
182 1.11 christos exit(0); /* show all scoreboard */
183 1.11 christos
184 1.11 christos case 'c': /* anyone with password can create
185 1.11 christos * scoreboard */
186 1.11 christos lprcat("Preparing to initialize the scoreboard.\n");
187 1.11 christos if (getpassword() != 0) { /* make new scoreboard */
188 1.11 christos makeboard();
189 1.11 christos lprc('\n');
190 1.11 christos showscores();
191 1.11 christos }
192 1.11 christos exit(0);
193 1.1 cgd
194 1.11 christos case 'n': /* no welcome msg */
195 1.11 christos nowelcome = 1;
196 1.11 christos argv[i][0] = 0;
197 1.11 christos break;
198 1.11 christos
199 1.11 christos case '0':
200 1.11 christos case '1':
201 1.11 christos case '2':
202 1.11 christos case '3':
203 1.11 christos case '4':
204 1.11 christos case '5':
205 1.11 christos case '6':
206 1.11 christos case '7':
207 1.11 christos case '8':
208 1.11 christos case '9': /* for hardness */
209 1.11 christos sscanf(&argv[i][1], "%d", &hard);
210 1.11 christos break;
211 1.1 cgd
212 1.1 cgd case 'h': /* print out command line arguments */
213 1.11 christos write(1, cmdhelp, sizeof(cmdhelp));
214 1.11 christos exit(0);
215 1.1 cgd
216 1.1 cgd case 'o': /* specify a .larnopts filename */
217 1.11 christos strncpy(optsfile, argv[i] + 2, 127);
218 1.11 christos break;
219 1.1 cgd
220 1.11 christos default:
221 1.11 christos printf("Unknown option <%s>\n", argv[i]);
222 1.11 christos exit(1);
223 1.1 cgd };
224 1.1 cgd
225 1.11 christos if (argv[i][0] == '+') {
226 1.11 christos clear();
227 1.11 christos restorflag = 1;
228 1.11 christos if (argv[i][1] == '+') {
229 1.11 christos hitflag = 1;
230 1.11 christos restoregame(ckpfile); /* restore checkpointed
231 1.11 christos * game */
232 1.11 christos }
233 1.1 cgd i = argc;
234 1.1 cgd }
235 1.11 christos }
236 1.1 cgd
237 1.1 cgd readopts(); /* read the options file if there is one */
238 1.1 cgd
239 1.1 cgd
240 1.1 cgd #ifdef UIDSCORE
241 1.1 cgd userid = geteuid(); /* obtain the user's effective id number */
242 1.11 christos #else /* UIDSCORE */
243 1.1 cgd userid = getplid(logname); /* obtain the players id number */
244 1.11 christos #endif /* UIDSCORE */
245 1.11 christos if (userid < 0) {
246 1.11 christos write(2, "Can't obtain playerid\n", 22);
247 1.11 christos exit(1);
248 1.11 christos }
249 1.1 cgd #ifdef HIDEBYLINK
250 1.11 christos /*
251 1.11 christos * this section of code causes the program to look like something else to ps
252 1.11 christos */
253 1.11 christos if (strcmp(psname, argv[0])) { /* if a different process name only */
254 1.11 christos if ((i = access(psname, 1)) < 0) { /* link not there */
255 1.11 christos if (link(argv[0], psname) >= 0) {
256 1.11 christos argv[0] = psname;
257 1.11 christos execv(psname, argv);
258 1.1 cgd }
259 1.11 christos } else
260 1.1 cgd unlink(psname);
261 1.11 christos }
262 1.11 christos for (i = 1; i < argc; i++) {
263 1.1 cgd szero(argv[i]); /* zero the argument to avoid ps snooping */
264 1.11 christos }
265 1.11 christos #endif /* HIDEBYLINK */
266 1.1 cgd
267 1.11 christos if (access(savefilename, 0) == 0) { /* restore game if need to */
268 1.11 christos clear();
269 1.11 christos restorflag = 1;
270 1.11 christos hitflag = 1;
271 1.11 christos restoregame(savefilename); /* restore last game */
272 1.11 christos }
273 1.11 christos sigsetup(); /* trap all needed signals */
274 1.11 christos sethard(hard); /* set up the desired difficulty */
275 1.11 christos setupvt100(); /* setup the terminal special mode */
276 1.11 christos if (c[HP] == 0) { /* create new game */
277 1.11 christos makeplayer(); /* make the character that will play */
278 1.11 christos newcavelevel(0);/* make the dungeon */
279 1.11 christos predostuff = 1; /* tell signals that we are in the welcome
280 1.11 christos * screen */
281 1.11 christos if (nowelcome == 0)
282 1.11 christos welcome(); /* welcome the player to the game */
283 1.11 christos }
284 1.11 christos drawscreen(); /* show the initial dungeon */
285 1.11 christos predostuff = 2; /* tell the trap functions that they must do
286 1.11 christos * a showplayer() from here on */
287 1.11 christos #if 0
288 1.11 christos nice(1); /* games should be run niced */
289 1.11 christos #endif
290 1.1 cgd yrepcount = hit2flag = 0;
291 1.11 christos while (1) {
292 1.11 christos if (dropflag == 0)
293 1.11 christos lookforobject(); /* see if there is an object
294 1.11 christos * here */
295 1.11 christos else
296 1.11 christos dropflag = 0; /* don't show it just dropped an item */
297 1.11 christos if (hitflag == 0) {
298 1.11 christos if (c[HASTEMONST])
299 1.11 christos movemonst();
300 1.11 christos movemonst();
301 1.11 christos } /* move the monsters */
302 1.11 christos if (viewflag == 0)
303 1.11 christos showcell(playerx, playery);
304 1.11 christos else
305 1.11 christos viewflag = 0; /* show stuff around player */
306 1.11 christos if (hit3flag)
307 1.11 christos flushall();
308 1.11 christos hitflag = hit3flag = 0;
309 1.11 christos nomove = 1;
310 1.1 cgd bot_linex(); /* update bottom line */
311 1.11 christos while (nomove) {
312 1.11 christos if (hit3flag)
313 1.11 christos flushall();
314 1.11 christos nomove = 0;
315 1.11 christos parse();
316 1.11 christos } /* get commands and make moves */
317 1.11 christos regen(); /* regenerate hp and spells */
318 1.11 christos if (c[TIMESTOP] == 0)
319 1.11 christos if (--rmst <= 0) {
320 1.11 christos rmst = 120 - (level << 2);
321 1.11 christos fillmonst(makemonst(level));
322 1.11 christos }
323 1.1 cgd }
324 1.11 christos }
325 1.11 christos
326 1.11 christos
327 1.1 cgd /*
328 1.1 cgd showstr()
329 1.1 cgd
330 1.1 cgd show character's inventory
331 1.1 cgd */
332 1.24 dholland static void
333 1.1 cgd showstr()
334 1.11 christos {
335 1.11 christos int i, number;
336 1.11 christos for (number = 3, i = 0; i < 26; i++)
337 1.11 christos if (iven[i])
338 1.11 christos number++; /* count items in inventory */
339 1.11 christos t_setup(number);
340 1.11 christos qshowstr();
341 1.11 christos t_endup(number);
342 1.11 christos }
343 1.1 cgd
344 1.11 christos void
345 1.1 cgd qshowstr()
346 1.11 christos {
347 1.11 christos int i, j, k, sigsav;
348 1.11 christos srcount = 0;
349 1.11 christos sigsav = nosignal;
350 1.11 christos nosignal = 1; /* don't allow ^c etc */
351 1.11 christos if (c[GOLD]) {
352 1.19 dholland lprintf(".) %ld gold pieces", (long) c[GOLD]);
353 1.11 christos srcount++;
354 1.11 christos }
355 1.11 christos for (k = 26; k >= 0; k--)
356 1.11 christos if (iven[k]) {
357 1.11 christos for (i = 22; i < 84; i++)
358 1.11 christos for (j = 0; j <= k; j++)
359 1.11 christos if (i == iven[j])
360 1.11 christos show3(j);
361 1.11 christos k = 0;
362 1.11 christos }
363 1.19 dholland lprintf("\nElapsed time is %ld. You have %ld mobuls left", (long) ((gltime + 99) / 100 + 1), (long) ((TIMELIMIT - gltime) / 100));
364 1.11 christos more();
365 1.11 christos nosignal = sigsav;
366 1.11 christos }
367 1.1 cgd
368 1.1 cgd /*
369 1.1 cgd * subroutine to clear screen depending on # lines to display
370 1.1 cgd */
371 1.24 dholland static void
372 1.1 cgd t_setup(count)
373 1.11 christos int count;
374 1.11 christos {
375 1.11 christos if (count < 20) { /* how do we clear the screen? */
376 1.11 christos cl_up(79, count);
377 1.11 christos cursor(1, 1);
378 1.11 christos } else {
379 1.11 christos resetscroll();
380 1.11 christos clear();
381 1.1 cgd }
382 1.11 christos }
383 1.1 cgd
384 1.1 cgd /*
385 1.1 cgd * subroutine to restore normal display screen depending on t_setup()
386 1.1 cgd */
387 1.24 dholland static void
388 1.1 cgd t_endup(count)
389 1.11 christos int count;
390 1.11 christos {
391 1.11 christos if (count < 18) /* how did we clear the screen? */
392 1.11 christos draws(0, MAXX, 0, (count > MAXY) ? MAXY : count);
393 1.11 christos else {
394 1.11 christos drawscreen();
395 1.11 christos setscroll();
396 1.1 cgd }
397 1.11 christos }
398 1.1 cgd
399 1.1 cgd /*
400 1.1 cgd function to show the things player is wearing only
401 1.1 cgd */
402 1.24 dholland static void
403 1.1 cgd showwear()
404 1.11 christos {
405 1.11 christos int i, j, sigsav, count;
406 1.11 christos sigsav = nosignal;
407 1.11 christos nosignal = 1; /* don't allow ^c etc */
408 1.11 christos srcount = 0;
409 1.11 christos
410 1.11 christos for (count = 2, j = 0; j <= 26; j++) /* count number of items we
411 1.11 christos * will display */
412 1.11 christos if ((i = iven[j]) != 0)
413 1.11 christos switch (i) {
414 1.11 christos case OLEATHER:
415 1.11 christos case OPLATE:
416 1.11 christos case OCHAIN:
417 1.11 christos case ORING:
418 1.11 christos case OSTUDLEATHER:
419 1.11 christos case OSPLINT:
420 1.11 christos case OPLATEARMOR:
421 1.11 christos case OSSPLATE:
422 1.11 christos case OSHIELD:
423 1.11 christos count++;
424 1.1 cgd };
425 1.1 cgd
426 1.1 cgd t_setup(count);
427 1.1 cgd
428 1.11 christos for (i = 22; i < 84; i++)
429 1.11 christos for (j = 0; j <= 26; j++)
430 1.11 christos if (i == iven[j])
431 1.11 christos switch (i) {
432 1.11 christos case OLEATHER:
433 1.11 christos case OPLATE:
434 1.11 christos case OCHAIN:
435 1.11 christos case ORING:
436 1.11 christos case OSTUDLEATHER:
437 1.11 christos case OSPLINT:
438 1.11 christos case OPLATEARMOR:
439 1.11 christos case OSSPLATE:
440 1.11 christos case OSHIELD:
441 1.11 christos show3(j);
442 1.1 cgd };
443 1.11 christos more();
444 1.11 christos nosignal = sigsav;
445 1.11 christos t_endup(count);
446 1.11 christos }
447 1.1 cgd
448 1.1 cgd /*
449 1.11 christos function to show the things player can wield only
450 1.1 cgd */
451 1.24 dholland static void
452 1.1 cgd showwield()
453 1.11 christos {
454 1.11 christos int i, j, sigsav, count;
455 1.11 christos sigsav = nosignal;
456 1.11 christos nosignal = 1; /* don't allow ^c etc */
457 1.11 christos srcount = 0;
458 1.11 christos
459 1.11 christos for (count = 2, j = 0; j <= 26; j++) /* count how many items */
460 1.11 christos if ((i = iven[j]) != 0)
461 1.11 christos switch (i) {
462 1.11 christos case ODIAMOND:
463 1.11 christos case ORUBY:
464 1.11 christos case OEMERALD:
465 1.11 christos case OSAPPHIRE:
466 1.11 christos case OBOOK:
467 1.11 christos case OCHEST:
468 1.11 christos case OLARNEYE:
469 1.11 christos case ONOTHEFT:
470 1.11 christos case OSPIRITSCARAB:
471 1.11 christos case OCUBEofUNDEAD:
472 1.11 christos case OPOTION:
473 1.11 christos case OSCROLL:
474 1.11 christos break;
475 1.11 christos default:
476 1.11 christos count++;
477 1.1 cgd };
478 1.1 cgd
479 1.1 cgd t_setup(count);
480 1.1 cgd
481 1.11 christos for (i = 22; i < 84; i++)
482 1.11 christos for (j = 0; j <= 26; j++)
483 1.11 christos if (i == iven[j])
484 1.11 christos switch (i) {
485 1.11 christos case ODIAMOND:
486 1.11 christos case ORUBY:
487 1.11 christos case OEMERALD:
488 1.11 christos case OSAPPHIRE:
489 1.11 christos case OBOOK:
490 1.11 christos case OCHEST:
491 1.11 christos case OLARNEYE:
492 1.11 christos case ONOTHEFT:
493 1.11 christos case OSPIRITSCARAB:
494 1.11 christos case OCUBEofUNDEAD:
495 1.11 christos case OPOTION:
496 1.11 christos case OSCROLL:
497 1.11 christos break;
498 1.11 christos default:
499 1.11 christos show3(j);
500 1.1 cgd };
501 1.11 christos more();
502 1.11 christos nosignal = sigsav;
503 1.11 christos t_endup(count);
504 1.11 christos }
505 1.1 cgd
506 1.1 cgd /*
507 1.1 cgd * function to show the things player can read only
508 1.1 cgd */
509 1.24 dholland static void
510 1.1 cgd showread()
511 1.11 christos {
512 1.11 christos int i, j, sigsav, count;
513 1.11 christos sigsav = nosignal;
514 1.11 christos nosignal = 1; /* don't allow ^c etc */
515 1.11 christos srcount = 0;
516 1.11 christos
517 1.11 christos for (count = 2, j = 0; j <= 26; j++)
518 1.11 christos switch (iven[j]) {
519 1.11 christos case OBOOK:
520 1.11 christos case OSCROLL:
521 1.11 christos count++;
522 1.11 christos };
523 1.1 cgd t_setup(count);
524 1.1 cgd
525 1.11 christos for (i = 22; i < 84; i++)
526 1.11 christos for (j = 0; j <= 26; j++)
527 1.11 christos if (i == iven[j])
528 1.11 christos switch (i) {
529 1.11 christos case OBOOK:
530 1.11 christos case OSCROLL:
531 1.11 christos show3(j);
532 1.1 cgd };
533 1.11 christos more();
534 1.11 christos nosignal = sigsav;
535 1.11 christos t_endup(count);
536 1.11 christos }
537 1.1 cgd
538 1.1 cgd /*
539 1.1 cgd * function to show the things player can eat only
540 1.1 cgd */
541 1.24 dholland static void
542 1.1 cgd showeat()
543 1.11 christos {
544 1.11 christos int i, j, sigsav, count;
545 1.11 christos sigsav = nosignal;
546 1.11 christos nosignal = 1; /* don't allow ^c etc */
547 1.11 christos srcount = 0;
548 1.11 christos
549 1.11 christos for (count = 2, j = 0; j <= 26; j++)
550 1.11 christos switch (iven[j]) {
551 1.11 christos case OCOOKIE:
552 1.11 christos count++;
553 1.11 christos };
554 1.1 cgd t_setup(count);
555 1.1 cgd
556 1.11 christos for (i = 22; i < 84; i++)
557 1.11 christos for (j = 0; j <= 26; j++)
558 1.11 christos if (i == iven[j])
559 1.11 christos switch (i) {
560 1.11 christos case OCOOKIE:
561 1.11 christos show3(j);
562 1.1 cgd };
563 1.11 christos more();
564 1.11 christos nosignal = sigsav;
565 1.11 christos t_endup(count);
566 1.11 christos }
567 1.1 cgd
568 1.1 cgd /*
569 1.1 cgd function to show the things player can quaff only
570 1.1 cgd */
571 1.24 dholland static void
572 1.1 cgd showquaff()
573 1.11 christos {
574 1.11 christos int i, j, sigsav, count;
575 1.11 christos sigsav = nosignal;
576 1.11 christos nosignal = 1; /* don't allow ^c etc */
577 1.11 christos srcount = 0;
578 1.11 christos
579 1.11 christos for (count = 2, j = 0; j <= 26; j++)
580 1.11 christos switch (iven[j]) {
581 1.11 christos case OPOTION:
582 1.11 christos count++;
583 1.11 christos };
584 1.1 cgd t_setup(count);
585 1.1 cgd
586 1.11 christos for (i = 22; i < 84; i++)
587 1.11 christos for (j = 0; j <= 26; j++)
588 1.11 christos if (i == iven[j])
589 1.11 christos switch (i) {
590 1.11 christos case OPOTION:
591 1.11 christos show3(j);
592 1.1 cgd };
593 1.11 christos more();
594 1.11 christos nosignal = sigsav;
595 1.11 christos t_endup(count);
596 1.11 christos }
597 1.1 cgd
598 1.24 dholland static void
599 1.11 christos show1(idx, str2)
600 1.11 christos int idx;
601 1.20 dholland const char *str2[];
602 1.11 christos {
603 1.11 christos lprintf("\n%c) %s", idx + 'a', objectname[iven[idx]]);
604 1.11 christos if (str2 != 0 && str2[ivenarg[idx]][0] != 0)
605 1.11 christos lprintf(" of%s", str2[ivenarg[idx]]);
606 1.11 christos }
607 1.1 cgd
608 1.11 christos void
609 1.20 dholland show3(int indx)
610 1.11 christos {
611 1.20 dholland switch (iven[indx]) {
612 1.11 christos case OPOTION:
613 1.20 dholland show1(indx, potionname);
614 1.11 christos break;
615 1.11 christos case OSCROLL:
616 1.20 dholland show1(indx, scrollname);
617 1.11 christos break;
618 1.11 christos
619 1.11 christos case OLARNEYE:
620 1.11 christos case OBOOK:
621 1.11 christos case OSPIRITSCARAB:
622 1.11 christos case ODIAMOND:
623 1.11 christos case ORUBY:
624 1.11 christos case OCUBEofUNDEAD:
625 1.11 christos case OEMERALD:
626 1.11 christos case OCHEST:
627 1.11 christos case OCOOKIE:
628 1.11 christos case OSAPPHIRE:
629 1.11 christos case ONOTHEFT:
630 1.20 dholland show1(indx, NULL);
631 1.11 christos break;
632 1.11 christos
633 1.11 christos default:
634 1.20 dholland lprintf("\n%c) %s", indx + 'a', objectname[iven[indx]]);
635 1.20 dholland if (ivenarg[indx] > 0)
636 1.20 dholland lprintf(" + %ld", (long) ivenarg[indx]);
637 1.20 dholland else if (ivenarg[indx] < 0)
638 1.20 dholland lprintf(" %ld", (long) ivenarg[indx]);
639 1.11 christos break;
640 1.11 christos }
641 1.20 dholland if (c[WIELD] == indx)
642 1.11 christos lprcat(" (weapon in hand)");
643 1.20 dholland if ((c[WEAR] == indx) || (c[SHIELD] == indx))
644 1.11 christos lprcat(" (being worn)");
645 1.11 christos if (++srcount >= 22) {
646 1.11 christos srcount = 0;
647 1.11 christos more();
648 1.11 christos clear();
649 1.1 cgd }
650 1.11 christos }
651 1.1 cgd
652 1.1 cgd /*
653 1.1 cgd subroutine to randomly create monsters if needed
654 1.1 cgd */
655 1.24 dholland static void
656 1.1 cgd randmonst()
657 1.11 christos {
658 1.11 christos if (c[TIMESTOP])
659 1.11 christos return; /* don't make monsters if time is stopped */
660 1.11 christos if (--rmst <= 0) {
661 1.11 christos rmst = 120 - (level << 2);
662 1.11 christos fillmonst(makemonst(level));
663 1.1 cgd }
664 1.11 christos }
665 1.11 christos
666 1.11 christos
667 1.1 cgd
668 1.1 cgd /*
669 1.1 cgd parse()
670 1.1 cgd
671 1.1 cgd get and execute a command
672 1.1 cgd */
673 1.24 dholland static void
674 1.1 cgd parse()
675 1.11 christos {
676 1.11 christos int i, j, k, flag;
677 1.11 christos while (1) {
678 1.1 cgd k = yylex();
679 1.11 christos switch (k) { /* get the token from the input and switch on
680 1.11 christos * it */
681 1.11 christos case 'h':
682 1.11 christos moveplayer(4);
683 1.11 christos return; /* west */
684 1.11 christos case 'H':
685 1.11 christos run(4);
686 1.11 christos return; /* west */
687 1.11 christos case 'l':
688 1.11 christos moveplayer(2);
689 1.11 christos return; /* east */
690 1.11 christos case 'L':
691 1.11 christos run(2);
692 1.11 christos return; /* east */
693 1.11 christos case 'j':
694 1.11 christos moveplayer(1);
695 1.11 christos return; /* south */
696 1.11 christos case 'J':
697 1.11 christos run(1);
698 1.11 christos return; /* south */
699 1.11 christos case 'k':
700 1.11 christos moveplayer(3);
701 1.11 christos return; /* north */
702 1.11 christos case 'K':
703 1.11 christos run(3);
704 1.11 christos return; /* north */
705 1.11 christos case 'u':
706 1.11 christos moveplayer(5);
707 1.11 christos return; /* northeast */
708 1.11 christos case 'U':
709 1.11 christos run(5);
710 1.11 christos return; /* northeast */
711 1.11 christos case 'y':
712 1.11 christos moveplayer(6);
713 1.11 christos return; /* northwest */
714 1.11 christos case 'Y':
715 1.11 christos run(6);
716 1.11 christos return; /* northwest */
717 1.11 christos case 'n':
718 1.11 christos moveplayer(7);
719 1.11 christos return; /* southeast */
720 1.11 christos case 'N':
721 1.11 christos run(7);
722 1.11 christos return; /* southeast */
723 1.11 christos case 'b':
724 1.11 christos moveplayer(8);
725 1.11 christos return; /* southwest */
726 1.11 christos case 'B':
727 1.11 christos run(8);
728 1.11 christos return; /* southwest */
729 1.11 christos
730 1.11 christos case '.':
731 1.11 christos if (yrepcount)
732 1.11 christos viewflag = 1;
733 1.11 christos return; /* stay here */
734 1.11 christos
735 1.11 christos case 'w':
736 1.11 christos yrepcount = 0;
737 1.11 christos wield();
738 1.11 christos return; /* wield a weapon */
739 1.11 christos
740 1.11 christos case 'W':
741 1.11 christos yrepcount = 0;
742 1.11 christos wear();
743 1.11 christos return; /* wear armor */
744 1.11 christos
745 1.11 christos case 'r':
746 1.11 christos yrepcount = 0;
747 1.11 christos if (c[BLINDCOUNT]) {
748 1.11 christos cursors();
749 1.11 christos lprcat("\nYou can't read anything when you're blind!");
750 1.11 christos } else if (c[TIMESTOP] == 0)
751 1.11 christos readscr();
752 1.11 christos return; /* to read a scroll */
753 1.11 christos
754 1.11 christos case 'q':
755 1.11 christos yrepcount = 0;
756 1.11 christos if (c[TIMESTOP] == 0)
757 1.11 christos quaff();
758 1.11 christos return; /* quaff a potion */
759 1.11 christos
760 1.11 christos case 'd':
761 1.11 christos yrepcount = 0;
762 1.11 christos if (c[TIMESTOP] == 0)
763 1.11 christos dropobj();
764 1.11 christos return; /* to drop an object */
765 1.11 christos
766 1.11 christos case 'c':
767 1.11 christos yrepcount = 0;
768 1.11 christos cast();
769 1.11 christos return; /* cast a spell */
770 1.11 christos
771 1.11 christos case 'i':
772 1.11 christos yrepcount = 0;
773 1.11 christos nomove = 1;
774 1.11 christos showstr();
775 1.11 christos return; /* status */
776 1.11 christos
777 1.11 christos case 'e':
778 1.11 christos yrepcount = 0;
779 1.11 christos if (c[TIMESTOP] == 0)
780 1.11 christos eatcookie();
781 1.11 christos return; /* to eat a fortune cookie */
782 1.11 christos
783 1.11 christos case 'D':
784 1.11 christos yrepcount = 0;
785 1.11 christos seemagic(0);
786 1.11 christos nomove = 1;
787 1.11 christos return; /* list spells and scrolls */
788 1.11 christos
789 1.11 christos case '?':
790 1.11 christos yrepcount = 0;
791 1.11 christos help();
792 1.11 christos nomove = 1;
793 1.11 christos return; /* give the help screen */
794 1.11 christos
795 1.11 christos case 'S':
796 1.11 christos clear();
797 1.11 christos lprcat("Saving . . .");
798 1.11 christos lflush();
799 1.11 christos savegame(savefilename);
800 1.11 christos wizard = 1;
801 1.11 christos died(-257); /* save the game - doesn't return */
802 1.11 christos
803 1.11 christos case 'Z':
804 1.11 christos yrepcount = 0;
805 1.11 christos if (c[LEVEL] > 9) {
806 1.11 christos oteleport(1);
807 1.11 christos return;
808 1.11 christos }
809 1.11 christos cursors();
810 1.11 christos lprcat("\nAs yet, you don't have enough experience to use teleportation");
811 1.11 christos return; /* teleport yourself */
812 1.11 christos
813 1.11 christos case '^': /* identify traps */
814 1.11 christos flag = yrepcount = 0;
815 1.11 christos cursors();
816 1.11 christos lprc('\n');
817 1.11 christos for (j = playery - 1; j < playery + 2; j++) {
818 1.11 christos if (j < 0)
819 1.11 christos j = 0;
820 1.11 christos if (j >= MAXY)
821 1.11 christos break;
822 1.11 christos for (i = playerx - 1; i < playerx + 2; i++) {
823 1.11 christos if (i < 0)
824 1.11 christos i = 0;
825 1.11 christos if (i >= MAXX)
826 1.11 christos break;
827 1.11 christos switch (item[i][j]) {
828 1.11 christos case OTRAPDOOR:
829 1.11 christos case ODARTRAP:
830 1.11 christos case OTRAPARROW:
831 1.11 christos case OTELEPORTER:
832 1.18 mouse lprcat("\nIt's ");
833 1.11 christos lprcat(objectname[item[i][j]]);
834 1.11 christos flag++;
835 1.11 christos };
836 1.11 christos }
837 1.11 christos }
838 1.11 christos if (flag == 0)
839 1.11 christos lprcat("\nNo traps are visible");
840 1.11 christos return;
841 1.1 cgd
842 1.1 cgd #if WIZID
843 1.11 christos case '_': /* this is the fudge player password for
844 1.11 christos * wizard mode */
845 1.11 christos yrepcount = 0;
846 1.11 christos cursors();
847 1.11 christos nomove = 1;
848 1.11 christos if (userid != wisid) {
849 1.11 christos lprcat("Sorry, you are not empowered to be a wizard.\n");
850 1.11 christos scbr(); /* system("stty -echo cbreak"); */
851 1.11 christos lflush();
852 1.11 christos return;
853 1.11 christos }
854 1.11 christos if (getpassword() == 0) {
855 1.11 christos scbr(); /* system("stty -echo cbreak"); */
856 1.11 christos return;
857 1.11 christos }
858 1.11 christos wizard = 1;
859 1.11 christos scbr(); /* system("stty -echo cbreak"); */
860 1.11 christos for (i = 0; i < 6; i++)
861 1.11 christos c[i] = 70;
862 1.11 christos iven[0] = iven[1] = 0;
863 1.11 christos take(OPROTRING, 50);
864 1.11 christos take(OLANCE, 25);
865 1.11 christos c[WIELD] = 1;
866 1.11 christos c[LANCEDEATH] = 1;
867 1.11 christos c[WEAR] = c[SHIELD] = -1;
868 1.11 christos raiseexperience(6000000L);
869 1.11 christos c[AWARENESS] += 25000;
870 1.11 christos {
871 1.11 christos int i, j;
872 1.11 christos for (i = 0; i < MAXY; i++)
873 1.11 christos for (j = 0; j < MAXX; j++)
874 1.11 christos know[j][i] = 1;
875 1.11 christos for (i = 0; i < SPNUM; i++)
876 1.11 christos spelknow[i] = 1;
877 1.11 christos for (i = 0; i < MAXSCROLL; i++)
878 1.11 christos scrollname[i] = scrollhide[i];
879 1.11 christos for (i = 0; i < MAXPOTION; i++)
880 1.11 christos potionname[i] = potionhide[i];
881 1.11 christos }
882 1.11 christos for (i = 0; i < MAXSCROLL; i++)
883 1.11 christos if (strlen(scrollname[i]) > 2) { /* no null items */
884 1.11 christos item[i][0] = OSCROLL;
885 1.11 christos iarg[i][0] = i;
886 1.11 christos }
887 1.11 christos for (i = MAXX - 1; i > MAXX - 1 - MAXPOTION; i--)
888 1.11 christos if (strlen(potionname[i - MAXX + MAXPOTION]) > 2) { /* no null items */
889 1.11 christos item[i][0] = OPOTION;
890 1.11 christos iarg[i][0] = i - MAXX + MAXPOTION;
891 1.11 christos }
892 1.11 christos for (i = 1; i < MAXY; i++) {
893 1.11 christos item[0][i] = i;
894 1.11 christos iarg[0][i] = 0;
895 1.11 christos }
896 1.11 christos for (i = MAXY; i < MAXY + MAXX; i++) {
897 1.11 christos item[i - MAXY][MAXY - 1] = i;
898 1.11 christos iarg[i - MAXY][MAXY - 1] = 0;
899 1.11 christos }
900 1.11 christos for (i = MAXX + MAXY; i < MAXX + MAXY + MAXY; i++) {
901 1.11 christos item[MAXX - 1][i - MAXX - MAXY] = i;
902 1.11 christos iarg[MAXX - 1][i - MAXX - MAXY] = 0;
903 1.11 christos }
904 1.11 christos c[GOLD] += 25000;
905 1.11 christos drawscreen();
906 1.11 christos return;
907 1.1 cgd #endif
908 1.1 cgd
909 1.11 christos case 'T':
910 1.11 christos yrepcount = 0;
911 1.11 christos cursors();
912 1.11 christos if (c[SHIELD] != -1) {
913 1.11 christos c[SHIELD] = -1;
914 1.11 christos lprcat("\nYour shield is off");
915 1.11 christos bottomline();
916 1.11 christos } else if (c[WEAR] != -1) {
917 1.11 christos c[WEAR] = -1;
918 1.11 christos lprcat("\nYour armor is off");
919 1.11 christos bottomline();
920 1.11 christos } else
921 1.11 christos lprcat("\nYou aren't wearing anything");
922 1.11 christos return;
923 1.1 cgd
924 1.11 christos case 'g':
925 1.11 christos cursors();
926 1.19 dholland lprintf("\nThe stuff you are carrying presently weighs %ld pounds", (long) packweight());
927 1.11 christos case ' ':
928 1.11 christos yrepcount = 0;
929 1.11 christos nomove = 1;
930 1.11 christos return;
931 1.1 cgd
932 1.11 christos case 'v':
933 1.11 christos yrepcount = 0;
934 1.11 christos cursors();
935 1.19 dholland lprintf("\nCaverns of Larn, Version %ld.%ld, Diff=%ld",
936 1.19 dholland (long) VERSION, (long) SUBVERSION,
937 1.19 dholland (long) c[HARDGAME]);
938 1.11 christos if (wizard)
939 1.11 christos lprcat(" Wizard");
940 1.11 christos nomove = 1;
941 1.11 christos if (cheat)
942 1.11 christos lprcat(" Cheater");
943 1.11 christos lprcat(copyright);
944 1.11 christos return;
945 1.1 cgd
946 1.11 christos case 'Q':
947 1.11 christos yrepcount = 0;
948 1.11 christos quit();
949 1.11 christos nomove = 1;
950 1.11 christos return; /* quit */
951 1.11 christos
952 1.11 christos case 'L' - 64:
953 1.11 christos yrepcount = 0;
954 1.11 christos drawscreen();
955 1.11 christos nomove = 1;
956 1.11 christos return; /* look */
957 1.1 cgd
958 1.1 cgd #if WIZID
959 1.1 cgd #ifdef EXTRA
960 1.11 christos case 'A':
961 1.11 christos yrepcount = 0;
962 1.11 christos nomove = 1;
963 1.11 christos if (wizard) {
964 1.11 christos diag();
965 1.11 christos return;
966 1.11 christos } /* create diagnostic file */
967 1.11 christos return;
968 1.1 cgd #endif
969 1.1 cgd #endif
970 1.11 christos case 'P':
971 1.11 christos cursors();
972 1.11 christos if (outstanding_taxes > 0)
973 1.19 dholland lprintf("\nYou presently owe %ld gp in taxes.",
974 1.19 dholland (long) outstanding_taxes);
975 1.11 christos else
976 1.11 christos lprcat("\nYou do not owe any taxes.");
977 1.11 christos return;
978 1.11 christos };
979 1.1 cgd }
980 1.11 christos }
981 1.1 cgd
982 1.11 christos void
983 1.1 cgd parse2()
984 1.11 christos {
985 1.11 christos if (c[HASTEMONST])
986 1.11 christos movemonst();
987 1.11 christos movemonst(); /* move the monsters */
988 1.11 christos randmonst();
989 1.11 christos regen();
990 1.11 christos }
991 1.1 cgd
992 1.24 dholland static void
993 1.1 cgd run(dir)
994 1.11 christos int dir;
995 1.11 christos {
996 1.11 christos int i;
997 1.11 christos i = 1;
998 1.11 christos while (i) {
999 1.11 christos i = moveplayer(dir);
1000 1.11 christos if (i > 0) {
1001 1.11 christos if (c[HASTEMONST])
1002 1.11 christos movemonst();
1003 1.11 christos movemonst();
1004 1.11 christos randmonst();
1005 1.11 christos regen();
1006 1.1 cgd }
1007 1.11 christos if (hitflag)
1008 1.11 christos i = 0;
1009 1.11 christos if (i != 0)
1010 1.11 christos showcell(playerx, playery);
1011 1.1 cgd }
1012 1.11 christos }
1013 1.1 cgd
1014 1.1 cgd /*
1015 1.1 cgd function to wield a weapon
1016 1.1 cgd */
1017 1.24 dholland static void
1018 1.11 christos wield()
1019 1.11 christos {
1020 1.11 christos int i;
1021 1.11 christos while (1) {
1022 1.11 christos if ((i = whatitem("wield")) == '\33')
1023 1.11 christos return;
1024 1.11 christos if (i != '.') {
1025 1.11 christos if (i == '*')
1026 1.11 christos showwield();
1027 1.11 christos else if (iven[i - 'a'] == 0) {
1028 1.11 christos ydhi(i);
1029 1.11 christos return;
1030 1.11 christos } else if (iven[i - 'a'] == OPOTION) {
1031 1.11 christos ycwi(i);
1032 1.11 christos return;
1033 1.11 christos } else if (iven[i - 'a'] == OSCROLL) {
1034 1.11 christos ycwi(i);
1035 1.11 christos return;
1036 1.11 christos } else if ((c[SHIELD] != -1) && (iven[i - 'a'] == O2SWORD)) {
1037 1.11 christos lprcat("\nBut one arm is busy with your shield!");
1038 1.11 christos return;
1039 1.11 christos } else {
1040 1.11 christos c[WIELD] = i - 'a';
1041 1.11 christos if (iven[i - 'a'] == OLANCE)
1042 1.11 christos c[LANCEDEATH] = 1;
1043 1.11 christos else
1044 1.11 christos c[LANCEDEATH] = 0;
1045 1.11 christos bottomline();
1046 1.11 christos return;
1047 1.1 cgd }
1048 1.1 cgd }
1049 1.1 cgd }
1050 1.11 christos }
1051 1.1 cgd
1052 1.1 cgd /*
1053 1.1 cgd common routine to say you don't have an item
1054 1.1 cgd */
1055 1.24 dholland static void
1056 1.1 cgd ydhi(x)
1057 1.11 christos int x;
1058 1.11 christos {
1059 1.11 christos cursors();
1060 1.11 christos lprintf("\nYou don't have item %c!", x);
1061 1.11 christos }
1062 1.24 dholland static void
1063 1.1 cgd ycwi(x)
1064 1.11 christos int x;
1065 1.11 christos {
1066 1.11 christos cursors();
1067 1.11 christos lprintf("\nYou can't wield item %c!", x);
1068 1.11 christos }
1069 1.1 cgd
1070 1.1 cgd /*
1071 1.1 cgd function to wear armor
1072 1.1 cgd */
1073 1.24 dholland static void
1074 1.1 cgd wear()
1075 1.11 christos {
1076 1.11 christos int i;
1077 1.11 christos while (1) {
1078 1.11 christos if ((i = whatitem("wear")) == '\33')
1079 1.11 christos return;
1080 1.11 christos if (i != '.') {
1081 1.11 christos if (i == '*')
1082 1.11 christos showwear();
1083 1.11 christos else
1084 1.11 christos switch (iven[i - 'a']) {
1085 1.11 christos case 0:
1086 1.11 christos ydhi(i);
1087 1.11 christos return;
1088 1.11 christos case OLEATHER:
1089 1.11 christos case OCHAIN:
1090 1.11 christos case OPLATE:
1091 1.11 christos case OSTUDLEATHER:
1092 1.11 christos case ORING:
1093 1.11 christos case OSPLINT:
1094 1.11 christos case OPLATEARMOR:
1095 1.11 christos case OSSPLATE:
1096 1.11 christos if (c[WEAR] != -1) {
1097 1.11 christos lprcat("\nYou're already wearing some armor");
1098 1.11 christos return;
1099 1.11 christos }
1100 1.11 christos c[WEAR] = i - 'a';
1101 1.11 christos bottomline();
1102 1.11 christos return;
1103 1.11 christos case OSHIELD:
1104 1.11 christos if (c[SHIELD] != -1) {
1105 1.11 christos lprcat("\nYou are already wearing a shield");
1106 1.11 christos return;
1107 1.11 christos }
1108 1.11 christos if (iven[c[WIELD]] == O2SWORD) {
1109 1.11 christos lprcat("\nYour hands are busy with the two handed sword!");
1110 1.11 christos return;
1111 1.11 christos }
1112 1.11 christos c[SHIELD] = i - 'a';
1113 1.11 christos bottomline();
1114 1.11 christos return;
1115 1.11 christos default:
1116 1.11 christos lprcat("\nYou can't wear that!");
1117 1.1 cgd };
1118 1.1 cgd }
1119 1.1 cgd }
1120 1.11 christos }
1121 1.1 cgd
1122 1.1 cgd /*
1123 1.1 cgd function to drop an object
1124 1.1 cgd */
1125 1.24 dholland static void
1126 1.1 cgd dropobj()
1127 1.11 christos {
1128 1.11 christos int i;
1129 1.20 dholland unsigned char *p;
1130 1.11 christos long amt;
1131 1.1 cgd p = &item[playerx][playery];
1132 1.11 christos while (1) {
1133 1.11 christos if ((i = whatitem("drop")) == '\33')
1134 1.11 christos return;
1135 1.11 christos if (i == '*')
1136 1.11 christos showstr();
1137 1.11 christos else {
1138 1.11 christos if (i == '.') { /* drop some gold */
1139 1.11 christos if (*p) {
1140 1.11 christos lprcat("\nThere's something here already!");
1141 1.11 christos return;
1142 1.11 christos }
1143 1.1 cgd lprcat("\n\n");
1144 1.11 christos cl_dn(1, 23);
1145 1.1 cgd lprcat("How much gold do you drop? ");
1146 1.11 christos if ((amt = readnum((long) c[GOLD])) == 0)
1147 1.11 christos return;
1148 1.11 christos if (amt > c[GOLD]) {
1149 1.11 christos lprcat("\nYou don't have that much!");
1150 1.11 christos return;
1151 1.11 christos }
1152 1.11 christos if (amt <= 32767) {
1153 1.11 christos *p = OGOLDPILE;
1154 1.11 christos i = amt;
1155 1.11 christos } else if (amt <= 327670L) {
1156 1.11 christos *p = ODGOLD;
1157 1.11 christos i = amt / 10;
1158 1.11 christos amt = 10 * i;
1159 1.11 christos } else if (amt <= 3276700L) {
1160 1.11 christos *p = OMAXGOLD;
1161 1.11 christos i = amt / 100;
1162 1.11 christos amt = 100 * i;
1163 1.11 christos } else if (amt <= 32767000L) {
1164 1.11 christos *p = OKGOLD;
1165 1.11 christos i = amt / 1000;
1166 1.11 christos amt = 1000 * i;
1167 1.11 christos } else {
1168 1.11 christos *p = OKGOLD;
1169 1.11 christos i = 32767;
1170 1.11 christos amt = 32767000L;
1171 1.1 cgd }
1172 1.11 christos c[GOLD] -= amt;
1173 1.19 dholland lprintf("You drop %ld gold pieces", (long)amt);
1174 1.11 christos iarg[playerx][playery] = i;
1175 1.11 christos bottomgold();
1176 1.11 christos know[playerx][playery] = 0;
1177 1.11 christos dropflag = 1;
1178 1.11 christos return;
1179 1.11 christos }
1180 1.11 christos drop_object(i - 'a');
1181 1.1 cgd return;
1182 1.1 cgd }
1183 1.1 cgd }
1184 1.11 christos }
1185 1.1 cgd
1186 1.1 cgd /*
1187 1.1 cgd * readscr() Subroutine to read a scroll one is carrying
1188 1.1 cgd */
1189 1.24 dholland static void
1190 1.1 cgd readscr()
1191 1.11 christos {
1192 1.11 christos int i;
1193 1.11 christos while (1) {
1194 1.11 christos if ((i = whatitem("read")) == '\33')
1195 1.11 christos return;
1196 1.11 christos if (i != '.') {
1197 1.11 christos if (i == '*')
1198 1.11 christos showread();
1199 1.11 christos else {
1200 1.11 christos if (iven[i - 'a'] == OSCROLL) {
1201 1.11 christos read_scroll(ivenarg[i - 'a']);
1202 1.11 christos iven[i - 'a'] = 0;
1203 1.11 christos return;
1204 1.11 christos }
1205 1.11 christos if (iven[i - 'a'] == OBOOK) {
1206 1.11 christos readbook(ivenarg[i - 'a']);
1207 1.11 christos iven[i - 'a'] = 0;
1208 1.11 christos return;
1209 1.11 christos }
1210 1.11 christos if (iven[i - 'a'] == 0) {
1211 1.11 christos ydhi(i);
1212 1.11 christos return;
1213 1.1 cgd }
1214 1.11 christos lprcat("\nThere's nothing on it to read");
1215 1.11 christos return;
1216 1.1 cgd }
1217 1.1 cgd }
1218 1.1 cgd }
1219 1.11 christos }
1220 1.1 cgd
1221 1.1 cgd /*
1222 1.1 cgd * subroutine to eat a cookie one is carrying
1223 1.1 cgd */
1224 1.24 dholland static void
1225 1.20 dholland eatcookie(void)
1226 1.1 cgd {
1227 1.20 dholland const char *p;
1228 1.20 dholland int i;
1229 1.20 dholland
1230 1.11 christos while (1) {
1231 1.11 christos if ((i = whatitem("eat")) == '\33')
1232 1.11 christos return;
1233 1.14 veego if (i != '.') {
1234 1.11 christos if (i == '*')
1235 1.11 christos showeat();
1236 1.11 christos else {
1237 1.11 christos if (iven[i - 'a'] == OCOOKIE) {
1238 1.11 christos lprcat("\nThe cookie was delicious.");
1239 1.11 christos iven[i - 'a'] = 0;
1240 1.11 christos if (!c[BLINDCOUNT]) {
1241 1.11 christos if ((p = fortune()) != NULL) {
1242 1.11 christos lprcat(" Inside you find a scrap of paper that says:\n");
1243 1.11 christos lprcat(p);
1244 1.1 cgd }
1245 1.1 cgd }
1246 1.11 christos return;
1247 1.11 christos }
1248 1.11 christos if (iven[i - 'a'] == 0) {
1249 1.11 christos ydhi(i);
1250 1.11 christos return;
1251 1.11 christos }
1252 1.11 christos lprcat("\nYou can't eat that!");
1253 1.1 cgd return;
1254 1.1 cgd }
1255 1.14 veego }
1256 1.1 cgd }
1257 1.1 cgd }
1258 1.1 cgd
1259 1.1 cgd /*
1260 1.1 cgd * subroutine to quaff a potion one is carrying
1261 1.1 cgd */
1262 1.24 dholland static void
1263 1.1 cgd quaff()
1264 1.11 christos {
1265 1.11 christos int i;
1266 1.11 christos while (1) {
1267 1.11 christos if ((i = whatitem("quaff")) == '\33')
1268 1.11 christos return;
1269 1.11 christos if (i != '.') {
1270 1.11 christos if (i == '*')
1271 1.11 christos showquaff();
1272 1.11 christos else {
1273 1.11 christos if (iven[i - 'a'] == OPOTION) {
1274 1.11 christos quaffpotion(ivenarg[i - 'a']);
1275 1.11 christos iven[i - 'a'] = 0;
1276 1.11 christos return;
1277 1.11 christos }
1278 1.11 christos if (iven[i - 'a'] == 0) {
1279 1.11 christos ydhi(i);
1280 1.11 christos return;
1281 1.1 cgd }
1282 1.11 christos lprcat("\nYou wouldn't want to quaff that, would you? ");
1283 1.11 christos return;
1284 1.1 cgd }
1285 1.1 cgd }
1286 1.1 cgd }
1287 1.11 christos }
1288 1.1 cgd
1289 1.1 cgd /*
1290 1.1 cgd function to ask what player wants to do
1291 1.1 cgd */
1292 1.22 dholland static int
1293 1.20 dholland whatitem(const char *str)
1294 1.11 christos {
1295 1.11 christos int i;
1296 1.11 christos cursors();
1297 1.11 christos lprintf("\nWhat do you want to %s [* for all] ? ", str);
1298 1.11 christos i = 0;
1299 1.11 christos while (i > 'z' || (i < 'a' && i != '*' && i != '\33' && i != '.'))
1300 1.23 dholland i = ttgetch();
1301 1.11 christos if (i == '\33')
1302 1.11 christos lprcat(" aborted");
1303 1.11 christos return (i);
1304 1.11 christos }
1305 1.1 cgd
1306 1.1 cgd /*
1307 1.1 cgd subroutine to get a number from the player
1308 1.1 cgd and allow * to mean return amt, else return the number entered
1309 1.1 cgd */
1310 1.11 christos unsigned long
1311 1.11 christos readnum(mx)
1312 1.11 christos long mx;
1313 1.11 christos {
1314 1.11 christos int i;
1315 1.11 christos unsigned long amt = 0;
1316 1.1 cgd sncbr();
1317 1.23 dholland if ((i = ttgetch()) == '*')
1318 1.11 christos amt = mx; /* allow him to say * for all gold */
1319 1.1 cgd else
1320 1.11 christos while (i != '\n') {
1321 1.11 christos if (i == '\033') {
1322 1.11 christos scbr();
1323 1.11 christos lprcat(" aborted");
1324 1.11 christos return (0);
1325 1.11 christos }
1326 1.11 christos if ((i <= '9') && (i >= '0') && (amt < 99999999))
1327 1.11 christos amt = amt * 10 + i - '0';
1328 1.23 dholland i = ttgetch();
1329 1.11 christos }
1330 1.11 christos scbr();
1331 1.11 christos return (amt);
1332 1.11 christos }
1333 1.1 cgd
1334 1.1 cgd #ifdef HIDEBYLINK
1335 1.1 cgd /*
1336 1.1 cgd * routine to zero every byte in a string
1337 1.1 cgd */
1338 1.11 christos void
1339 1.1 cgd szero(str)
1340 1.11 christos char *str;
1341 1.11 christos {
1342 1.1 cgd while (*str)
1343 1.1 cgd *str++ = 0;
1344 1.11 christos }
1345 1.11 christos #endif /* HIDEBYLINK */
1346