home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / TOP / USR / SRC / larn.t.Z / larn.t / main.c < prev    next >
C/C++ Source or Header  |  1988-11-13  |  26KB  |  954 lines

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