[BACK]Return to main.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / games / phantasia

Annotation of src/games/phantasia/main.c, Revision 1.16.20.1

1.16.20.1! wrstuden    1: /*     $NetBSD: main.c,v 1.16 2006/05/13 22:29:53 christos Exp $       */
1.2       cgd         2:
1.1       jtc         3: /*
                      4:  * Phantasia 3.3.2 -- Interterminal fantasy game
                      5:  *
                      6:  * Edward A. Estes
                      7:  * AT&T, March 12, 1986
                      8:  */
                      9:
                     10: /* DISCLAIMER:
                     11:  *
                     12:  * This game is distributed for free as is.  It is not guaranteed to work
                     13:  * in every conceivable environment.  It is not even guaranteed to work
                     14:  * in ANY environment.
                     15:  *
                     16:  * This game is distributed without notice of copyright, therefore it
                     17:  * may be used in any manner the recipient sees fit.  However, the
                     18:  * author assumes no responsibility for maintaining or revising this
                     19:  * game, in its original form, or any derivitives thereof.
                     20:  *
                     21:  * The author shall not be responsible for any loss, cost, or damage,
                     22:  * including consequential damage, caused by reliance on this material.
                     23:  *
                     24:  * The author makes no warranties, express or implied, including warranties
                     25:  * of merchantability or fitness for a particular purpose or use.
                     26:  *
                     27:  * AT&T is in no way connected with this game.
                     28:  */
                     29:
1.15      jmc        30: #include <sys/stat.h>
1.1       jtc        31: #include <sys/types.h>
                     32: #include <pwd.h>
                     33:
                     34: /*
                     35:  * The program allocates as much file space as it needs to store characters,
                     36:  * so the possibility exists for the character file to grow without bound.
                     37:  * The file is purged upon normal entry to try to avoid that problem.
                     38:  * A similar problem exists for energy voids.  To alleviate the problem here,
                     39:  * the void file is cleared with every new king, and a limit is placed
                     40:  * on the size of the energy void file.
                     41:  */
                     42:
                     43: /*
                     44:  * Put one line of text into the file 'motd' for announcements, etc.
                     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: /*
                     56:  * main.c      Main routines for Phantasia
                     57:  */
                     58:
                     59: #include "include.h"
1.14      he         60: #undef bool
1.13      ross       61: #include <curses.h>
1.1       jtc        62:
1.11      wiz        63: int    main(int, char **);
1.1       jtc        64:
1.4       lukem      65: int
1.1       jtc        66: main(argc, argv)
1.4       lukem      67:        int     argc;
                     68:        char  **argv;
