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