Annotation of 43BSDTahoe/games/phantasia/main.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Phantasia 3.3.2 -- Interterminal fantasy game
                      3:  *
                      4:  * Edward A. Estes
                      5:  * AT&T, March 12, 1986
                      6:  */
                      7: 
                      8: /* DISCLAIMER:
                      9:  *
                     10:  * This game is distributed for free as is.  It is not guaranteed to work
                     11:  * in every conceivable environment.  It is not even guaranteed to work
                     12:  * in ANY environment.
                     13:  *
                     14:  * This game is distributed without notice of copyright, therefore it
                     15:  * may be used in any manner the recipient sees fit.  However, the
                     16:  * author assumes no responsibility for maintaining or revising this
                     17:  * game, in its original form, or any derivitives thereof.
                     18:  *
                     19:  * The author shall not be responsible for any loss, cost, or damage,
                     20:  * including consequential damage, caused by reliance on this material.
                     21:  *
                     22:  * The author makes no warranties, express or implied, including warranties
                     23:  * of merchantability or fitness for a particular purpose or use.
                     24:  *
                     25:  * AT&T is in no way connected with this game.
                     26:  */
                     27: 
                     28: /*
                     29:  * The program allocates as much file space as it needs to store characters,
                     30:  * so the possibility exists for the character file to grow without bound.
                     31:  * The file is purged upon normal entry to try to avoid that problem.
                     32:  * A similar problem exists for energy voids.  To alleviate the problem here,
                     33:  * the void file is cleared with every new king, and a limit is placed
                     34:  * on the size of the energy void file.
                     35:  */
                     36: 
                     37: /*
                     38:  * Put one line of text into the file 'motd' for announcements, etc.
                     39:  */
                     40: 
                     41: /*
                     42:  * If ENEMY is #defined, a list of restricted login names is checked
                     43:  * in the file 'enemy'.  These names are listed, one per line, with
                     44:  * no trailing blanks.
                     45:  */
                     46: 
                     47: /*
                     48:  * The scoreboard file is updated when someone dies, and keeps track
                     49:  * of the highest character to date for that login.
                     50:  * Being purged from the character file does not cause the scoreboard
                     51:  * to be updated.
                     52:  */
                     53: 
                     54: /*
                     55:  * All source files are set up for 'vi' with shiftwidth=4, tabstop=8. 
                     56:  */
                     57: 
                     58: /**/
                     59: 
                     60: /*
                     61:  * main.c      Main routines for Phantasia
                     62:  */
                     63: 
                     64: #include "include.h"
                     65: 
                     66: /***************************************************************************
                     67: / FUNCTION NAME: main()
                     68: /
                     69: / FUNCTION: initialize state, and call main process
                     70: /
                     71: / AUTHOR: E. A. Estes, 12/4/85
                     72: /
                     73: / ARGUMENTS:
                     74: /      int     argc - argument count
                     75: /      char    **argv - argument vector
                     76: /
                     77: / RETURN VALUE: none
                     78: /
                     79: / MODULES CALLED: monstlist(), checkenemy(), ok_to_play(), activelist(), 
                     80: /      throneroom(), checkbattle(), readmessage(), changestats(), writerecord(), 
                     81: /      tradingpost(), adjuststats(), recallplayer(), displaystats(), checktampered(), 
                     82: /      fabs(), rollnewplayer(), time(), exit(), sqrt(), floor(), wmove(), 
                     83: /      signal(), strcat(), purgeoldplayers(), getuid(), isatty(), wclear(), 
                     84: /      strcpy(), system(), altercoordinates(), cleanup(), waddstr(), procmain(), 
                     85: /      playinit(), leavegame(), localtime(), getanswer(), neatstuff(), initialstate(), 
                     86: /      scorelist(), titlelist()
                     87: /
                     88: / GLOBAL INPUTS: *Login, Throne, Wizard, Player, *stdscr, Changed, Databuf[], 
                     89: /      Fileloc, Helpfile[], Stattable[]
                     90: /
                     91: / GLOBAL OUTPUTS: Wizard, Player, Changed, Fileloc, Timeout, *Statptr
                     92: /
                     93: / DESCRIPTION:
                     94: /      Process arguments, initialize program, and loop forever processing
                     95: /      player input.
                     96: /
                     97: /***************************************************************************/
                     98: 
                     99: main(argc, argv)
                    100: int    argc;
                    101: char   **argv;
                    102: {
                    103: bool   noheader = FALSE;       /* set if don't want header */
                    104: bool   headeronly = FALSE;     /* set if only want header */
                    105: bool   examine = FALSE;        /* set if examine a character */
                    106: long   seconds;                /* for time of day */
                    107: double dtemp;                  /* for temporary calculations */
                    108: 
                    109:     initialstate();            /* init globals */
                    110: 
                    111: #ifdef ENEMY
                    112:     checkenemy();              /* check if denied access */
                    113: #endif
                    114: 
                    115:     /* process arguments */
                    116:     while (--argc && (*++argv)[0] == '-')
                    117:        switch ((*argv)[1])
                    118:            {
                    119:            case 's':   /* short */
                    120:                noheader = TRUE;
                    121:                break;
                    122: 
                    123:            case 'H':   /* Header */
                    124:                headeronly = TRUE;
                    125:                break;
                    126: 
                    127:            case 'a':   /* all users */
                    128:                activelist();
                    129:                cleanup(TRUE);
                    130:                /*NOTREACHED*/
                    131: 
                    132:            case 'p':   /* purge old players */
                    133:                purgeoldplayers();
                    134:                cleanup(TRUE);
                    135:                /*NOTREACHED*/
                    136: 
                    137:            case 'S':   /* set 'Wizard' */
                    138:                Wizard = (getuid() == UID);
                    139:                break;
                    140: 
                    141:            case 'x':   /* examine */
                    142:                examine = TRUE;
                    143:                break;
                    144: 
                    145:            case 'm':   /* monsters */
                    146:                monstlist();
                    147:                cleanup(TRUE);
                    148:                /*NOTREACHED*/
                    149: 
                    150:            case 'b':   /* scoreboard */
                    151:                scorelist();
                    152:                cleanup(TRUE);
                    153:                /*NOTREACHED*/
                    154: 
                    155:            case 'h':   /* help */
                    156:                cleanup(FALSE);
                    157:                strcpy(Databuf, "cat ");
                    158:                system(strcat(Databuf, Helpfile));
                    159:                exit(0);
                    160:                /*NOTREACHED*/
                    161:                }
                    162: 
                    163:     if (!isatty(0))            /* don't let non-tty's play */
                    164:        cleanup(TRUE);
                    165:        /*NOTREACHED*/
                    166: 
                    167:     playinit();                        /* set up to catch signals, init curses */
                    168: 
                    169:     if (examine)
                    170:        {
                    171:        changestats(FALSE);
                    172:        cleanup(TRUE);
                    173:        /*NOTREACHED*/
                    174:        }
                    175: 
                    176:     if (!noheader)
                    177:        {
                    178:        titlelist();
                    179:        purgeoldplayers();    /* clean up old characters */
                    180:        }
                    181: 
                    182:     if (headeronly)
                    183:        cleanup(TRUE);
                    184:        /*NOTREACHED*/
                    185: 
                    186: #ifdef OK_TO_PLAY
                    187:     if (!ok_to_play())
                    188:        {
                    189:        mvaddstr(23, 27, "Sorry, you can't play now.\n");
                    190:        cleanup(TRUE);
                    191:        /*NOTREACHED*/
                    192:        }
                    193: #endif
                    194: 
                    195:     do
                    196:        /* get the player structure filled */
                    197:        {
                    198:        Fileloc = -1L;
                    199: 
                    200:        mvaddstr(22, 17, "Do you have a character to run [Q = Quit] ? ");
                    201: 
                    202:        switch (getanswer("NYQ", FALSE))
                    203:            {
                    204:            case 'Y':
                    205:                Fileloc = recallplayer();
                    206:                break;
                    207: 
                    208:            case 'Q':
                    209:                cleanup(TRUE);
                    210:                /*NOTREACHED*/
                    211: 
                    212:            default:
                    213:                Fileloc = rollnewplayer();
                    214:                break;
                    215:            }
                    216:        clear();
                    217:        }
                    218:     while (Fileloc < 0L);
                    219: 
                    220:     if (Player.p_level > 5.0)
                    221:        /* low level players have long timeout */
                    222:        Timeout = TRUE;
                    223: 
                    224:     /* update some important player statistics */
                    225:     strcpy(Player.p_login, Login);
                    226:     time(&seconds);
                    227:     Player.p_lastused = localtime(&seconds)->tm_yday;
                    228:     Player.p_status = S_PLAYING;
                    229:     writerecord(&Player, Fileloc);
                    230: 
                    231:     Statptr = &Stattable[Player.p_type];       /* initialize pointer */
                    232: 
                    233:     /* catch interrupts */
                    234: #ifdef BSD41
                    235:     sigset(SIGINT, interrupt);
                    236: #endif
                    237: #ifdef BSD42
                    238:     signal(SIGINT, interrupt);
                    239: #endif
                    240: #ifdef SYS3
                    241:     signal(SIGINT, interrupt);
                    242: #endif
                    243: #ifdef SYS5
                    244:     signal(SIGINT, interrupt);
                    245: #endif
                    246: 
                    247:     altercoordinates(Player.p_x, Player.p_y, A_FORCED);        /* set some flags */
                    248: 
                    249:     clear();
                    250: 
                    251:     for (;;)
                    252:        /* loop forever, processing input */
                    253:        {
                    254: #ifdef OK_TO_PLAY
                    255:        if (!ok_to_play())
                    256:            {
                    257:            mvaddstr(6, 0, "Whoops!  Can't play now.\n");
                    258:            leavegame();
                    259:            /*NOTREACHED*/
                    260:            }
                    261: #endif
                    262: 
                    263:        adjuststats();          /* cleanup stats */
                    264: 
                    265:        if (Throne && Player.p_crowns == 0 && Player.p_specialtype != SC_KING)
                    266:            /* not allowed on throne -- move */
                    267:            {
                    268:            mvaddstr(5,0,"You're not allowed in the Lord's Chamber without a crown.\n");
                    269:            altercoordinates(0.0, 0.0, A_NEAR);
                    270:            }
                    271: 
                    272:        checktampered();        /* check for energy voids, etc. */
                    273: 
                    274:        if (Player.p_status != S_CLOAKED
                    275:            /* not cloaked */
                    276:            && (dtemp = fabs(Player.p_x)) == fabs(Player.p_y)
                    277:            /* |x| = |y| */
                    278:            && !Throne)
                    279:            /* not on throne */
                    280:            {
                    281:            dtemp = sqrt(dtemp / 100.0);
                    282:            if (floor(dtemp) == dtemp)
                    283:                /* |x| / 100 == n*n; at a trading post */
                    284:                {
                    285:                tradingpost();
                    286:                clear();
                    287:                }
                    288:            }
                    289: 
                    290:        checkbattle();          /* check for player to player battle */
                    291:        neatstuff();            /* gurus, medics, etc. */
                    292: 
                    293:        if (Player.p_status == S_CLOAKED)
                    294:            /* costs 3 mana per turn to be cloaked */
                    295:            if (Player.p_mana > 3.0)
                    296:                Player.p_mana -= 3.0;
                    297:            else
                    298:                /* ran out of mana, uncloak */
                    299:                {
                    300:                Player.p_status = S_PLAYING;
                    301:                Changed = TRUE;
                    302:                }
                    303: 
                    304:        if (Player.p_status != S_PLAYING && Player.p_status != S_CLOAKED)
                    305:            /* change status back to S_PLAYING */
                    306:            {
                    307:            Player.p_status = S_PLAYING;
                    308:            Changed = TRUE;
                    309:            }
                    310: 
                    311:        if (Changed)
                    312:            /* update file only if important stuff has changed */
                    313:            {
                    314:            writerecord(&Player, Fileloc);
                    315:            Changed = FALSE;
                    316:            continue;
                    317:            }
                    318: 
                    319:        readmessage();                  /* read message, if any */
                    320: 
                    321:        displaystats();                 /* print statistics */
                    322: 
                    323:        move(6, 0);
                    324: 
                    325:        if (Throne)
                    326:            /* maybe make king, print prompt, etc. */
                    327:            throneroom();
                    328: 
                    329:        /* print status line */
                    330:        addstr("1:Move  2:Players  3:Talk  4:Stats  5:Quit  ");
                    331:        if (Player.p_level >= MEL_CLOAK && Player.p_magiclvl >= ML_CLOAK)
                    332:            addstr("6:Cloak  ");
                    333:        if (Player.p_level >= MEL_TELEPORT && Player.p_magiclvl >= ML_TELEPORT)
                    334:            addstr("7:Teleport  ");
                    335:        if (Player.p_specialtype >= SC_COUNCIL || Wizard)
                    336:            addstr("8:Intervene  ");
                    337: 
                    338:        procmain();                     /* process input */
                    339:        }
                    340: }
                    341: /**/
                    342: /************************************************************************
                    343: /
                    344: / FUNCTION NAME: initialstate()
                    345: /
                    346: / FUNCTION: initialize some important global variable
                    347: /
                    348: / AUTHOR: E. A. Estes, 12/4/85
                    349: /
                    350: / ARGUMENTS: none
                    351: /
                    352: / RETURN VALUE: none
                    353: /
                    354: / MODULES CALLED: time(), fopen(), srandom(), error(), getuid(), getlogin(), 
                    355: /      getpwuid()
                    356: /
                    357: / GLOBAL INPUTS: Peoplefile[], Voidfile[], Messfile[], Monstfile[]
                    358: /
                    359: / GLOBAL OUTPUTS: *Energyvoidfp, Echo, Marsh, *Login, Users, Beyond, 
                    360: /      Throne, Wizard, Changed, Okcount, Timeout, Windows, *Monstfp, *Messagefp, 
                    361: /      *Playersfp
                    362: /
                    363: / DESCRIPTION:
                    364: /      Set global flags, and open files which remain open.
                    365: /
                    366: /************************************************************************/
                    367: 
                    368: initialstate()
                    369: {
                    370:     Beyond = FALSE;
                    371:     Marsh = FALSE;
                    372:     Throne = FALSE;
                    373:     Changed = FALSE;
                    374:     Wizard = FALSE;
                    375:     Timeout = FALSE;
                    376:     Users = 0;
                    377:     Windows = FALSE;
                    378:     Echo = TRUE;
                    379: #ifdef OK_TO_PLAY
                    380:     Okcount = 0;
                    381: #endif
                    382: 
                    383:     /* setup login name */
                    384:     if ((Login = getlogin()) == NULL)
                    385:        Login = getpwuid(getuid())->pw_name;
                    386:     
                    387:     /* open some files */
                    388:     if ((Playersfp = fopen(Peoplefile, "r+")) == NULL)
                    389:        error(Peoplefile);
                    390:        /*NOTREACHED*/
                    391: 
                    392:     if ((Monstfp = fopen(Monstfile, "r+")) == NULL)
                    393:        error(Monstfile);
                    394:        /*NOTREACHED*/
                    395: 
                    396:     if ((Messagefp = fopen(Messfile, "r")) == NULL)
                    397:        error(Messfile);
                    398:        /*NOTREACHED*/
                    399: 
                    400:     if ((Energyvoidfp = fopen(Voidfile, "r+")) == NULL)
                    401:        error(Voidfile);
                    402:        /*NOTREACHED*/
                    403: 
                    404:     srandom((unsigned) time((long *) NULL));   /* prime random numbers */
                    405: }
                    406: /**/
                    407: /************************************************************************
                    408: /
                    409: / FUNCTION NAME: rollnewplayer()
                    410: /
                    411: / FUNCTION: roll up a new character
                    412: /
                    413: / AUTHOR: E. A. Estes, 12/4/85
                    414: /
                    415: / ARGUMENTS: none
                    416: /
                    417: / RETURN VALUE: none
                    418: /
                    419: / MODULES CALLED: initplayer(), allocrecord(), truncstring(), fabs(), wmove(), 
                    420: /      wclear(), sscanf(), strcmp(), genchar(), waddstr(), findname(), mvprintw(), 
                    421: /      getanswer(), getstring()
                    422: /
                    423: / GLOBAL INPUTS: Other, Wizard, Player, *stdscr, Databuf[]
                    424: /
                    425: / GLOBAL OUTPUTS: Echo
                    426: /
                    427: / DESCRIPTION:
                    428: /      Prompt player, and roll up new character.
                    429: /
                    430: /************************************************************************/
                    431: 
                    432: long
                    433: rollnewplayer()
                    434: {
                    435: int    chartype;       /* character type */
                    436: int    ch;             /* input */
                    437: 
                    438:     initplayer(&Player);               /* initialize player structure */
                    439: 
                    440:     clear();
                    441:     mvaddstr(4, 21, "Which type of character do you want:");
                    442:     mvaddstr(8, 4, "1:Magic User  2:Fighter  3:Elf  4:Dwarf  5:Halfling  6:Experimento  ");
                    443:     if (Wizard) {
                    444:        addstr("7:Super  ? ");
                    445:        chartype = getanswer("1234567", FALSE);
                    446:        }
                    447:     else {
                    448:        addstr("?  ");
                    449:        chartype = getanswer("123456", FALSE);
                    450:        }
                    451: 
                    452:     do
                    453:        {
                    454:        genchar(chartype);              /* roll up a character */
                    455: 
                    456:        /* print out results */
                    457:        mvprintw(12, 14,
                    458:            "Strength    :  %2.0f  Quickness:  %2.0f  Mana       :  %2.0f\n",
                    459:            Player.p_strength, Player.p_quickness, Player.p_mana);
                    460:        mvprintw(13, 14,
                    461:            "Energy Level:  %2.0f  Brains   :  %2.0f  Magic Level:  %2.0f\n",
                    462:            Player.p_energy, Player.p_brains, Player.p_magiclvl);
                    463: 
                    464:        if (Player.p_type == C_EXPER || Player.p_type == C_SUPER)
                    465:            break;
                    466: 
                    467:        mvaddstr(14, 14, "Type '1' to keep >");
                    468:        ch = getanswer(" ", TRUE);
                    469:        }
                    470:     while (ch != '1');
                    471: 
                    472:     if (Player.p_type == C_EXPER || Player.p_type == C_SUPER)
                    473:        /* get coordinates for experimento */
                    474:        for (;;)
                    475:            {
                    476:            mvaddstr(16, 0, "Enter the X Y coordinates of your experimento ? ");
                    477:            getstring(Databuf, SZ_DATABUF);
                    478:            sscanf(Databuf, "%lf %lf", &Player.p_x, &Player.p_y);
                    479: 
                    480:            if (fabs(Player.p_x) > D_EXPER || fabs(Player.p_y) > D_EXPER)
                    481:                mvaddstr(17, 0, "Invalid coordinates.  Try again.\n");
                    482:            else
                    483:                break;
                    484:            }
                    485: 
                    486:     for (;;)
                    487:        /* name the new character */
                    488:        {
                    489:        mvprintw(18, 0,
                    490:            "Give your character a name [up to %d characters] ?  ", SZ_NAME - 1);
                    491:        getstring(Player.p_name, SZ_NAME);
                    492:        truncstring(Player.p_name);             /* remove trailing blanks */
                    493: 
                    494:        if (Player.p_name[0] == '\0')
                    495:            /* no null names */
                    496:            mvaddstr(19, 0, "Invalid name.");
                    497:        else if (findname(Player.p_name, &Other) >= 0L)
                    498:            /* cannot have duplicate names */
                    499:            mvaddstr(19, 0, "Name already in use.");
                    500:        else
                    501:            /* name is acceptable */
                    502:            break;
                    503: 
                    504:        addstr("  Pick another.\n");
                    505:        }
                    506: 
                    507:     /* get a password for character */
                    508:     Echo = FALSE;
                    509: 
                    510:     do
                    511:        {
                    512:        mvaddstr(20, 0, "Give your character a password [up to 8 characters] ? ");
                    513:        getstring(Player.p_password, SZ_PASSWORD);
                    514:        mvaddstr(21, 0, "One more time to verify ? ");
                    515:        getstring(Databuf, SZ_PASSWORD);
                    516:        }
                    517:     while (strcmp(Player.p_password, Databuf) != 0);
                    518: 
                    519:     Echo = TRUE;
                    520: 
                    521:     return(allocrecord());
                    522: }
                    523: /**/
                    524: /************************************************************************
                    525: /
                    526: / FUNCTION NAME: procmain()
                    527: /
                    528: / FUNCTION: process input from player
                    529: /
                    530: / AUTHOR: E. A. Estes, 12/4/85
                    531: /
                    532: / ARGUMENTS: none
                    533: /
                    534: / RETURN VALUE: none
                    535: /
                    536: / MODULES CALLED: dotampered(), changestats(), inputoption(), allstatslist(), 
                    537: /      fopen(), wmove(), drandom(), sscanf(), fclose(), altercoordinates(), 
                    538: /      waddstr(), fprintf(), distance(), userlist(), leavegame(), encounter(), 
                    539: /      getstring(), wclrtobot()
                    540: /
                    541: / GLOBAL INPUTS: Circle, Illcmd[], Throne, Wizard, Player, *stdscr, 
                    542: /      Databuf[], Illmove[], Messfile[]
                    543: /
                    544: / GLOBAL OUTPUTS: Player, Changed
                    545: /
                    546: / DESCRIPTION:
                    547: /      Process main menu options.
                    548: /
                    549: /************************************************************************/
                    550: 
                    551: procmain()
                    552: {
                    553: int    ch;                     /* input */
                    554: double x;                      /* desired new x coordinate */
                    555: double y;                      /* desired new y coordinate */
                    556: double temp;                   /* for temporary calculations */
                    557: FILE   *fp;                    /* for opening files */
                    558: register int   loop;           /* a loop counter */
                    559: bool   hasmoved = FALSE;       /* set if player has moved */
                    560: 
                    561:     ch = inputoption();
                    562:     mvaddstr(4, 0, "\n\n");            /* clear status area */
                    563: 
                    564:     move(7, 0);
                    565:     clrtobot();                        /* clear data on bottom area of screen */
                    566: 
                    567:     if (Player.p_specialtype == SC_VALAR && (ch == '1' || ch == '7'))
                    568:        /* valar cannot move */
                    569:        ch = ' ';
                    570: 
                    571:     switch (ch)
                    572:        {
                    573:        case 'K':               /* move up/north */
                    574:        case 'N':
                    575:            x = Player.p_x;
                    576:            y = Player.p_y + MAXMOVE();
                    577:            hasmoved = TRUE;
                    578:            break;
                    579: 
                    580:        case 'J':               /* move down/south */
                    581:        case 'S':
                    582:            x = Player.p_x;
                    583:            y = Player.p_y - MAXMOVE();
                    584:            hasmoved = TRUE;
                    585:            break;
                    586: 
                    587:        case 'L':               /* move right/east */
                    588:        case 'E':
                    589:            x = Player.p_x + MAXMOVE();
                    590:            y = Player.p_y;
                    591:            hasmoved = TRUE;
                    592:            break;
                    593: 
                    594:        case 'H':               /* move left/west */
                    595:        case 'W':
                    596:            x = Player.p_x - MAXMOVE();
                    597:            y = Player.p_y;
                    598:            hasmoved = TRUE;
                    599:            break;
                    600: 
                    601:        default:    /* rest */
                    602:            Player.p_energy += (Player.p_maxenergy + Player.p_shield) / 15.0
                    603:                + Player.p_level / 3.0 + 2.0;
                    604:            Player.p_energy =
                    605:                MIN(Player.p_energy, Player.p_maxenergy + Player.p_shield);
                    606: 
                    607:            if (Player.p_status != S_CLOAKED)
                    608:                /* cannot find mana if cloaked */
                    609:                {
                    610:                Player.p_mana += (Circle + Player.p_level) / 4.0;
                    611: 
                    612:                if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne)
                    613:                    /* wandering monster */
                    614:                    encounter(-1);
                    615:                }
                    616:            break;
                    617: 
                    618:        case 'X':               /* change/examine a character */
                    619:            changestats(TRUE);
                    620:            break;
                    621: 
                    622:        case '1':               /* move */
                    623:            for (loop = 3; loop; --loop)
                    624:                {
                    625:                mvaddstr(4, 0, "X Y Coordinates ? ");
                    626:                getstring(Databuf, SZ_DATABUF);
                    627: 
                    628:                if (sscanf(Databuf, "%lf %lf", &x, &y) != 2)
                    629:                    mvaddstr(5, 0, "Try again\n");
                    630:                else if (distance(Player.p_x, x, Player.p_y, y) > MAXMOVE())
                    631:                    ILLMOVE();
                    632:                else
                    633:                    {
                    634:                    hasmoved = TRUE;
                    635:                    break;
                    636:                    }
                    637:                }
                    638:            break;
                    639: 
                    640:        case '2':               /* players */
                    641:            userlist(TRUE);
                    642:            break;
                    643: 
                    644:        case '3':               /* message */
                    645:            mvaddstr(4, 0, "Message ? ");
                    646:            getstring(Databuf, SZ_DATABUF);
                    647:            /* we open the file for writing to erase any data which is already there */
                    648:            fp = fopen(Messfile, "w");
                    649:            if (Databuf[0] != '\0')
                    650:                fprintf(fp, "%s: %s", Player.p_name, Databuf);
                    651:            fclose(fp);
                    652:            break;
                    653: 
                    654:        case '4':               /* stats */
                    655:            allstatslist();
                    656:            break;
                    657: 
                    658:        case '5':               /* good-bye */
                    659:            leavegame();
                    660:            /*NOTREACHED*/
                    661: 
                    662:        case '6':               /* cloak */
                    663:            if (Player.p_level < MEL_CLOAK || Player.p_magiclvl < ML_CLOAK)
                    664:                ILLCMD();
                    665:            else if (Player.p_status == S_CLOAKED)
                    666:                Player.p_status = S_PLAYING;
                    667:            else if (Player.p_mana < MM_CLOAK)
                    668:                mvaddstr(5, 0, "No mana left.\n");
                    669:            else
                    670:                {
                    671:                Changed = TRUE;
                    672:                Player.p_mana -= MM_CLOAK;
                    673:                Player.p_status = S_CLOAKED;
                    674:                }
                    675:            break;
                    676: 
                    677:        case '7':       /* teleport */
                    678:            /*
                    679:             * conditions for teleport
                    680:             *  - 20 per (level plus magic level)
                    681:             *  - OR council of the wise or valar or ex-valar
                    682:             *  - OR transport from throne
                    683:             * transports from throne cost no mana
                    684:             */
                    685:            if (Player.p_level < MEL_TELEPORT || Player.p_magiclvl < ML_TELEPORT)
                    686:                ILLCMD();
                    687:            else 
                    688:                for (loop = 3; loop; --loop)
                    689:                    {
                    690:                    mvaddstr(4, 0, "X Y Coordinates ? ");
                    691:                    getstring(Databuf, SZ_DATABUF);
                    692: 
                    693:                    if (sscanf(Databuf, "%lf %lf", &x, &y) == 2)
                    694:                        {
                    695:                        temp = distance(Player.p_x, x, Player.p_y, y);
                    696:                        if (!Throne
                    697:                            /* can transport anywhere from throne */
                    698:                            && Player.p_specialtype <= SC_COUNCIL
                    699:                            /* council, valar can transport anywhere */
                    700:                            && temp > (Player.p_level + Player.p_magiclvl) * 20.0)
                    701:                            /* can only move 20 per exp. level + mag. level */
                    702:                            ILLMOVE();
                    703:                        else
                    704:                            {
                    705:                            temp = (temp / 75.0 + 1.0) * 20.0;  /* mana used */
                    706: 
                    707:                            if (!Throne && temp > Player.p_mana)
                    708:                                mvaddstr(5, 0, "Not enough power for that distance.\n");
                    709:                            else
                    710:                                {
                    711:                                if (!Throne)
                    712:                                    Player.p_mana -= temp;
                    713:                                hasmoved = TRUE;
                    714:                                break;
                    715:                                }
                    716:                            }
                    717:                        }
                    718:                    }
                    719:            break;
                    720: 
                    721:        case 'C':
                    722:        case '9':               /* monster */
                    723:            if (Throne)
                    724:                /* no monsters while on throne */
                    725:                mvaddstr(5, 0, "No monsters in the chamber!\n");
                    726:            else if (Player.p_specialtype != SC_VALAR)
                    727:                /* the valar cannot call monsters */
                    728:                {
                    729:                Player.p_sin += 1e-6;
                    730:                encounter(-1);
                    731:                }
                    732:            break;
                    733: 
                    734:        case '0':               /* decree */
                    735:            if (Wizard || Player.p_specialtype == SC_KING && Throne)
                    736:                /* kings must be on throne to decree */
                    737:                dotampered();
                    738:            else
                    739:                ILLCMD();
                    740:            break;
                    741: 
                    742:        case '8':               /* intervention */
                    743:            if (Wizard || Player.p_specialtype >= SC_COUNCIL)
                    744:                dotampered();
                    745:            else
                    746:                ILLCMD();
                    747:            break;
                    748:        }
                    749: 
                    750:     if (hasmoved)
                    751:        /* player has moved -- alter coordinates, and do random monster */
                    752:        {
                    753:        altercoordinates(x, y, A_SPECIFIC);
                    754: 
                    755:        if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne)
                    756:            encounter(-1);
                    757:        }
                    758: }
                    759: /**/
                    760: #ifdef ENEMY
                    761: /************************************************************************
                    762: /
                    763: / FUNCTION NAME: checkenemy()
                    764: /
                    765: / FUNCTION: check login name against enemy list
                    766: /
                    767: / AUTHOR: E. A. Estes, 12/4/85
                    768: /
                    769: / ARGUMENTS: none
                    770: /
                    771: / RETURN VALUE: none
                    772: /
                    773: / MODULES CALLED: fopen(), fgets(), strcmp(), fclose(), printf(), cleanup()
                    774: /
                    775: / GLOBAL INPUTS: *Login, Databuf[], Enemyfile[]
                    776: /
                    777: / GLOBAL OUTPUTS: none
                    778: /
                    779: / DESCRIPTION:
                    780: /      The enemy file has a list of login names which are denied
                    781: /      access to Phantasia.
                    782: /      We scan this list and exit if the current login name is
                    783: /      found in the list.
                    784: /
                    785: /************************************************************************/
                    786: 
                    787: checkenemy()
                    788: {
                    789: FILE   *fp;            /* to open enemy file */
                    790: 
                    791:     /* check hit list of restricted accounts */
                    792:     if ((fp = fopen(Enemyfile, "r")) != NULL)
                    793:        {
                    794:        while (fgets(Databuf, SZ_DATABUF, fp) != NULL)
                    795:            if (strcmp(Login, Databuf) == 0)
                    796:                {
                    797:                printf ("The Phantasia privileges for the account \"%s\" have been revoked.\n", Login);
                    798:                printf ("Mail comments to %s.\n", WIZARD);
                    799:                fclose(fp);
                    800:                cleanup(TRUE);
                    801:                /*NOTREACHED*/
                    802:                }
                    803:        fclose (fp);
                    804:        }
                    805: }
                    806: #endif
                    807: 
                    808: /**/
                    809: /************************************************************************
                    810: /
                    811: / FUNCTION NAME: titlelist()
                    812: /
                    813: / FUNCTION: print title page
                    814: /
                    815: / AUTHOR: E. A. Estes, 12/4/85
                    816: /
                    817: / ARGUMENTS: none
                    818: /
                    819: / RETURN VALUE: none
                    820: /
                    821: / MODULES CALLED: fread(), fseek(), fopen(), fgets(), wmove(), strcpy(), 
                    822: /      fclose(), strlen(), waddstr(), sprintf(), wrefresh()
                    823: /
                    824: / GLOBAL INPUTS: Lines, Other, *stdscr, Databuf[], Lastdead[], Motdfile[], 
                    825: /      *Playersfp
                    826: /
                    827: / GLOBAL OUTPUTS: Lines
                    828: /
                    829: / DESCRIPTION:
                    830: /      Print important information about game, players, etc.
                    831: /
                    832: /************************************************************************/
                    833: 
                    834: titlelist()
                    835: {
                    836: register FILE  *fp;            /* used for opening various files */
                    837: bool   councilfound = FALSE;   /* set if we find a member of the council */
                    838: bool   kingfound = FALSE;      /* set if we find a king */
                    839: double hiexp, nxtexp;          /* used for finding the two highest players */
                    840: double hilvl, nxtlvl;          /* used for finding the two highest players */
                    841: char   hiname[21], nxtname[21];/* used for finding the two highest players */
                    842: 
                    843:     mvaddstr(0, 14, "W e l c o m e   t o   P h a n t a s i a (vers. 3.3.2)!");
                    844: 
                    845:     /* print message of the day */
                    846:     if ((fp = fopen(Motdfile, "r")) != NULL
                    847:        && fgets(Databuf, SZ_DATABUF, fp) != NULL)
                    848:        {
                    849:        mvaddstr(2, 40 - strlen(Databuf) / 2, Databuf);
                    850:        fclose(fp);
                    851:        }
                    852: 
                    853:     /* search for king */
                    854:     fseek(Playersfp, 0L, 0);
                    855:     while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                    856:        if (Other.p_specialtype == SC_KING && Other.p_status != S_NOTUSED)
                    857:            /* found the king */
                    858:            {
                    859:            sprintf(Databuf, "The present ruler is %s  Level:%.0f",
                    860:                Other.p_name, Other.p_level);
                    861:            mvaddstr(4, 40 - strlen(Databuf) / 2, Databuf);
                    862:            kingfound = TRUE;
                    863:            break;
                    864:            }
                    865: 
                    866:     if (!kingfound)
                    867:        mvaddstr(4, 24, "There is no ruler at this time.");
                    868: 
                    869:     /* search for valar */
                    870:     fseek(Playersfp, 0L, 0);
                    871:     while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                    872:        if (Other.p_specialtype == SC_VALAR && Other.p_status != S_NOTUSED)
                    873:            /* found the valar */
                    874:            {
                    875:            sprintf(Databuf, "The Valar is %s   Login:  %s", Other.p_name, Other.p_login);
                    876:            mvaddstr(6, 40 - strlen(Databuf) / 2 , Databuf);
                    877:            break;
                    878:            }
                    879: 
                    880:     /* search for council of the wise */
                    881:     fseek(Playersfp, 0L, 0);
                    882:     Lines = 10;
                    883:     while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                    884:        if (Other.p_specialtype == SC_COUNCIL && Other.p_status != S_NOTUSED)
                    885:            /* found a member of the council */
                    886:            {
                    887:            if (!councilfound)
                    888:                {
                    889:                mvaddstr(8, 30, "Council of the Wise:");
                    890:                councilfound = TRUE;
                    891:                }
                    892: 
                    893:            /* This assumes a finite (<=5) number of C.O.W.: */
                    894:            sprintf(Databuf, "%s   Login:  %s", Other.p_name, Other.p_login);
                    895:            mvaddstr(Lines++, 40 - strlen(Databuf) / 2, Databuf);
                    896:            }
                    897: 
                    898:     /* search for the two highest players */
                    899:     nxtname[0] = hiname[0] = '\0';
                    900:     hiexp = 0.0;
                    901:     nxtlvl = hilvl = 0;
                    902: 
                    903:     fseek(Playersfp, 0L, 0);
                    904:     while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                    905:        if (Other.p_experience > hiexp && Other.p_specialtype <= SC_KING && Other.p_status != S_NOTUSED)
                    906:            /* highest found so far */
                    907:            {
                    908:            nxtexp = hiexp;
                    909:            hiexp = Other.p_experience;
                    910:            nxtlvl = hilvl;
                    911:            hilvl = Other.p_level;
                    912:            strcpy(nxtname, hiname);
                    913:            strcpy(hiname, Other.p_name);
                    914:            }
                    915:        else if (Other.p_experience > nxtexp
                    916:            && Other.p_specialtype <= SC_KING
                    917:            && Other.p_status != S_NOTUSED)
                    918:            /* next highest found so far */
                    919:            {
                    920:            nxtexp = Other.p_experience;
                    921:            nxtlvl = Other.p_level;
                    922:            strcpy(nxtname, Other.p_name);
                    923:            }
                    924: 
                    925:     mvaddstr(15, 28, "Highest characters are:");
                    926:     sprintf(Databuf, "%s  Level:%.0f   and   %s  Level:%.0f",
                    927:        hiname, hilvl, nxtname, nxtlvl);
                    928:     mvaddstr(17, 40 - strlen(Databuf) / 2, Databuf);
                    929: 
                    930:     /* print last to die */
                    931:     if ((fp = fopen(Lastdead,"r")) != NULL
                    932:        && fgets(Databuf, SZ_DATABUF, fp) != NULL)
                    933:        {
                    934:        mvaddstr(19, 25, "The last character to die was:");
                    935:        mvaddstr(20, 40 - strlen(Databuf) / 2,Databuf);
                    936:        fclose(fp);
                    937:        }
                    938: 
                    939:     refresh();
                    940: }
                    941: /**/
                    942: /************************************************************************
                    943: /
                    944: / FUNCTION NAME: recallplayer()
                    945: /
                    946: / FUNCTION: find a character on file
                    947: /
                    948: / AUTHOR: E. A. Estes, 12/4/85
                    949: /
                    950: / ARGUMENTS: none
                    951: /
                    952: / RETURN VALUE: none
                    953: /
                    954: / MODULES CALLED: writerecord(), truncstring(), more(), death(), wmove(), 
                    955: /      wclear(), strcmp(), printw(), cleanup(), waddstr(), findname(), mvprintw(), 
                    956: /      getanswer(), getstring()
                    957: /
                    958: / GLOBAL INPUTS: Player, *stdscr, Databuf[]
                    959: /
                    960: / GLOBAL OUTPUTS: Echo, Player
                    961: /
                    962: / DESCRIPTION:
                    963: /      Search for a character of a certain name, and check password.
                    964: /
                    965: /************************************************************************/
                    966: 
                    967: long
                    968: recallplayer()
                    969: {
                    970: long   loc = 0L;               /* location in player file */
                    971: register int   loop;           /* loop counter */
                    972: int    ch;                     /* input */
                    973: 
                    974:     clear();
                    975:     mvprintw(10, 0, "What was your character's name ? ");
                    976:     getstring(Databuf, SZ_NAME);
                    977:     truncstring(Databuf);
                    978: 
                    979:     if ((loc = findname(Databuf, &Player)) >= 0L)
                    980:        /* found character */
                    981:        {
                    982:        Echo = FALSE;
                    983: 
                    984:        for (loop = 0; loop < 2; ++loop)
                    985:            {
                    986:            /* prompt for password */
                    987:            mvaddstr(11, 0, "Password ? ");
                    988:            getstring(Databuf, SZ_PASSWORD);
                    989:            if (strcmp(Databuf, Player.p_password) == 0)
                    990:                /* password good */
                    991:                {
                    992:                Echo = TRUE;
                    993: 
                    994:                if (Player.p_status != S_OFF)
                    995:                    /* player did not exit normally last time */
                    996:                    {
                    997:                    clear();
                    998:                    addstr("Your character did not exit normally last time.\n");
                    999:                    addstr("If you think you have good cause to have your character saved,\n");
                   1000:                    printw("you may quit and mail your reason to '%s'.\n", WIZARD);
                   1001:                    addstr("Otherwise, continuing spells certain death.\n");
                   1002:                    addstr("Do you want to quit ? ");
                   1003:                    ch = getanswer("YN", FALSE);
                   1004:                    if (ch == 'Y')
                   1005:                        {
                   1006:                        Player.p_status = S_HUNGUP;
                   1007:                        writerecord(&Player, loc);
                   1008:                        cleanup(TRUE);
                   1009:                        /*NOTREACHED*/
                   1010:                        }
                   1011:                    death("Stupidity");
                   1012:                    /*NOTREACHED*/
                   1013:                    }
                   1014:                return(loc);
                   1015:                }
                   1016:            else
                   1017:                mvaddstr(12, 0, "No good.\n");
                   1018:            }
                   1019: 
                   1020:        Echo = TRUE;
                   1021:        }
                   1022:     else
                   1023:        mvaddstr(11, 0, "Not found.\n");
                   1024: 
                   1025:     more(13);
                   1026:     return(-1L);
                   1027: }
                   1028: /**/
                   1029: /************************************************************************
                   1030: /
                   1031: / FUNCTION NAME: neatstuff()
                   1032: /
                   1033: / FUNCTION: do random stuff
                   1034: /
                   1035: / AUTHOR: E. A. Estes, 3/3/86
                   1036: /
                   1037: / ARGUMENTS: none
                   1038: /
                   1039: / RETURN VALUE: none
                   1040: /
                   1041: / MODULES CALLED: collecttaxes(), floor(), wmove(), drandom(), infloat(), 
                   1042: /      waddstr(), mvprintw(), getanswer()
                   1043: /
                   1044: / GLOBAL INPUTS: Player, *stdscr, *Statptr
                   1045: /
                   1046: / GLOBAL OUTPUTS: Player
                   1047: /
                   1048: / DESCRIPTION:
                   1049: /      Handle gurus, medics, etc.
                   1050: /
                   1051: /************************************************************************/
                   1052: 
                   1053: neatstuff()
                   1054: {
                   1055: double temp;   /* for temporary calculations */
                   1056: int    ch;     /* input */
                   1057: 
                   1058:     switch ((int) ROLL(0.0, 100.0))
                   1059:        {
                   1060:        case 1:
                   1061:        case 2:
                   1062:            if (Player.p_poison > 0.0)
                   1063:                {
                   1064:                mvaddstr(4, 0, "You've found a medic!  How much will you offer to be cured ? ");
                   1065:                temp = floor(infloat());
                   1066:                if (temp < 0.0 || temp > Player.p_gold)
                   1067:                    /* negative gold, or more than available */
                   1068:                    {
                   1069:                    mvaddstr(6, 0, "He was not amused, and made you worse.\n");
                   1070:                    Player.p_poison += 1.0;
                   1071:                    }
                   1072:                else if (drandom() / 2.0 > (temp + 1.0) / MAX(Player.p_gold, 1))
                   1073:                    /* medic wants 1/2 of available gold */
                   1074:                    mvaddstr(5, 0, "Sorry, he wasn't interested.\n");
                   1075:                else
                   1076:                    {
                   1077:                    mvaddstr(5, 0, "He accepted.");
                   1078:                    Player.p_poison = MAX(0.0, Player.p_poison - 1.0);
                   1079:                    Player.p_gold -= temp;
                   1080:                    }
                   1081:                }
                   1082:            break;
                   1083: 
                   1084:        case 3:
                   1085:            mvaddstr(4, 0, "You've been caught raping and pillaging!\n");
                   1086:            Player.p_experience += 4000.0;
                   1087:            Player.p_sin += 0.5;
                   1088:            break;
                   1089: 
                   1090:        case 4:
                   1091:            temp = ROLL(10.0, 75.0);
                   1092:            mvprintw(4, 0, "You've found %.0f gold pieces, want them ? ", temp);
                   1093:            ch = getanswer("NY", FALSE);
                   1094: 
                   1095:            if (ch == 'Y')
                   1096:                collecttaxes(temp, 0.0);
                   1097:            break;
                   1098: 
                   1099:        case 5:
                   1100:            if (Player.p_sin > 1.0)
                   1101:                {
                   1102:                mvaddstr(4, 0, "You've found a Holy Orb!\n");
                   1103:                Player.p_sin -= 0.25;
                   1104:                }
                   1105:            break;
                   1106: 
                   1107:        case 6:
                   1108:            if (Player.p_poison < 1.0)
                   1109:                {
                   1110:                mvaddstr(4, 0, "You've been hit with a plague!\n");
                   1111:                Player.p_poison += 1.0;
                   1112:                }
                   1113:            break;
                   1114: 
                   1115:        case 7:
                   1116:            mvaddstr(4, 0, "You've found some holy water.\n");
                   1117:            ++Player.p_holywater;
                   1118:            break;
                   1119: 
                   1120:        case 8:
                   1121:            mvaddstr(4, 0, "You've met a Guru. . .");
                   1122:            if (drandom() * Player.p_sin > 1.0)
                   1123:                addstr("You disgusted him with your sins!\n");
                   1124:            else if (Player.p_poison > 0.0)
                   1125:                {
                   1126:                addstr("He looked kindly upon you, and cured you.\n");
                   1127:                Player.p_poison = 0.0;
                   1128:                }
                   1129:            else
                   1130:                {
                   1131:                addstr("He rewarded you for your virtue.\n");
                   1132:                Player.p_mana += 50.0;
                   1133:                Player.p_shield += 2.0;
                   1134:                }
                   1135:            break;
                   1136: 
                   1137:        case 9:
                   1138:            mvaddstr(4, 0, "You've found an amulet.\n");
                   1139:            ++Player.p_amulets;
                   1140:            break;
                   1141: 
                   1142:        case 10:
                   1143:            if (Player.p_blindness)
                   1144:                {
                   1145:                mvaddstr(4, 0, "You've regained your sight!\n");
                   1146:                Player.p_blindness = FALSE;
                   1147:                }
                   1148:            break;
                   1149: 
                   1150:        default:        /* deal with poison */
                   1151:            if (Player.p_poison > 0.0)
                   1152:                {
                   1153:                temp = Player.p_poison * Statptr->c_weakness
                   1154:                    * Player.p_maxenergy / 600.0;
                   1155:                if (Player.p_energy > Player.p_maxenergy / 10.0
                   1156:                    && temp + 5.0 < Player.p_energy)
                   1157:                    Player.p_energy -= temp;
                   1158:                }
                   1159:            break;
                   1160:        }
                   1161: }
                   1162: /**/
                   1163: /************************************************************************
                   1164: /
                   1165: / FUNCTION NAME: genchar()
                   1166: /
                   1167: / FUNCTION: generate a random character
                   1168: /
                   1169: / AUTHOR: E. A. Estes, 12/4/85
                   1170: /
                   1171: / ARGUMENTS:
                   1172: /      int type - ASCII value of character type to generate
                   1173: /
                   1174: / RETURN VALUE: none
                   1175: /
                   1176: / MODULES CALLED: floor(), drandom()
                   1177: /
                   1178: / GLOBAL INPUTS: Wizard, Player, Stattable[]
                   1179: /
                   1180: / GLOBAL OUTPUTS: Player
                   1181: /
                   1182: / DESCRIPTION:
                   1183: /      Use the lookup table for rolling stats.
                   1184: /
                   1185: /************************************************************************/
                   1186: 
                   1187: genchar(type)
                   1188: int    type;
                   1189: {
                   1190: register int   subscript;              /* used for subscripting into Stattable */
                   1191: register struct charstats      *statptr;/* for pointing into Stattable */
                   1192: 
                   1193:     subscript = type - '1';
                   1194: 
                   1195:     if (subscript < C_MAGIC || subscript > C_EXPER)
                   1196:        if (subscript != C_SUPER || !Wizard)
                   1197:            /* fighter is default */
                   1198:            subscript = C_FIGHTER;
                   1199:     
                   1200:     statptr = &Stattable[subscript];
                   1201: 
                   1202:     Player.p_quickness =
                   1203:        ROLL(statptr->c_quickness.base, statptr->c_quickness.interval);
                   1204:     Player.p_strength =
                   1205:        ROLL(statptr->c_strength.base, statptr->c_strength.interval);
                   1206:     Player.p_mana =
                   1207:        ROLL(statptr->c_mana.base, statptr->c_mana.interval);
                   1208:     Player.p_maxenergy =
                   1209:     Player.p_energy =
                   1210:        ROLL(statptr->c_energy.base, statptr->c_energy.interval);
                   1211:     Player.p_brains =
                   1212:        ROLL(statptr->c_brains.base, statptr->c_brains.interval);
                   1213:     Player.p_magiclvl =
                   1214:        ROLL(statptr->c_magiclvl.base, statptr->c_magiclvl.interval);
                   1215: 
                   1216:     Player.p_type = subscript;
                   1217: 
                   1218:     if (Player.p_type == C_HALFLING)
                   1219:        /* give halfling some experience */
                   1220:        Player.p_experience = ROLL(600.0, 200.0);
                   1221: }
                   1222: /**/
                   1223: /************************************************************************
                   1224: /
                   1225: / FUNCTION NAME: playinit()
                   1226: /
                   1227: / FUNCTION: initialize for playing game
                   1228: /
                   1229: / AUTHOR: E. A. Estes, 12/4/85
                   1230: /
                   1231: / ARGUMENTS: none
                   1232: /
                   1233: / RETURN VALUE: none
                   1234: /
                   1235: / MODULES CALLED: signal(), wclear(), noecho(), crmode(), initscr(), 
                   1236: /      wrefresh()
                   1237: /
                   1238: / GLOBAL INPUTS: *stdscr, ill_sig()
                   1239: /
                   1240: / GLOBAL OUTPUTS: Windows
                   1241: /
                   1242: / DESCRIPTION:
                   1243: /      Catch a bunch of signals, and turn on curses stuff.
                   1244: /
                   1245: /************************************************************************/
                   1246: 
                   1247: playinit()
                   1248: {
                   1249:     /* catch/ingnore signals */
                   1250: 
                   1251: #ifdef BSD41
                   1252:     sigignore(SIGQUIT);
                   1253:     sigignore(SIGALRM);
                   1254:     sigignore(SIGTERM);
                   1255:     sigignore(SIGTSTP);
                   1256:     sigignore(SIGTTIN);
                   1257:     sigignore(SIGTTOU);
                   1258:     sighold(SIGINT);
                   1259:     sigset(SIGHUP, ill_sig);
                   1260:     sigset(SIGTRAP, ill_sig);
                   1261:     sigset(SIGIOT, ill_sig);
                   1262:     sigset(SIGEMT, ill_sig);
                   1263:     sigset(SIGFPE, ill_sig);
                   1264:     sigset(SIGBUS, ill_sig);
                   1265:     sigset(SIGSEGV, ill_sig);
                   1266:     sigset(SIGSYS, ill_sig);
                   1267:     sigset(SIGPIPE, ill_sig);
                   1268: #endif
                   1269: #ifdef BSD42
                   1270:     signal(SIGQUIT, ill_sig);
                   1271:     signal(SIGALRM, SIG_IGN);
                   1272:     signal(SIGTERM, SIG_IGN);
                   1273:     signal(SIGTSTP, SIG_IGN);
                   1274:     signal(SIGTTIN, SIG_IGN);
                   1275:     signal(SIGTTOU, SIG_IGN);
                   1276:     signal(SIGINT, ill_sig);
                   1277:     signal(SIGHUP, SIG_DFL);
                   1278:     signal(SIGTRAP, ill_sig);
                   1279:     signal(SIGIOT, ill_sig);
                   1280:     signal(SIGEMT, ill_sig);
                   1281:     signal(SIGFPE, ill_sig);
                   1282:     signal(SIGBUS, ill_sig);
                   1283:     signal(SIGSEGV, ill_sig);
                   1284:     signal(SIGSYS, ill_sig);
                   1285:     signal(SIGPIPE, ill_sig);
                   1286: #endif
                   1287: #ifdef SYS3
                   1288:     signal(SIGINT, SIG_IGN);
                   1289:     signal(SIGQUIT, SIG_IGN);
                   1290:     signal(SIGTERM, SIG_IGN);
                   1291:     signal(SIGALRM, SIG_IGN);
                   1292:     signal(SIGHUP, ill_sig);
                   1293:     signal(SIGTRAP, ill_sig);
                   1294:     signal(SIGIOT, ill_sig);
                   1295:     signal(SIGEMT, ill_sig);
                   1296:     signal(SIGFPE, ill_sig);
                   1297:     signal(SIGBUS, ill_sig);
                   1298:     signal(SIGSEGV, ill_sig);
                   1299:     signal(SIGSYS, ill_sig);
                   1300:     signal(SIGPIPE, ill_sig);
                   1301: #endif
                   1302: #ifdef SYS5
                   1303:     signal(SIGINT, SIG_IGN);
                   1304:     signal(SIGQUIT, SIG_IGN);
                   1305:     signal(SIGTERM, SIG_IGN);
                   1306:     signal(SIGALRM, SIG_IGN);
                   1307:     signal(SIGHUP, ill_sig);
                   1308:     signal(SIGTRAP, ill_sig);
                   1309:     signal(SIGIOT, ill_sig);
                   1310:     signal(SIGEMT, ill_sig);
                   1311:     signal(SIGFPE, ill_sig);
                   1312:     signal(SIGBUS, ill_sig);
                   1313:     signal(SIGSEGV, ill_sig);
                   1314:     signal(SIGSYS, ill_sig);
                   1315:     signal(SIGPIPE, ill_sig);
                   1316: #endif
                   1317: 
                   1318:     initscr();         /* turn on curses */
                   1319:     noecho();          /* do not echo input */
                   1320:     crmode();          /* do not process erase, kill */
                   1321:     clear();
                   1322:     refresh();
                   1323:     Windows = TRUE;    /* mark the state */
                   1324: }
                   1325: 
                   1326: /**/
                   1327: /************************************************************************
                   1328: /
                   1329: / FUNCTION NAME: cleanup()
                   1330: /
                   1331: / FUNCTION: close some files, and maybe exit
                   1332: /
                   1333: / AUTHOR: E. A. Estes, 12/4/85
                   1334: /
                   1335: / ARGUMENTS:
                   1336: /      bool doexit - exit flag
                   1337: /
                   1338: / RETURN VALUE: none
                   1339: /
                   1340: / MODULES CALLED: exit(), wmove(), fclose(), endwin(), nocrmode(), wrefresh()
                   1341: /
                   1342: / GLOBAL INPUTS: *Energyvoidfp, LINES, *stdscr, Windows, *Monstfp, 
                   1343: /      *Messagefp, *Playersfp
                   1344: /
                   1345: / GLOBAL OUTPUTS: none
                   1346: /
                   1347: / DESCRIPTION:
                   1348: /      Close all open files.  If we are "in curses" terminate curses.
                   1349: /      If 'doexit' is set, exit, otherwise return.
                   1350: /
                   1351: /************************************************************************/
                   1352: 
                   1353: cleanup(doexit)
                   1354: bool   doexit;
                   1355: {
                   1356:     if (Windows)
                   1357:        {
                   1358:        move(LINES - 2, 0);
                   1359:        refresh();
                   1360:        nocrmode();
                   1361:        endwin();
                   1362:        }
                   1363: 
                   1364:     fclose(Playersfp);
                   1365:     fclose(Monstfp);
                   1366:     fclose(Messagefp);
                   1367:     fclose(Energyvoidfp);
                   1368: 
                   1369:     if (doexit)
                   1370:        exit(0);
                   1371:        /*NOTREACHED*/
                   1372: }
                   1373: /**/
                   1374: #ifdef OK_TO_PLAY
                   1375: #include <sys/types.h>
                   1376: #include <utmp.h>   /* used for counting users on system */
                   1377: 
                   1378: /************************************************************************
                   1379: /
                   1380: / FUNCTION NAME: ok_to_play()
                   1381: /
                   1382: / FUNCTION: indicate whether playing is allowed
                   1383: /
                   1384: / AUTHOR: E. A. Estes, 12/4/85
                   1385: /
                   1386: / ARGUMENTS: none
                   1387: /
                   1388: / RETURN VALUE:
                   1389: /      FALSE if playing is not allowed
                   1390: /      TRUE if playing is allowed
                   1391: /
                   1392: / MODULES CALLED: time(), fread(), fopen(), fclose(), localtime()
                   1393: /
                   1394: / GLOBAL INPUTS: Wizard, Okcount
                   1395: /
                   1396: / GLOBAL OUTPUTS: Okcount
                   1397: /
                   1398: / DESCRIPTION: 
                   1399: /      This function is provided to allow one to restrict access to the game.
                   1400: /      Tailor this routine as appropriate.
                   1401: /      Return FALSE if playing is not allowed at this time.
                   1402: /
                   1403: /************************************************************************/
                   1404: 
                   1405: ok_to_play()
                   1406: {
                   1407: register struct tm     *tp;    /* to get time of day */
                   1408: register int   numusers = 0;   /* number of users on system */
                   1409: FILE   *fp;                    /* to open files */
                   1410: long   now;                    /* present time */
                   1411: struct utmp    ubuf;           /* to read 'utmp' file */
                   1412: 
                   1413:     if (Wizard)
                   1414:        /* wizard can always play */
                   1415:        return(TRUE);
                   1416: 
                   1417:     if (Okcount >= 5)
                   1418:        Okcount = 0;
                   1419:     if (Okcount++ > 0)
                   1420:        /* only check every 5 times */
                   1421:        return(TRUE);
                   1422: 
                   1423:     /* check time of day */
                   1424:     time(&now);
                   1425:     tp = localtime(&now);
                   1426:     if (((tp->tm_hour > 8 && tp->tm_hour < 12)         /* 8-noon */
                   1427:        || (tp->tm_hour > 12 && tp->tm_hour < 16))      /* 1-4 pm */
                   1428:        && (tp->tm_wday != 0 && tp->tm_wday != 6))      /* not a weekend */
                   1429:            return(FALSE);
                   1430: 
                   1431:     /* check # of users */
                   1432:     if ((fp = fopen("/etc/utmp", "r")) != NULL)
                   1433:        {
                   1434:        while (fread((char *) &ubuf, sizeof(ubuf), 1, fp) == 1)
                   1435: #ifdef SYS5
                   1436:            if (ubuf.ut_type == USER_PROCESS)
                   1437: #else
                   1438:            if (ubuf.ut_name[0] != '\0')
                   1439: #endif
                   1440:                ++numusers;
                   1441:        fclose(fp);
                   1442: 
                   1443:        if (numusers > N_MAXUSERS)
                   1444:            return(FALSE);
                   1445:        }
                   1446:     return(TRUE);
                   1447: }
                   1448: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.