1.1       jtc        69: {
1.4       lukem      70:        bool    noheader = FALSE;       /* set if don't want header */
                     71:        bool    headeronly = FALSE;     /* set if only want header */
                     72:        bool    examine = FALSE;        /* set if examine a character */
                     73:        time_t  seconds;                /* for time of day */
                     74:        double  dtemp;                  /* for temporary calculations */
                     75:
                     76:        initialstate();                 /* init globals */
                     77:
                     78:        /* process arguments */
                     79:        while (--argc && (*++argv)[0] == '-')
                     80:                switch ((*argv)[1]) {
                     81:                case 's':       /* short */
                     82:                        noheader = TRUE;
                     83:                        break;
                     84:
                     85:                case 'H':       /* Header */
                     86:                        headeronly = TRUE;
                     87:                        break;
1.1       jtc        88:
1.4       lukem      89:                case 'a':       /* all users */
                     90:                        activelist();
                     91:                        cleanup(TRUE);
                     92:                        /* NOTREACHED */
                     93:
                     94:                case 'p':       /* purge old players */
                     95:                        purgeoldplayers();
                     96:                        cleanup(TRUE);
                     97:                        /* NOTREACHED */
1.1       jtc        98:
1.4       lukem      99:                case 'S':       /* set 'Wizard' */
                    100:                        Wizard = !getuid();
                    101:                        break;
                    102:
                    103:                case 'x':       /* examine */
                    104:                        examine = TRUE;
                    105:                        break;
1.1       jtc       106:
1.4       lukem     107:                case 'm':       /* monsters */
                    108:                        monstlist();
                    109:                        cleanup(TRUE);
                    110:                        /* NOTREACHED */
1.1       jtc       111:
1.4       lukem     112:                case 'b':       /* scoreboard */
                    113:                        scorelist();
                    114:                        cleanup(TRUE);
                    115:                        /* NOTREACHED */
                    116:                }
1.1       jtc       117:
1.4       lukem     118:        if (!isatty(0))         /* don't let non-tty's play */
1.1       jtc       119:                cleanup(TRUE);
1.4       lukem     120:        /* NOTREACHED */
1.1       jtc       121:
1.4       lukem     122:        playinit();             /* set up to catch signals, init curses */
1.1       jtc       123:
1.4       lukem     124:        if (examine) {
                    125:                changestats(FALSE);
1.1       jtc       126:                cleanup(TRUE);
1.4       lukem     127:                /* NOTREACHED */
1.1       jtc       128:        }
1.4       lukem     129:        if (!noheader) {
                    130:                titlelist();
                    131:                purgeoldplayers();      /* clean up old characters */
1.1       jtc       132:        }
1.4       lukem     133:        if (headeronly)
                    134:                cleanup(TRUE);
                    135:        /* NOTREACHED */
1.1       jtc       136:
1.4       lukem     137:        do
                    138:                /* get the player structure filled */
1.1       jtc       139:        {
1.4       lukem     140:                Fileloc = -1L;
1.1       jtc       141:
1.4       lukem     142:                mvaddstr(22, 17, "Do you have a character to run [Q = Quit] ? ");
1.1       jtc       143:
1.4       lukem     144:                switch (getanswer("NYQ", FALSE)) {
                    145:                case 'Y':
                    146:                        Fileloc = recallplayer();
                    147:                        break;
1.1       jtc       148:
1.4       lukem     149:                case 'Q':
                    150:                        cleanup(TRUE);
                    151:                        /* NOTREACHED */
1.1       jtc       152:
1.4       lukem     153:                default:
                    154:                        Fileloc = rollnewplayer();
                    155:                        break;
                    156:                }
                    157:                clear();
1.1       jtc       158:        }
1.4       lukem     159:        while (Fileloc < 0L);
1.1       jtc       160:
1.4       lukem     161:        if (Player.p_level > 5.0)
                    162:                /* low level players have long timeout */
                    163:                Timeout = TRUE;
                    164:
                    165:        /* update some important player statistics */
                    166:        strcpy(Player.p_login, Login);
                    167:        time(&seconds);
                    168:        Player.p_lastused = localtime(&seconds)->tm_yday;
                    169:        Player.p_status = S_PLAYING;
                    170:        writerecord(&Player, Fileloc);
1.1       jtc       171:
1.4       lukem     172:        Statptr = &Stattable[Player.p_type];    /* initialize pointer */
1.1       jtc       173:
1.4       lukem     174:        /* catch interrupts */
1.1       jtc       175: #ifdef BSD41
1.4       lukem     176:        sigset(SIGINT, interrupt);
1.1       jtc       177: #endif
                    178: #ifdef BSD42
1.4       lukem     179:        signal(SIGINT, interrupt);
1.1       jtc       180: #endif
                    181: #ifdef SYS3
1.4       lukem     182:        signal(SIGINT, interrupt);
1.1       jtc       183: #endif
                    184: #ifdef SYS5
1.4       lukem     185:        signal(SIGINT, interrupt);
1.1       jtc       186: #endif
                    187:
1.4       lukem     188:        altercoordinates(Player.p_x, Player.p_y, A_FORCED);     /* set some flags */
1.1       jtc       189:
1.4       lukem     190:        clear();
1.1       jtc       191:
1.4       lukem     192:        for (;;)
                    193:                /* loop forever, processing input */
1.1       jtc       194:        {
                    195:
1.4       lukem     196:                adjuststats();  /* cleanup stats */
                    197:
                    198:                if (Throne && Player.p_crowns == 0 && Player.p_specialtype != SC_KING)
                    199:                        /* not allowed on throne -- move */
                    200:                {
                    201:                        mvaddstr(5, 0, "You're not allowed in the Lord's Chamber without a crown.\n");
                    202:                        altercoordinates(0.0, 0.0, A_NEAR);
                    203:                }
                    204:                checktampered();/* check for energy voids, etc. */
1.1       jtc       205:
1.4       lukem     206:                if (Player.p_status != S_CLOAKED
                    207:                /* not cloaked */
                    208:                    && (dtemp = fabs(Player.p_x)) == fabs(Player.p_y)
                    209:                /* |x| = |y| */
                    210:                    && !Throne)
                    211:                        /* not on throne */
1.1       jtc       212:                {
1.4       lukem     213:                        dtemp = sqrt(dtemp / 100.0);
                    214:                        if (floor(dtemp) == dtemp)
                    215:                                /* |x| / 100 == n*n; at a trading post */
                    216:                        {
                    217:                                tradingpost();
                    218:                                clear();
                    219:                        }
1.1       jtc       220:                }
1.4       lukem     221:                checkbattle();  /* check for player to player battle */
                    222:                neatstuff();    /* gurus, medics, etc. */
1.1       jtc       223:
1.5       veego     224:                if (Player.p_status == S_CLOAKED) {
1.4       lukem     225:                        /* costs 3 mana per turn to be cloaked */
                    226:                        if (Player.p_mana > 3.0)
                    227:                                Player.p_mana -= 3.0;
                    228:                        else
                    229:                                /* ran out of mana, uncloak */
                    230:                        {
                    231:                                Player.p_status = S_PLAYING;
                    232:                                Changed = TRUE;
                    233:                        }
1.5       veego     234:                }
1.1       jtc       235:
1.4       lukem     236:                if (Player.p_status != S_PLAYING && Player.p_status != S_CLOAKED)
                    237:                        /* change status back to S_PLAYING */
1.1       jtc       238:                {
1.4       lukem     239:                        Player.p_status = S_PLAYING;
                    240:                        Changed = TRUE;
1.1       jtc       241:                }
1.4       lukem     242:                if (Changed)
                    243:                        /* update file only if important stuff has changed */
                    244:                {
                    245:                        writerecord(&Player, Fileloc);
                    246:                        Changed = FALSE;
                    247:                        continue;
                    248:                }
                    249:                readmessage();  /* read message, if any */
                    250:
                    251:                displaystats(); /* print statistics */
1.1       jtc       252:
1.4       lukem     253:                move(6, 0);
1.1       jtc       254:
1.4       lukem     255:                if (Throne)
                    256:                        /* maybe make king, print prompt, etc. */
                    257:                        throneroom();
                    258:
                    259:                /* print status line */
                    260:                addstr("1:Move  2:Players  3:Talk  4:Stats  5:Quit  ");
                    261:                if (Player.p_level >= MEL_CLOAK && Player.p_magiclvl >= ML_CLOAK)
                    262:                        addstr("6:Cloak  ");
                    263:                if (Player.p_level >= MEL_TELEPORT && Player.p_magiclvl >= ML_TELEPORT)
                    264:                        addstr("7:Teleport  ");
                    265:                if (Player.p_specialtype >= SC_COUNCIL || Wizard)
                    266:                        addstr("8:Intervene  ");
                    267:
                    268:                procmain();     /* process input */
1.1       jtc       269:        }
                    270: }
                    271:
