]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - larn/main.c
src/games/quiz from Lite
[bsdgames-darwin.git] / larn / main.c
1 #ifndef lint
2 static char rcsid[] = "$NetBSD: main.c,v 1.6 1995/04/22 07:34:07 cgd Exp $";
3 #endif /* not lint */
4
5 /* main.c */
6 #include <sys/types.h>
7 #include "header.h"
8 #include <pwd.h>
9 static char copyright[]="\nLarn is copyrighted 1986 by Noah Morgan.\n";
10 int srcount=0; /* line counter for showstr() */
11 int dropflag=0; /* if 1 then don't lookforobject() next round */
12 int rmst=80; /* random monster creation counter */
13 int userid; /* the players login user id number */
14 char nowelcome=0,nomove=0; /* if (nomove) then don't count next iteration as a move */
15 static char viewflag=0;
16 /* if viewflag then we have done a 99 stay here and don't showcell in the main loop */
17 char restorflag=0; /* 1 means restore has been done */
18 static char cmdhelp[] = "\
19 Cmd line format: larn [-slicnh] [-o<optsifle>] [-##] [++]\n\
20 -s show the scoreboard\n\
21 -l show the logfile (wizard id only)\n\
22 -i show scoreboard with inventories of dead characters\n\
23 -c create new scoreboard (wizard id only)\n\
24 -n suppress welcome message on starting game\n\
25 -## specify level of difficulty (example: -5)\n\
26 -h print this help text\n\
27 ++ restore game from checkpoint file\n\
28 -o<optsfile> specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
29 ";
30 #ifdef VT100
31 static char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125",
32 "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
33 "vt341" };
34 #endif VT100
35 /*
36 ************
37 MAIN PROGRAM
38 ************
39 */
40 main(argc,argv)
41 int argc;
42 char **argv;
43 {
44 register int i,j;
45 int hard;
46 char *ptr=0,*ttype;
47 struct passwd *pwe;
48
49 /*
50 * first task is to identify the player
51 */
52 #ifndef VT100
53 init_term(); /* setup the terminal (find out what type) for termcap */
54 #endif VT100
55 if (((ptr = getlogin()) == 0) || (*ptr==0)) /* try to get login name */
56 if (pwe=getpwuid(getuid())) /* can we get it from /etc/passwd? */
57 ptr = pwe->pw_name;
58 else
59 if ((ptr = getenv("USER")) == 0)
60 if ((ptr = getenv("LOGNAME")) == 0)
61 {
62 noone: write(2, "Can't find your logname. Who Are You?\n",39);
63 exit();
64 }
65 if (ptr==0) goto noone;
66 if (strlen(ptr)==0) goto noone;
67 /*
68 * second task is to prepare the pathnames the player will need
69 */
70 strcpy(loginname,ptr); /* save loginname of the user for logging purposes */
71 strcpy(logname,ptr); /* this will be overwritten with the players name */
72 if ((ptr = getenv("HOME")) == 0) ptr = ".";
73 strcpy(savefilename, ptr);
74 strcat(savefilename, "/Larn.sav"); /* save file name in home directory */
75 sprintf(optsfile, "%s/.larnopts",ptr); /* the .larnopts filename */
76
77 /*
78 * now malloc the memory for the dungeon
79 */
80 cell = (struct cel *)malloc(sizeof(struct cel)*(MAXLEVEL+MAXVLEVEL)*MAXX*MAXY);
81 if (cell == 0) died(-285); /* malloc failure */
82 lpbuf = malloc((5* BUFBIG)>>2); /* output buffer */
83 inbuffer = malloc((5*MAXIBUF)>>2); /* output buffer */
84 if ((lpbuf==0) || (inbuffer==0)) died(-285); /* malloc() failure */
85
86 lcreat((char*)0); newgame(); /* set the initial clock */ hard= -1;
87
88 #ifdef VT100
89 /*
90 * check terminal type to avoid users who have not vt100 type terminals
91 */
92 ttype = getenv("TERM");
93 for (j=1, i=0; i<sizeof(termtypes)/sizeof(char *); i++)
94 if (strcmp(ttype,termtypes[i]) == 0) { j=0; break; }
95 if (j)
96 {
97 lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n"); lflush();
98 exit();
99 }
100 #endif VT100
101
102 /*
103 * now make scoreboard if it is not there (don't clear)
104 */
105 if (access(scorefile,0) == -1) /* not there */
106 makeboard();
107
108 /*
109 * now process the command line arguments
110 */
111 for (i=1; i<argc; i++)
112 {
113 if (argv[i][0] == '-')
114 switch(argv[i][1])
115 {
116 case 's': showscores(); exit(); /* show scoreboard */
117
118 case 'l': /* show log file */
119 diedlog(); exit();
120
121 case 'i': showallscores(); exit(); /* show all scoreboard */
122
123 case 'c': /* anyone with password can create scoreboard */
124 lprcat("Preparing to initialize the scoreboard.\n");
125 if (getpassword() != 0) /*make new scoreboard*/
126 {
127 makeboard(); lprc('\n'); showscores();
128 }
129 exit();
130
131 case 'n': /* no welcome msg */ nowelcome=1; argv[i][0]=0; break;
132
133 case '0': case '1': case '2': case '3': case '4': case '5':
134 case '6': case '7': case '8': case '9': /* for hardness */
135 sscanf(&argv[i][1],"%d",&hard);
136 break;
137
138 case 'h': /* print out command line arguments */
139 write(1,cmdhelp,sizeof(cmdhelp)); exit();
140
141 case 'o': /* specify a .larnopts filename */
142 strncpy(optsfile,argv[i]+2,127); break;
143
144 default: printf("Unknown option <%s>\n",argv[i]); exit();
145 };
146
147 if (argv[i][0] == '+')
148 {
149 clear(); restorflag = 1;
150 if (argv[i][1] == '+')
151 {
152 hitflag=1; restoregame(ckpfile); /* restore checkpointed game */
153 }
154 i = argc;
155 }
156 }
157
158 readopts(); /* read the options file if there is one */
159
160
161 #ifdef UIDSCORE
162 userid = geteuid(); /* obtain the user's effective id number */
163 #else UIDSCORE
164 userid = getplid(logname); /* obtain the players id number */
165 #endif UIDSCORE
166 if (userid < 0) { write(2,"Can't obtain playerid\n",22); exit(); }
167
168 #ifdef HIDEBYLINK
169 /*
170 * this section of code causes the program to look like something else to ps
171 */
172 if (strcmp(psname,argv[0])) /* if a different process name only */
173 {
174 if ((i=access(psname,1)) < 0)
175 { /* link not there */
176 if (link(argv[0],psname)>=0)
177 {
178 argv[0] = psname; execv(psname,argv);
179 }
180 }
181 else
182 unlink(psname);
183 }
184
185 for (i=1; i<argc; i++)
186 {
187 szero(argv[i]); /* zero the argument to avoid ps snooping */
188 }
189 #endif HIDEBYLINK
190
191 if (access(savefilename,0)==0) /* restore game if need to */
192 {
193 clear(); restorflag = 1;
194 hitflag=1; restoregame(savefilename); /* restore last game */
195 }
196 sigsetup(); /* trap all needed signals */
197 sethard(hard); /* set up the desired difficulty */
198 setupvt100(); /* setup the terminal special mode */
199 if (c[HP]==0) /* create new game */
200 {
201 makeplayer(); /* make the character that will play */
202 newcavelevel(0);/* make the dungeon */
203 predostuff = 1; /* tell signals that we are in the welcome screen */
204 if (nowelcome==0) welcome(); /* welcome the player to the game */
205 }
206 drawscreen(); /* show the initial dungeon */
207 predostuff = 2; /* tell the trap functions that they must do a showplayer()
208 from here on */
209 /* nice(1); /* games should be run niced */
210 yrepcount = hit2flag = 0;
211 while (1)
212 {
213 if (dropflag==0) lookforobject(); /* see if there is an object here */
214 else dropflag=0; /* don't show it just dropped an item */
215 if (hitflag==0) { if (c[HASTEMONST]) movemonst(); movemonst(); } /* move the monsters */
216 if (viewflag==0) showcell(playerx,playery); else viewflag=0; /* show stuff around player */
217 if (hit3flag) flushall();
218 hitflag=hit3flag=0; nomove=1;
219 bot_linex(); /* update bottom line */
220 while (nomove)
221 {
222 if (hit3flag) flushall();
223 nomove=0; parse();
224 } /* get commands and make moves */
225 regen(); /* regenerate hp and spells */
226 if (c[TIMESTOP]==0)
227 if (--rmst <= 0)
228 { rmst = 120-(level<<2); fillmonst(makemonst(level)); }
229 }
230 }
231 \f
232 /*
233 showstr()
234
235 show character's inventory
236 */
237 showstr()
238 {
239 register int i,number;
240 for (number=3, i=0; i<26; i++)
241 if (iven[i]) number++; /* count items in inventory */
242 t_setup(number); qshowstr(); t_endup(number);
243 }
244
245 qshowstr()
246 {
247 register int i,j,k,sigsav;
248 srcount=0; sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
249 if (c[GOLD]) { lprintf(".) %d gold pieces",(long)c[GOLD]); srcount++; }
250 for (k=26; k>=0; k--)
251 if (iven[k])
252 { for (i=22; i<84; i++)
253 for (j=0; j<=k; j++) if (i==iven[j]) show3(j); k=0; }
254
255 lprintf("\nElapsed time is %d. You have %d mobuls left",(long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100));
256 more(); nosignal=sigsav;
257 }
258
259 /*
260 * subroutine to clear screen depending on # lines to display
261 */
262 t_setup(count)
263 register int count;
264 {
265 if (count<20) /* how do we clear the screen? */
266 {
267 cl_up(79,count); cursor(1,1);
268 }
269 else
270 {
271 resetscroll(); clear();
272 }
273 }
274
275 /*
276 * subroutine to restore normal display screen depending on t_setup()
277 */
278 t_endup(count)
279 register int count;
280 {
281 if (count<18) /* how did we clear the screen? */
282 draws(0,MAXX,0,(count>MAXY) ? MAXY : count);
283 else
284 {
285 drawscreen(); setscroll();
286 }
287 }
288
289 /*
290 function to show the things player is wearing only
291 */
292 showwear()
293 {
294 register int i,j,sigsav,count;
295 sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
296 srcount=0;
297
298 for (count=2,j=0; j<=26; j++) /* count number of items we will display */
299 if (i=iven[j])
300 switch(i)
301 {
302 case OLEATHER: case OPLATE: case OCHAIN:
303 case ORING: case OSTUDLEATHER: case OSPLINT:
304 case OPLATEARMOR: case OSSPLATE: case OSHIELD:
305 count++;
306 };
307
308 t_setup(count);
309
310 for (i=22; i<84; i++)
311 for (j=0; j<=26; j++)
312 if (i==iven[j])
313 switch(i)
314 {
315 case OLEATHER: case OPLATE: case OCHAIN:
316 case ORING: case OSTUDLEATHER: case OSPLINT:
317 case OPLATEARMOR: case OSSPLATE: case OSHIELD:
318 show3(j);
319 };
320 more(); nosignal=sigsav; t_endup(count);
321 }
322
323 /*
324 function to show the things player can wield only
325 */
326 showwield()
327 {
328 register int i,j,sigsav,count;
329 sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
330 srcount=0;
331
332 for (count=2,j=0; j<=26; j++) /* count how many items */
333 if (i=iven[j])
334 switch(i)
335 {
336 case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE:
337 case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT:
338 case OSPIRITSCARAB: case OCUBEofUNDEAD:
339 case OPOTION: case OSCROLL: break;
340 default: count++;
341 };
342
343 t_setup(count);
344
345 for (i=22; i<84; i++)
346 for (j=0; j<=26; j++)
347 if (i==iven[j])
348 switch(i)
349 {
350 case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE:
351 case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT:
352 case OSPIRITSCARAB: case OCUBEofUNDEAD:
353 case OPOTION: case OSCROLL: break;
354 default: show3(j);
355 };
356 more(); nosignal=sigsav; t_endup(count);
357 }
358
359 /*
360 * function to show the things player can read only
361 */
362 showread()
363 {
364 register int i,j,sigsav,count;
365 sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
366 srcount=0;
367
368 for (count=2,j=0; j<=26; j++)
369 switch(iven[j])
370 {
371 case OBOOK: case OSCROLL: count++;
372 };
373 t_setup(count);
374
375 for (i=22; i<84; i++)
376 for (j=0; j<=26; j++)
377 if (i==iven[j])
378 switch(i)
379 {
380 case OBOOK: case OSCROLL: show3(j);
381 };
382 more(); nosignal=sigsav; t_endup(count);
383 }
384
385 /*
386 * function to show the things player can eat only
387 */
388 showeat()
389 {
390 register int i,j,sigsav,count;
391 sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
392 srcount=0;
393
394 for (count=2,j=0; j<=26; j++)
395 switch(iven[j])
396 {
397 case OCOOKIE: count++;
398 };
399 t_setup(count);
400
401 for (i=22; i<84; i++)
402 for (j=0; j<=26; j++)
403 if (i==iven[j])
404 switch(i)
405 {
406 case OCOOKIE: show3(j);
407 };
408 more(); nosignal=sigsav; t_endup(count);
409 }
410
411 /*
412 function to show the things player can quaff only
413 */
414 showquaff()
415 {
416 register int i,j,sigsav,count;
417 sigsav=nosignal; nosignal=1; /* don't allow ^c etc */
418 srcount=0;
419
420 for (count=2,j=0; j<=26; j++)
421 switch(iven[j])
422 {
423 case OPOTION: count++;
424 };
425 t_setup(count);
426
427 for (i=22; i<84; i++)
428 for (j=0; j<=26; j++)
429 if (i==iven[j])
430 switch(i)
431 {
432 case OPOTION: show3(j);
433 };
434 more(); nosignal=sigsav; t_endup(count);
435 }
436
437 show1(idx,str2)
438 register int idx;
439 register char *str2[];
440 {
441 lprintf("\n%c) %s",idx+'a',objectname[iven[idx]]);
442 if (str2!=0 && str2[ivenarg[idx]][0]!=0) lprintf(" of%s",str2[ivenarg[idx]]);
443 }
444
445 show3(index)
446 register int index;
447 {
448 switch(iven[index])
449 {
450 case OPOTION: show1(index,potionname); break;
451 case OSCROLL: show1(index,scrollname); break;
452
453 case OLARNEYE: case OBOOK: case OSPIRITSCARAB:
454 case ODIAMOND: case ORUBY: case OCUBEofUNDEAD:
455 case OEMERALD: case OCHEST: case OCOOKIE:
456 case OSAPPHIRE: case ONOTHEFT: show1(index,(char **)0); break;
457
458 default: lprintf("\n%c) %s",index+'a',objectname[iven[index]]);
459 if (ivenarg[index]>0) lprintf(" + %d",(long)ivenarg[index]);
460 else if (ivenarg[index]<0) lprintf(" %d",(long)ivenarg[index]);
461 break;
462 }
463 if (c[WIELD]==index) lprcat(" (weapon in hand)");
464 if ((c[WEAR]==index) || (c[SHIELD]==index)) lprcat(" (being worn)");
465 if (++srcount>=22) { srcount=0; more(); clear(); }
466 }
467
468 /*
469 subroutine to randomly create monsters if needed
470 */
471 randmonst()
472 {
473 if (c[TIMESTOP]) return; /* don't make monsters if time is stopped */
474 if (--rmst <= 0)
475 {
476 rmst = 120 - (level<<2); fillmonst(makemonst(level));
477 }
478 }
479
480 \f
481 /*
482 parse()
483
484 get and execute a command
485 */
486 parse()
487 {
488 register int i,j,k,flag;
489 while (1)
490 {
491 k = yylex();
492 switch(k) /* get the token from the input and switch on it */
493 {
494 case 'h': moveplayer(4); return; /* west */
495 case 'H': run(4); return; /* west */
496 case 'l': moveplayer(2); return; /* east */
497 case 'L': run(2); return; /* east */
498 case 'j': moveplayer(1); return; /* south */
499 case 'J': run(1); return; /* south */
500 case 'k': moveplayer(3); return; /* north */
501 case 'K': run(3); return; /* north */
502 case 'u': moveplayer(5); return; /* northeast */
503 case 'U': run(5); return; /* northeast */
504 case 'y': moveplayer(6); return; /* northwest */
505 case 'Y': run(6); return; /* northwest */
506 case 'n': moveplayer(7); return; /* southeast */
507 case 'N': run(7); return; /* southeast */
508 case 'b': moveplayer(8); return; /* southwest */
509 case 'B': run(8); return; /* southwest */
510
511 case '.': if (yrepcount) viewflag=1; return; /* stay here */
512
513 case 'w': yrepcount=0; wield(); return; /* wield a weapon */
514
515 case 'W': yrepcount=0; wear(); return; /* wear armor */
516
517 case 'r': yrepcount=0;
518 if (c[BLINDCOUNT]) { cursors(); lprcat("\nYou can't read anything when you're blind!"); } else
519 if (c[TIMESTOP]==0) readscr(); return; /* to read a scroll */
520
521 case 'q': yrepcount=0; if (c[TIMESTOP]==0) quaff(); return; /* quaff a potion */
522
523 case 'd': yrepcount=0; if (c[TIMESTOP]==0) dropobj(); return; /* to drop an object */
524
525 case 'c': yrepcount=0; cast(); return; /* cast a spell */
526
527 case 'i': yrepcount=0; nomove=1; showstr(); return; /* status */
528
529 case 'e': yrepcount=0;
530 if (c[TIMESTOP]==0) eatcookie(); return; /* to eat a fortune cookie */
531
532 case 'D': yrepcount=0; seemagic(0); nomove=1; return; /* list spells and scrolls */
533
534 case '?': yrepcount=0; help(); nomove=1; return; /* give the help screen*/
535
536 case 'S': clear(); lprcat("Saving . . ."); lflush();
537 savegame(savefilename); wizard=1; died(-257); /* save the game - doesn't return */
538
539 case 'Z': yrepcount=0; if (c[LEVEL]>9) { oteleport(1); return; }
540 cursors(); lprcat("\nAs yet, you don't have enough experience to use teleportation");
541 return; /* teleport yourself */
542
543 case '^': /* identify traps */ flag=yrepcount=0; cursors();
544 lprc('\n'); for (j=playery-1; j<playery+2; j++)
545 {
546 if (j < 0) j=0; if (j >= MAXY) break;
547 for (i=playerx-1; i<playerx+2; i++)
548 {
549 if (i < 0) i=0; if (i >= MAXX) break;
550 switch(item[i][j])
551 {
552 case OTRAPDOOR: case ODARTRAP:
553 case OTRAPARROW: case OTELEPORTER:
554 lprcat("\nIts "); lprcat(objectname[item[i][j]]); flag++;
555 };
556 }
557 }
558 if (flag==0) lprcat("\nNo traps are visible");
559 return;
560
561 #if WIZID
562 case '_': /* this is the fudge player password for wizard mode*/
563 yrepcount=0; cursors(); nomove=1;
564 if (userid!=wisid)
565 {
566 lprcat("Sorry, you are not empowered to be a wizard.\n");
567 scbr(); /* system("stty -echo cbreak"); */
568 lflush(); return;
569 }
570 if (getpassword()==0)
571 {
572 scbr(); /* system("stty -echo cbreak"); */ return;
573 }
574 wizard=1; scbr(); /* system("stty -echo cbreak"); */
575 for (i=0; i<6; i++) c[i]=70; iven[0]=iven[1]=0;
576 take(OPROTRING,50); take(OLANCE,25); c[WIELD]=1;
577 c[LANCEDEATH]=1; c[WEAR] = c[SHIELD] = -1;
578 raiseexperience(6000000L); c[AWARENESS] += 25000;
579 {
580 register int i,j;
581 for (i=0; i<MAXY; i++)
582 for (j=0; j<MAXX; j++) know[j][i]=1;
583 for (i=0; i<SPNUM; i++) spelknow[i]=1;
584 for (i=0; i<MAXSCROLL; i++) scrollname[i]=scrollhide[i];
585 for (i=0; i<MAXPOTION; i++) potionname[i]=potionhide[i];
586 }
587 for (i=0; i<MAXSCROLL; i++)
588 if (strlen(scrollname[i])>2) /* no null items */
589 { item[i][0]=OSCROLL; iarg[i][0]=i; }
590 for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--)
591 if (strlen(potionname[i-MAXX+MAXPOTION])>2) /* no null items */
592 { item[i][0]=OPOTION; iarg[i][0]=i-MAXX+MAXPOTION; }
593 for (i=1; i<MAXY; i++)
594 { item[0][i]=i; iarg[0][i]=0; }
595 for (i=MAXY; i<MAXY+MAXX; i++)
596 { item[i-MAXY][MAXY-1]=i; iarg[i-MAXY][MAXY-1]=0; }
597 for (i=MAXX+MAXY; i<MAXX+MAXY+MAXY; i++)
598 { item[MAXX-1][i-MAXX-MAXY]=i; iarg[MAXX-1][i-MAXX-MAXY]=0; }
599 c[GOLD]+=25000; drawscreen(); return;
600 #endif
601
602 case 'T': yrepcount=0; cursors(); if (c[SHIELD] != -1) { c[SHIELD] = -1; lprcat("\nYour shield is off"); bottomline(); } else
603 if (c[WEAR] != -1) { c[WEAR] = -1; lprcat("\nYour armor is off"); bottomline(); }
604 else lprcat("\nYou aren't wearing anything");
605 return;
606
607 case 'g': cursors();
608 lprintf("\nThe stuff you are carrying presently weighs %d pounds",(long)packweight());
609 case ' ': yrepcount=0; nomove=1; return;
610
611 case 'v': yrepcount=0; cursors();
612 lprintf("\nCaverns of Larn, Version %d.%d, Diff=%d",(long)VERSION,(long)SUBVERSION,(long)c[HARDGAME]);
613 if (wizard) lprcat(" Wizard"); nomove=1;
614 if (cheat) lprcat(" Cheater");
615 lprcat(copyright);
616 return;
617
618 case 'Q': yrepcount=0; quit(); nomove=1; return; /* quit */
619
620 case 'L'-64: yrepcount=0; drawscreen(); nomove=1; return; /* look */
621
622 #if WIZID
623 #ifdef EXTRA
624 case 'A': yrepcount=0; nomove=1; if (wizard) { diag(); return; } /* create diagnostic file */
625 return;
626 #endif
627 #endif
628 case 'P': cursors();
629 if (outstanding_taxes>0)
630 lprintf("\nYou presently owe %d gp in taxes.",(long)outstanding_taxes);
631 else
632 lprcat("\nYou do not owe any taxes.");
633 return;
634 };
635 }
636 }
637
638 parse2()
639 {
640 if (c[HASTEMONST]) movemonst(); movemonst(); /* move the monsters */
641 randmonst(); regen();
642 }
643
644 run(dir)
645 int dir;
646 {
647 register int i;
648 i=1; while (i)
649 {
650 i=moveplayer(dir);
651 if (i>0) { if (c[HASTEMONST]) movemonst(); movemonst(); randmonst(); regen(); }
652 if (hitflag) i=0;
653 if (i!=0) showcell(playerx,playery);
654 }
655 }
656
657 /*
658 function to wield a weapon
659 */
660 wield()
661 {
662 register int i;
663 while (1)
664 {
665 if ((i = whatitem("wield"))=='\33') return;
666 if (i != '.')
667 {
668 if (i=='*') showwield();
669 else if (iven[i-'a']==0) { ydhi(i); return; }
670 else if (iven[i-'a']==OPOTION) { ycwi(i); return; }
671 else if (iven[i-'a']==OSCROLL) { ycwi(i); return; }
672 else if ((c[SHIELD]!= -1) && (iven[i-'a']==O2SWORD)) { lprcat("\nBut one arm is busy with your shield!"); return; }
673 else { c[WIELD]=i-'a'; if (iven[i-'a'] == OLANCE) c[LANCEDEATH]=1; else c[LANCEDEATH]=0; bottomline(); return; }
674 }
675 }
676 }
677
678 /*
679 common routine to say you don't have an item
680 */
681 ydhi(x)
682 int x;
683 { cursors(); lprintf("\nYou don't have item %c!",x); }
684 ycwi(x)
685 int x;
686 { cursors(); lprintf("\nYou can't wield item %c!",x); }
687
688 /*
689 function to wear armor
690 */
691 wear()
692 {
693 register int i;
694 while (1)
695 {
696 if ((i = whatitem("wear"))=='\33') return;
697 if (i != '.')
698 {
699 if (i=='*') showwear(); else
700 switch(iven[i-'a'])
701 {
702 case 0: ydhi(i); return;
703 case OLEATHER: case OCHAIN: case OPLATE: case OSTUDLEATHER:
704 case ORING: case OSPLINT: case OPLATEARMOR: case OSSPLATE:
705 if (c[WEAR] != -1) { lprcat("\nYou're already wearing some armor"); return; }
706 c[WEAR]=i-'a'; bottomline(); return;
707 case OSHIELD: if (c[SHIELD] != -1) { lprcat("\nYou are already wearing a shield"); return; }
708 if (iven[c[WIELD]]==O2SWORD) { lprcat("\nYour hands are busy with the two handed sword!"); return; }
709 c[SHIELD] = i-'a'; bottomline(); return;
710 default: lprcat("\nYou can't wear that!");
711 };
712 }
713 }
714 }
715
716 /*
717 function to drop an object
718 */
719 dropobj()
720 {
721 register int i;
722 register char *p;
723 long amt;
724 p = &item[playerx][playery];
725 while (1)
726 {
727 if ((i = whatitem("drop"))=='\33') return;
728 if (i=='*') showstr(); else
729 {
730 if (i=='.') /* drop some gold */
731 {
732 if (*p) { lprcat("\nThere's something here already!"); return; }
733 lprcat("\n\n");
734 cl_dn(1,23);
735 lprcat("How much gold do you drop? ");
736 if ((amt=readnum((long)c[GOLD])) == 0) return;
737 if (amt>c[GOLD])
738 { lprcat("\nYou don't have that much!"); return; }
739 if (amt<=32767)
740 { *p=OGOLDPILE; i=amt; }
741 else if (amt<=327670L)
742 { *p=ODGOLD; i=amt/10; amt = 10*i; }
743 else if (amt<=3276700L)
744 { *p=OMAXGOLD; i=amt/100; amt = 100*i; }
745 else if (amt<=32767000L)
746 { *p=OKGOLD; i=amt/1000; amt = 1000*i; }
747 else
748 { *p=OKGOLD; i=32767; amt = 32767000L; }
749 c[GOLD] -= amt;
750 lprintf("You drop %d gold pieces",(long)amt);
751 iarg[playerx][playery]=i; bottomgold();
752 know[playerx][playery]=0; dropflag=1; return;
753 }
754 drop_object(i-'a');
755 return;
756 }
757 }
758 }
759
760 /*
761 * readscr() Subroutine to read a scroll one is carrying
762 */
763 readscr()
764 {
765 register int i;
766 while (1)
767 {
768 if ((i = whatitem("read"))=='\33') return;
769 if (i != '.')
770 {
771 if (i=='*') showread(); else
772 {
773 if (iven[i-'a']==OSCROLL) { read_scroll(ivenarg[i-'a']); iven[i-'a']=0; return; }
774 if (iven[i-'a']==OBOOK) { readbook(ivenarg[i-'a']); iven[i-'a']=0; return; }
775 if (iven[i-'a']==0) { ydhi(i); return; }
776 lprcat("\nThere's nothing on it to read"); return;
777 }
778 }
779 }
780 }
781
782 /*
783 * subroutine to eat a cookie one is carrying
784 */
785 eatcookie()
786 {
787 register int i;
788 char *p;
789 while (1)
790 {
791 if ((i = whatitem("eat"))=='\33') return;
792 if (i != '.')
793 if (i=='*') showeat(); else
794 {
795 if (iven[i-'a']==OCOOKIE)
796 {
797 lprcat("\nThe cookie was delicious.");
798 iven[i-'a']=0;
799 if (!c[BLINDCOUNT])
800 {
801 if (p=fortune())
802 {
803 lprcat(" Inside you find a scrap of paper that says:\n");
804 lprcat(p);
805 }
806 }
807 return;
808 }
809 if (iven[i-'a']==0) { ydhi(i); return; }
810 lprcat("\nYou can't eat that!"); return;
811 }
812 }
813 }
814
815 /*
816 * subroutine to quaff a potion one is carrying
817 */
818 quaff()
819 {
820 register int i;
821 while (1)
822 {
823 if ((i = whatitem("quaff"))=='\33') return;
824 if (i != '.')
825 {
826 if (i=='*') showquaff(); else
827 {
828 if (iven[i-'a']==OPOTION) { quaffpotion(ivenarg[i-'a']); iven[i-'a']=0; return; }
829 if (iven[i-'a']==0) { ydhi(i); return; }
830 lprcat("\nYou wouldn't want to quaff that, would you? "); return;
831 }
832 }
833 }
834 }
835
836 /*
837 function to ask what player wants to do
838 */
839 whatitem(str)
840 char *str;
841 {
842 int i;
843 cursors(); lprintf("\nWhat do you want to %s [* for all] ? ",str);
844 i=0; while (i>'z' || (i<'a' && i!='*' && i!='\33' && i!='.')) i=getchar();
845 if (i=='\33') lprcat(" aborted");
846 return(i);
847 }
848
849 /*
850 subroutine to get a number from the player
851 and allow * to mean return amt, else return the number entered
852 */
853 unsigned long readnum(mx)
854 long mx;
855 {
856 register int i;
857 register unsigned long amt=0;
858 sncbr();
859 if ((i=getchar()) == '*') amt = mx; /* allow him to say * for all gold */
860 else
861 while (i != '\n')
862 {
863 if (i=='\033') { scbr(); lprcat(" aborted"); return(0); }
864 if ((i <= '9') && (i >= '0') && (amt<99999999))
865 amt = amt*10+i-'0';
866 i = getchar();
867 }
868 scbr(); return(amt);
869 }
870
871 #ifdef HIDEBYLINK
872 /*
873 * routine to zero every byte in a string
874 */
875 szero(str)
876 register char *str;
877 {
878 while (*str)
879 *str++ = 0;
880 }
881 #endif HIDEBYLINK