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