1.4       lukem     272: void
1.1       jtc       273: initialstate()
                    274: {
1.15      jmc       275:        struct stat sb;
                    276:
1.4       lukem     277:        Beyond = FALSE;
                    278:        Marsh = FALSE;
                    279:        Throne = FALSE;
                    280:        Changed = FALSE;
                    281:        Wizard = FALSE;
                    282:        Timeout = FALSE;
                    283:        Users = 0;
                    284:        Windows = FALSE;
                    285:        Echo = TRUE;
1.1       jtc       286:
1.4       lukem     287:        /* setup login name */
                    288:        if ((Login = getlogin()) == NULL)
                    289:                Login = getpwuid(getuid())->pw_name;
                    290:
                    291:        /* open some files */
                    292:        if ((Playersfp = fopen(_PATH_PEOPLE, "r+")) == NULL)
                    293:                error(_PATH_PEOPLE);
                    294:        /* NOTREACHED */
1.9       jsm       295:        if (fileno(Playersfp) < 3)
                    296:                exit(1);
1.4       lukem     297:
                    298:        if ((Monstfp = fopen(_PATH_MONST, "r+")) == NULL)
                    299:                error(_PATH_MONST);
                    300:        /* NOTREACHED */
                    301:
                    302:        if ((Messagefp = fopen(_PATH_MESS, "r")) == NULL)
                    303:                error(_PATH_MESS);
                    304:        /* NOTREACHED */
                    305:
                    306:        if ((Energyvoidfp = fopen(_PATH_VOID, "r+")) == NULL)
                    307:                error(_PATH_VOID);
1.15      jmc       308:        if (fstat(fileno(Energyvoidfp), &sb) == -1)
                    309:                error("stat");
                    310:        if (sb.st_size == 0) {
                    311:                /* initialize grail to new location */
                    312:                Enrgyvoid.ev_active = TRUE;
                    313:                Enrgyvoid.ev_x = ROLL(-1.0e6, 2.0e6);
                    314:                Enrgyvoid.ev_y = ROLL(-1.0e6, 2.0e6);
                    315:                writevoid(&Enrgyvoid, 0L);
                    316:        }
                    317:
1.4       lukem     318:        /* NOTREACHED */
                    319:
                    320:        srandom((unsigned) time(NULL)); /* prime random numbers */
1.1       jtc       321: }
                    322:
                    323: long
                    324: rollnewplayer()
                    325: {
1.4       lukem     326:        int     chartype;       /* character type */
                    327:        int     ch;             /* input */
1.1       jtc       328:
1.4       lukem     329:        initplayer(&Player);    /* initialize player structure */
1.1       jtc       330:
1.4       lukem     331:        clear();
                    332:        mvaddstr(4, 21, "Which type of character do you want:");
                    333:        mvaddstr(8, 4,
                    334: "1:Magic User  2:Fighter  3:Elf  4:Dwarf  5:Halfling  6:Experimento  ");
                    335:        if (Wizard) {
                    336:                addstr("7:Super  ? ");
                    337:                chartype = getanswer("1234567", FALSE);
                    338:        } else {
                    339:                addstr("?  ");
                    340:                chartype = getanswer("123456", FALSE);
                    341:        }
                    342:
                    343:        do {
                    344:                genchar(chartype);      /* roll up a character */
                    345:
                    346:                /* print out results */
                    347:                mvprintw(12, 14,
                    348:                    "Strength    :  %2.0f  Quickness:  %2.0f  Mana       :  %2.0f\n",
                    349:                    Player.p_strength, Player.p_quickness, Player.p_mana);
                    350:                mvprintw(13, 14,
                    351:                    "Energy Level:  %2.0f  Brains   :  %2.0f  Magic Level:  %2.0f\n",
                    352:                    Player.p_energy, Player.p_brains, Player.p_magiclvl);
1.1       jtc       353:
1.4       lukem     354:                if (Player.p_type == C_EXPER || Player.p_type == C_SUPER)
                    355:                        break;
1.1       jtc       356:
1.4       lukem     357:                mvaddstr(14, 14, "Type '1' to keep >");
                    358:                ch = getanswer(" ", TRUE);
                    359:        }
                    360:        while (ch != '1');
1.1       jtc       361:
                    362:        if (Player.p_type == C_EXPER || Player.p_type == C_SUPER)
1.4       lukem     363:                /* get coordinates for experimento */
                    364:                for (;;) {
                    365:                        mvaddstr(16, 0, "Enter the X Y coordinates of your experimento ? ");
                    366:                        getstring(Databuf, SZ_DATABUF);
                    367:                        sscanf(Databuf, "%lf %lf", &Player.p_x, &Player.p_y);
1.1       jtc       368:
1.4       lukem     369:                        if (fabs(Player.p_x) > D_EXPER || fabs(Player.p_y) > D_EXPER)
                    370:                                mvaddstr(17, 0, "Invalid coordinates.  Try again.\n");
                    371:                        else
                    372:                                break;
                    373:                }
1.1       jtc       374:
                    375:        for (;;)
1.4       lukem     376:                /* name the new character */
1.1       jtc       377:        {
1.4       lukem     378:                mvprintw(18, 0,
                    379:                    "Give your character a name [up to %d characters] ?  ", SZ_NAME - 1);
                    380:                getstring(Player.p_name, SZ_NAME);
                    381:                truncstring(Player.p_name);     /* remove trailing blanks */
                    382:
                    383:                if (Player.p_name[0] == '\0')
                    384:                        /* no null names */
                    385:                        mvaddstr(19, 0, "Invalid name.");
                    386:                else
                    387:                        if (findname(Player.p_name, &Other) >= 0L)
                    388:                                /* cannot have duplicate names */
                    389:                                mvaddstr(19, 0, "Name already in use.");
                    390:                        else
                    391:                                /* name is acceptable */
                    392:                                break;
1.1       jtc       393:
1.4       lukem     394:                addstr("  Pick another.\n");
1.1       jtc       395:        }
                    396:
1.4       lukem     397:        /* get a password for character */
                    398:        Echo = FALSE;
1.1       jtc       399:
1.4       lukem     400:        do {
                    401:                mvaddstr(20, 0, "Give your character a password [up to 8 characters] ? ");
                    402:                getstring(Player.p_password, SZ_PASSWORD);
1.6       hubertf   403:                mvaddstr(21, 0, "Enter again to verify: ");
1.4       lukem     404:                getstring(Databuf, SZ_PASSWORD);
1.1       jtc       405:        }
1.4       lukem     406:        while (strcmp(Player.p_password, Databuf) != 0);
1.1       jtc       407:
1.4       lukem     408:        Echo = TRUE;
1.1       jtc       409:
1.4       lukem     410:        return (allocrecord());
1.1       jtc       411: }
                    412:
1.4       lukem     413: void
1.1       jtc       414: procmain()
                    415: {
1.4       lukem     416:        int     ch;             /* input */
                    417:        double  x;              /* desired new x coordinate */
                    418:        double  y;              /* desired new y coordinate */
                    419:        double  temp;           /* for temporary calculations */
                    420:        FILE   *fp;             /* for opening files */
                    421:        int     loop;           /* a loop counter */
                    422:        bool    hasmoved = FALSE;       /* set if player has moved */
                    423:
                    424:        ch = inputoption();
                    425:        mvaddstr(4, 0, "\n\n"); /* clear status area */
                    426:
                    427:        move(7, 0);
                    428:        clrtobot();             /* clear data on bottom area of screen */
                    429:
                    430:        if (Player.p_specialtype == SC_VALAR && (ch == '1' || ch == '7'))
                    431:                /* valar cannot move */
                    432:                ch = ' ';
1.1       jtc       433:
1.4       lukem     434:        switch (ch) {
1.1       jtc       435:        case 'K':               /* move up/north */
                    436:        case 'N':
1.4       lukem     437:                x = Player.p_x;
                    438:                y = Player.p_y + MAXMOVE();
                    439:                hasmoved = TRUE;
                    440:                break;
1.1       jtc       441:
                    442:        case 'J':               /* move down/south */
                    443:        case 'S':
1.4       lukem     444:                x = Player.p_x;
                    445:                y = Player.p_y - MAXMOVE();
                    446:                hasmoved = TRUE;
                    447:                break;
1.1       jtc       448:
                    449:        case 'L':               /* move right/east */
                    450:        case 'E':
1.4       lukem     451:                x = Player.p_x + MAXMOVE();
                    452:                y = Player.p_y;
                    453:                hasmoved = TRUE;
                    454:                break;
1.1       jtc       455:
                    456:        case 'H':               /* move left/west */
                    457:        case 'W':
1.4       lukem     458:                x = Player.p_x - MAXMOVE();
                    459:                y = Player.p_y;
                    460:                hasmoved = TRUE;
                    461:                break;
1.1       jtc       462:
1.4       lukem     463:        default:                /* rest */
                    464:                Player.p_energy += (Player.p_maxenergy + Player.p_shield) / 15.0
                    465:                    + Player.p_level / 3.0 + 2.0;
                    466:                Player.p_energy =
                    467:                    MIN(Player.p_energy, Player.p_maxenergy + Player.p_shield);
                    468:
                    469:                if (Player.p_status != S_CLOAKED)
                    470:                        /* cannot find mana if cloaked */
                    471:                {
                    472:                        Player.p_mana += (Circle + Player.p_level) / 4.0;
                    473:
                    474:                        if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne)
                    475:                                /* wandering monster */
                    476:                                encounter(-1);
1.1       jtc       477:                }
1.4       lukem     478:                break;
1.1       jtc       479:
                    480:        case 'X':               /* change/examine a character */
1.4       lukem     481:                changestats(TRUE);
                    482:                break;
1.1       jtc       483:
                    484:        case '1':               /* move */
1.4       lukem     485:                for (loop = 3; loop; --loop) {
                    486:                        mvaddstr(4, 0, "X Y Coordinates ? ");
                    487:                        getstring(Databuf, SZ_DATABUF);
1.1       jtc       488:
1.4       lukem     489:                        if (sscanf(Databuf, "%lf %lf", &x, &y) != 2)
                    490:                                mvaddstr(5, 0, "Try again\n");
                    491:                        else
                    492:                                if (distance(Player.p_x, x, Player.p_y, y) > MAXMOVE())
                    493:                                        ILLMOVE();
                    494:                                else {
                    495:                                        hasmoved = TRUE;
                    496:                                        break;
                    497:                                }
1.1       jtc       498:                }
1.4       lukem     499:                break;
1.1       jtc       500:
                    501:        case '2':               /* players */
1.4       lukem     502:                userlist(TRUE);
                    503:                break;
1.1       jtc       504:
                    505:        case '3':               /* message */
1.4       lukem     506:                mvaddstr(4, 0, "Message ? ");
                    507:                getstring(Databuf, SZ_DATABUF);
                    508:                /* we open the file for writing to erase any data which is
                    509:                 * already there */
                    510:                fp = fopen(_PATH_MESS, "w");
                    511:                if (Databuf[0] != '\0')
                    512:                        fprintf(fp, "%s: %s", Player.p_name, Databuf);
                    513:                fclose(fp);
                    514:                break;
1.1       jtc       515:
                    516:        case '4':               /* stats */
1.4       lukem     517:                allstatslist();
                    518:                break;
1.1       jtc       519:
                    520:        case '5':               /* good-bye */
1.4       lukem     521:                leavegame();
                    522:                /* NOTREACHED */
1.1       jtc       523:
                    524:        case '6':               /* cloak */
1.4       lukem     525:                if (Player.p_level < MEL_CLOAK || Player.p_magiclvl < ML_CLOAK)
                    526:                        ILLCMD();
                    527:                else
                    528:                        if (Player.p_status == S_CLOAKED)
                    529:                                Player.p_status = S_PLAYING;
1.1       jtc       530:                        else
1.4       lukem     531:                                if (Player.p_mana < MM_CLOAK)
                    532:                                        mvaddstr(5, 0, "No mana left.\n");
                    533:                                else {
                    534:                                        Changed = TRUE;
                    535:                                        Player.p_mana -= MM_CLOAK;
                    536:                                        Player.p_status = S_CLOAKED;
                    537:                                }
                    538:                break;
1.1       jtc       539:
1.4       lukem     540:        case '7':               /* teleport */
                    541:                /*
                    542:                 * conditions for teleport
                    543:                 *      - 20 per (level plus magic level)
                    544:                 *      - OR council of the wise or valar or ex-valar
                    545:                 *      - OR transport from throne
                    546:                 * transports from throne cost no mana
                    547:                 */
                    548:                if (Player.p_level < MEL_TELEPORT || Player.p_magiclvl < ML_TELEPORT)
                    549:                        ILLCMD();
                    550:                else
                    551:                        for (loop = 3; loop; --loop) {
                    552:                                mvaddstr(4, 0, "X Y Coordinates ? ");
                    553:                                getstring(Databuf, SZ_DATABUF);
                    554:
                    555:                                if (sscanf(Databuf, "%lf %lf", &x, &y) == 2) {
                    556:                                        temp = distance(Player.p_x, x, Player.p_y, y);
                    557:                                        if (!Throne
                    558:                                        /* can transport anywhere from throne */
                    559:                                            && Player.p_specialtype <= SC_COUNCIL
                    560:                                        /* council, valar can transport
                    561:                                         * anywhere */
                    562:                                            && temp > (Player.p_level + Player.p_magiclvl) * 20.0)
                    563:                                                /* can only move 20 per exp.
                    564:                                                 * level + mag. level */
                    565:                                                ILLMOVE();
                    566:                                        else {
                    567:                                                temp = (temp / 75.0 + 1.0) * 20.0;      /* mana used */
                    568:
                    569:                                                if (!Throne && temp > Player.p_mana)
                    570:                                                        mvaddstr(5, 0, "Not enough power for that distance.\n");
                    571:                                                else {
                    572:                                                        if (!Throne)
                    573:                                                                Player.p_mana -= temp;
                    574:                                                        hasmoved = TRUE;
                    575:                                                        break;
                    576:                                                }
                    577:                                        }
1.1       jtc       578:                                }
                    579:                        }
1.4       lukem     580:                break;
1.1       jtc       581:
                    582:        case 'C':
                    583:        case '9':               /* monster */
1.4       lukem     584:                if (Throne)
                    585:                        /* no monsters while on throne */
                    586:                        mvaddstr(5, 0, "No monsters in the chamber!\n");
                    587:                else
                    588:                        if (Player.p_specialtype != SC_VALAR)
                    589:                                /* the valar cannot call monsters */
                    590:                        {
                    591:                                Player.p_sin += 1e-6;
                    592:                                encounter(-1);
                    593:                        }
                    594:                break;
1.1       jtc       595:
                    596:        case '0':               /* decree */
1.4       lukem     597:                if (Wizard || (Player.p_specialtype == SC_KING && Throne))
                    598:                        /* kings must be on throne to decree */
                    599:                        dotampered();
                    600:                else
                    601:                        ILLCMD();
                    602:                break;
1.1       jtc       603:
                    604:        case '8':               /* intervention */
1.4       lukem     605:                if (Wizard || Player.p_specialtype >= SC_COUNCIL)
                    606:                        dotampered();
                    607:                else
                    608:                        ILLCMD();
                    609:                break;
1.1       jtc       610:        }
                    611:
1.4       lukem     612:        if (hasmoved)
                    613:                /* player has moved -- alter coordinates, and do random
                    614:                 * monster */
1.1       jtc       615:        {
1.4       lukem     616:                altercoordinates(x, y, A_SPECIFIC);
1.1       jtc       617:
1.4       lukem     618:                if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne)
                    619:                        encounter(-1);
1.1       jtc       620:        }
                    621: }
                    622:
1.4       lukem     623: void
1.1       jtc       624: titlelist()
                    625: {
1.4       lukem     626:        FILE   *fp;             /* used for opening various files */
                    627:        bool    councilfound = FALSE;   /* set if we find a member of the
                    628:                                         * council */
                    629:        bool    kingfound = FALSE;      /* set if we find a king */
                    630:        double  hiexp, nxtexp;  /* used for finding the two highest players */
                    631:        double  hilvl, nxtlvl;  /* used for finding the two highest players */
                    632:        char    hiname[21], nxtname[21];        /* used for finding the two
                    633:                                                 * highest players */
                    634:
                    635:        nxtexp = 0;
                    636:        mvaddstr(0, 14,
                    637:            "W e l c o m e   t o   P h a n t a s i a (vers. 3.3.2)!");
                    638:
                    639:        /* print message of the day */
                    640:        if ((fp = fopen(_PATH_MOTD, "r")) != NULL
                    641:            && fgets(Databuf, SZ_DATABUF, fp) != NULL) {
                    642:                mvaddstr(2, 40 - strlen(Databuf) / 2, Databuf);
                    643:                fclose(fp);
                    644:        }
                    645:        /* search for king */
1.8       jsm       646:        fseek(Playersfp, 0L, SEEK_SET);
1.4       lukem     647:        while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                    648:                if (Other.p_specialtype == SC_KING &&
                    649:                    Other.p_status != S_NOTUSED)
                    650:                        /* found the king */
                    651:                {
                    652:                        sprintf(Databuf, "The present ruler is %s  Level:%.0f",
                    653:                            Other.p_name, Other.p_level);
                    654:                        mvaddstr(4, 40 - strlen(Databuf) / 2, Databuf);
                    655:                        kingfound = TRUE;
                    656:                        break;
                    657:                }
                    658:        if (!kingfound)
                    659:                mvaddstr(4, 24, "There is no ruler at this time.");
                    660:
                    661:        /* search for valar */
1.8       jsm       662:        fseek(Playersfp, 0L, SEEK_SET);
1.4       lukem     663:        while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                    664:                if (Other.p_specialtype == SC_VALAR && Other.p_status != S_NOTUSED)
                    665:                        /* found the valar */
                    666:                {
                    667:                        sprintf(Databuf, "The Valar is %s   Login:  %s", Other.p_name, Other.p_login);
                    668:                        mvaddstr(6, 40 - strlen(Databuf) / 2, Databuf);
                    669:                        break;
                    670:                }
                    671:        /* search for council of the wise */
1.8       jsm       672:        fseek(Playersfp, 0L, SEEK_SET);
1.4       lukem     673:        Lines = 10;
                    674:        while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                    675:                if (Other.p_specialtype == SC_COUNCIL && Other.p_status != S_NOTUSED)
                    676:                        /* found a member of the council */
                    677:                {
                    678:                        if (!councilfound) {
                    679:                                mvaddstr(8, 30, "Council of the Wise:");
                    680:                                councilfound = TRUE;
                    681:                        }
                    682:                        /* This assumes a finite (<=5) number of C.O.W.: */
                    683:                        sprintf(Databuf, "%s   Login:  %s", Other.p_name, Other.p_login);
                    684:                        mvaddstr(Lines++, 40 - strlen(Databuf) / 2, Databuf);
                    685:                }
                    686:        /* search for the two highest players */
                    687:        nxtname[0] = hiname[0] = '\0';
                    688:        hiexp = 0.0;
                    689:        nxtlvl = hilvl = 0;
                    690:
1.8       jsm       691:        fseek(Playersfp, 0L, SEEK_SET);
1.4       lukem     692:        while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                    693:                if (Other.p_experience > hiexp && Other.p_specialtype <= SC_KING && Other.p_status != S_NOTUSED)
                    694:                        /* highest found so far */
                    695:                {
                    696:                        nxtexp = hiexp;
                    697:                        hiexp = Other.p_experience;
                    698:                        nxtlvl = hilvl;
                    699:                        hilvl = Other.p_level;
                    700:                        strcpy(nxtname, hiname);
                    701:                        strcpy(hiname, Other.p_name);
                    702:                } else
                    703:                        if (Other.p_experience > nxtexp
                    704:                            && Other.p_specialtype <= SC_KING
                    705:                            && Other.p_status != S_NOTUSED)
                    706:                                /* next highest found so far */
                    707:                        {
                    708:                                nxtexp = Other.p_experience;
                    709:                                nxtlvl = Other.p_level;
                    710:                                strcpy(nxtname, Other.p_name);
                    711:                        }
                    712:        mvaddstr(15, 28, "Highest characters are:");
                    713:        sprintf(Databuf, "%s  Level:%.0f   and   %s  Level:%.0f",
                    714:            hiname, hilvl, nxtname, nxtlvl);
                    715:        mvaddstr(17, 40 - strlen(Databuf) / 2, Databuf);
                    716:
                    717:        /* print last to die */
                    718:        if ((fp = fopen(_PATH_LASTDEAD, "r")) != NULL
                    719:            && fgets(Databuf, SZ_DATABUF, fp) != NULL) {
                    720:                mvaddstr(19, 25, "The last character to die was:");
                    721:                mvaddstr(20, 40 - strlen(Databuf) / 2, Databuf);
1.16      christos  722:        }
                    723:        if (fp)
1.4       lukem     724:                fclose(fp);
                    725:        refresh();
1.1       jtc       726: }
                    727:
                    728: long
                    729: recallplayer()
                    730: {
1.4       lukem     731:        long    loc = 0L;       /* location in player file */
                    732:        int     loop;           /* loop counter */
                    733:        int     ch;             /* input */
1.1       jtc       734:
1.4       lukem     735:        clear();
                    736:        mvprintw(10, 0, "What was your character's name ? ");
                    737:        getstring(Databuf, SZ_NAME);
                    738:        truncstring(Databuf);
                    739:
                    740:        if ((loc = findname(Databuf, &Player)) >= 0L)
                    741:                /* found character */
                    742:        {
                    743:                Echo = FALSE;
                    744:
                    745:                for (loop = 0; loop < 2; ++loop) {
                    746:                        /* prompt for password */
                    747:                        mvaddstr(11, 0, "Password ? ");
                    748:                        getstring(Databuf, SZ_PASSWORD);
                    749:                        if (strcmp(Databuf, Player.p_password) == 0)
                    750:                                /* password good */
                    751:                        {
                    752:                                Echo = TRUE;
1.1       jtc       753:
1.4       lukem     754:                                if (Player.p_status != S_OFF)
                    755:                                        /* player did not exit normally last
                    756:                                         * time */
                    757:                                {
                    758:                                        clear();
                    759:                                        addstr("Your character did not exit normally last time.\n");
                    760:                                        addstr("If you think you have good cause to have your character saved,\n");
                    761:                                        printw("you may quit and mail your reason to 'root'.\n");
                    762:                                        addstr("Otherwise, continuing spells certain death.\n");
                    763:                                        addstr("Do you want to quit ? ");
                    764:                                        ch = getanswer("YN", FALSE);
                    765:                                        if (ch == 'Y') {
                    766:                                                Player.p_status = S_HUNGUP;
                    767:                                                writerecord(&Player, loc);
                    768:                                                cleanup(TRUE);
                    769:                                                /* NOTREACHED */
                    770:                                        }
                    771:                                        death("Stupidity");
                    772:                                        /* NOTREACHED */
                    773:                                }
                    774:                                return (loc);
                    775:                        } else
                    776:                                mvaddstr(12, 0, "No good.\n");
1.1       jtc       777:                }
                    778:
1.4       lukem     779:                Echo = TRUE;
                    780:        } else
                    781:                mvaddstr(11, 0, "Not found.\n");
1.1       jtc       782:
1.4       lukem     783:        more(13);
                    784:        return (-1L);
1.1       jtc       785: }
                    786:
1.4       lukem     787: void
1.1       jtc       788: neatstuff()
                    789: {
1.4       lukem     790:        double  temp;           /* for temporary calculations */
                    791:        int     ch;             /* input */
1.1       jtc       792:
1.4       lukem     793:        switch ((int) ROLL(0.0, 100.0)) {
1.1       jtc       794:        case 1:
                    795:        case 2:
1.4       lukem     796:                if (Player.p_poison > 0.0) {
                    797:                        mvaddstr(4, 0, "You've found a medic!  How much will you offer to be cured ? ");
                    798:                        temp = floor(infloat());
                    799:                        if (temp < 0.0 || temp > Player.p_gold)
                    800:                                /* negative gold, or more than available */
                    801:                        {
                    802:                                mvaddstr(6, 0, "He was not amused, and made you worse.\n");
                    803:                                Player.p_poison += 1.0;
                    804:                        } else
                    805:                                if (drandom() / 2.0 > (temp + 1.0) / MAX(Player.p_gold, 1))
                    806:                                        /* medic wants 1/2 of available gold */
                    807:                                        mvaddstr(5, 0, "Sorry, he wasn't interested.\n");
                    808:                                else {
                    809:                                        mvaddstr(5, 0, "He accepted.");
                    810:                                        Player.p_poison = MAX(0.0, Player.p_poison - 1.0);
                    811:                                        Player.p_gold -= temp;
                    812:                                }
1.1       jtc       813:                }
1.4       lukem     814:                break;
1.1       jtc       815:
                    816:        case 3:
1.4       lukem     817:                mvaddstr(4, 0, "You've been caught raping and pillaging!\n");
                    818:                Player.p_experience += 4000.0;
                    819:                Player.p_sin += 0.5;
                    820:                break;
1.1       jtc       821:
                    822:        case 4:
1.4       lukem     823:                temp = ROLL(10.0, 75.0);
                    824:                mvprintw(4, 0, "You've found %.0f gold pieces, want them ? ", temp);
                    825:                ch = getanswer("NY", FALSE);
                    826:
                    827:                if (ch == 'Y')
                    828:                        collecttaxes(temp, 0.0);
                    829:                break;
1.1       jtc       830:
                    831:        case 5:
1.4       lukem     832:                if (Player.p_sin > 1.0) {
                    833:                        mvaddstr(4, 0, "You've found a Holy Orb!\n");
                    834:                        Player.p_sin -= 0.25;
1.1       jtc       835:                }
1.4       lukem     836:                break;
1.1       jtc       837:
                    838:        case 6:
1.4       lukem     839:                if (Player.p_poison < 1.0) {
                    840:                        mvaddstr(4, 0, "You've been hit with a plague!\n");
                    841:                        Player.p_poison += 1.0;
1.1       jtc       842:                }
1.4       lukem     843:                break;
1.1       jtc       844:
                    845:        case 7:
1.4       lukem     846:                mvaddstr(4, 0, "You've found some holy water.\n");
                    847:                ++Player.p_holywater;
                    848:                break;
1.1       jtc       849:
                    850:        case 8:
1.4       lukem     851:                mvaddstr(4, 0, "You've met a Guru. . .");
                    852:                if (drandom() * Player.p_sin > 1.0)
                    853:                        addstr("You disgusted him with your sins!\n");
                    854:                else
                    855:                        if (Player.p_poison > 0.0) {
                    856:                                addstr("He looked kindly upon you, and cured you.\n");
                    857:                                Player.p_poison = 0.0;
                    858:                        } else {
                    859:                                addstr("He rewarded you for your virtue.\n");
                    860:                                Player.p_mana += 50.0;
                    861:                                Player.p_shield += 2.0;
                    862:                        }
                    863:                break;
1.1       jtc       864:
                    865:        case 9:
1.4       lukem     866:                mvaddstr(4, 0, "You've found an amulet.\n");
                    867:                ++Player.p_amulets;
                    868:                break;
1.1       jtc       869:
                    870:        case 10:
1.4       lukem     871:                if (Player.p_blindness) {
                    872:                        mvaddstr(4, 0, "You've regained your sight!\n");
                    873:                        Player.p_blindness = FALSE;
1.1       jtc       874:                }
1.4       lukem     875:                break;
1.1       jtc       876:
1.4       lukem     877:        default:                /* deal with poison */
                    878:                if (Player.p_poison > 0.0) {
                    879:                        temp = Player.p_poison * Statptr->c_weakness
                    880:                            * Player.p_maxenergy / 600.0;
                    881:                        if (Player.p_energy > Player.p_maxenergy / 10.0
                    882:                            && temp + 5.0 < Player.p_energy)
                    883:                                Player.p_energy -= temp;
1.1       jtc       884:                }
1.4       lukem     885:                break;
1.1       jtc       886:        }
                    887: }
                    888:
1.4       lukem     889: void
1.1       jtc       890: genchar(type)
1.4       lukem     891:        int     type;
1.1       jtc       892: {
1.4       lukem     893:        int     subscript;      /* used for subscripting into Stattable */
1.7       jsm       894:        const struct charstats *statptr; /* for pointing into Stattable */
1.1       jtc       895:
1.4       lukem     896:        subscript = type - '1';
1.1       jtc       897:
1.4       lukem     898:        if (subscript < C_MAGIC || subscript > C_EXPER)
                    899:                if (subscript != C_SUPER || !Wizard)
                    900:                        /* fighter is default */
                    901:                        subscript = C_FIGHTER;
                    902:
                    903:        statptr = &Stattable[subscript];
                    904:
                    905:        Player.p_quickness =
                    906:            ROLL(statptr->c_quickness.base, statptr->c_quickness.interval);
                    907:        Player.p_strength =
                    908:            ROLL(statptr->c_strength.base, statptr->c_strength.interval);
                    909:        Player.p_mana =
                    910:            ROLL(statptr->c_mana.base, statptr->c_mana.interval);
                    911:        Player.p_maxenergy =
                    912:            Player.p_energy =
                    913:            ROLL(statptr->c_energy.base, statptr->c_energy.interval);
                    914:        Player.p_brains =
                    915:            ROLL(statptr->c_brains.base, statptr->c_brains.interval);
                    916:        Player.p_magiclvl =
                    917:            ROLL(statptr->c_magiclvl.base, statptr->c_magiclvl.interval);
                    918:
                    919:        Player.p_type = subscript;
                    920:
                    921:        if (Player.p_type == C_HALFLING)
                    922:                /* give halfling some experience */
                    923:                Player.p_experience = ROLL(600.0, 200.0);
1.1       jtc       924: }
                    925:
1.4       lukem     926: void
1.1       jtc       927: playinit()
                    928: {
1.4       lukem     929:        /* catch/ingnore signals */
1.1       jtc       930:
                    931: #ifdef BSD41
1.4       lukem     932:        sigignore(SIGQUIT);
                    933:        sigignore(SIGALRM);
                    934:        sigignore(SIGTERM);
                    935:        sigignore(SIGTSTP);
                    936:        sigignore(SIGTTIN);
                    937:        sigignore(SIGTTOU);
                    938:        sighold(SIGINT);
                    939:        sigset(SIGHUP, ill_sig);
                    940:        sigset(SIGTRAP, ill_sig);
                    941:        sigset(SIGIOT, ill_sig);
                    942:        sigset(SIGEMT, ill_sig);
                    943:        sigset(SIGFPE, ill_sig);
                    944:        sigset(SIGBUS, ill_sig);
                    945:        sigset(SIGSEGV, ill_sig);
                    946:        sigset(SIGSYS, ill_sig);
                    947:        sigset(SIGPIPE, ill_sig);
1.1       jtc       948: #endif
                    949: #ifdef BSD42
1.4       lukem     950:        signal(SIGQUIT, ill_sig);
                    951:        signal(SIGALRM, SIG_IGN);
                    952:        signal(SIGTERM, SIG_IGN);
                    953:        signal(SIGTSTP, SIG_IGN);
                    954:        signal(SIGTTIN, SIG_IGN);
                    955:        signal(SIGTTOU, SIG_IGN);
                    956:        signal(SIGINT, ill_sig);
                    957:        signal(SIGHUP, SIG_DFL);
                    958:        signal(SIGTRAP, ill_sig);
                    959:        signal(SIGIOT, ill_sig);
                    960:        signal(SIGEMT, ill_sig);
                    961:        signal(SIGFPE, ill_sig);
                    962:        signal(SIGBUS, ill_sig);
                    963:        signal(SIGSEGV, ill_sig);
                    964:        signal(SIGSYS, ill_sig);
                    965:        signal(SIGPIPE, ill_sig);
1.1       jtc       966: #endif
                    967: #ifdef SYS3
1.4       lukem     968:        signal(SIGINT, SIG_IGN);
                    969:        signal(SIGQUIT, SIG_IGN);
                    970:        signal(SIGTERM, SIG_IGN);
                    971:        signal(SIGALRM, SIG_IGN);
                    972:        signal(SIGHUP, ill_sig);
                    973:        signal(SIGTRAP, ill_sig);
                    974:        signal(SIGIOT, ill_sig);
                    975:        signal(SIGEMT, ill_sig);
                    976:        signal(SIGFPE, ill_sig);
                    977:        signal(SIGBUS, ill_sig);
                    978:        signal(SIGSEGV, ill_sig);
                    979:        signal(SIGSYS, ill_sig);
                    980:        signal(SIGPIPE, ill_sig);
1.1       jtc       981: #endif
                    982: #ifdef SYS5
1.4       lukem     983:        signal(SIGINT, SIG_IGN);
                    984:        signal(SIGQUIT, SIG_IGN);
                    985:        signal(SIGTERM, SIG_IGN);
                    986:        signal(SIGALRM, SIG_IGN);
                    987:        signal(SIGHUP, ill_sig);
                    988:        signal(SIGTRAP, ill_sig);
                    989:        signal(SIGIOT, ill_sig);
                    990:        signal(SIGEMT, ill_sig);
                    991:        signal(SIGFPE, ill_sig);
                    992:        signal(SIGBUS, ill_sig);
                    993:        signal(SIGSEGV, ill_sig);
                    994:        signal(SIGSYS, ill_sig);
                    995:        signal(SIGPIPE, ill_sig);
1.1       jtc       996: #endif
                    997:
1.16.20.1! wrstuden  998:        if (!initscr()) {       /* turn on curses */
        !           999:                fprintf(stderr, "couldn't initialize screen\n");
        !          1000:                exit (0);
        !          1001:        }
1.4       lukem    1002:        noecho();               /* do not echo input */
1.10      blymn    1003:        cbreak();               /* do not process erase, kill */
1.4       lukem    1004:        clear();
                   1005:        refresh();
                   1006:        Windows = TRUE;         /* mark the state */
1.1       jtc      1007: }
                   1008:
1.4       lukem    1009: void
1.1       jtc      1010: cleanup(doexit)
1.4       lukem    1011:        int    doexit;
1.1       jtc      1012: {
1.4       lukem    1013:        if (Windows) {
                   1014:                move(LINES - 2, 0);
                   1015:                refresh();
1.10      blymn    1016:                nocbreak();
1.4       lukem    1017:                endwin();
                   1018:        }
1.12      jsm      1019:        if (Playersfp)
                   1020:                fclose(Playersfp);
                   1021:        if (Monstfp)
                   1022:                fclose(Monstfp);
                   1023:        if (Messagefp)
                   1024:                fclose(Messagefp);
                   1025:        if (Energyvoidfp)
                   1026:                fclose(Energyvoidfp);
1.4       lukem    1027:
                   1028:        if (doexit)
                   1029:                exit(0);
                   1030:        /* NOTREACHED */
1.1       jtc      1031: }

CVSweb <webmaster@jp.NetBSD.org>