Annotation of 43BSDReno/games/hunt/NEW/driver.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  Hunt
                      3:  *  Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
                      4:  *  San Francisco, California
                      5:  *
                      6:  *  Copyright (c) 1985 Regents of the University of California.
                      7:  *  All rights reserved.  The Berkeley software License Agreement
                      8:  *  specifies the terms and conditions for redistribution.
                      9:  */
                     10: 
                     11: # include      "hunt.h"
                     12: # include      <signal.h>
                     13: # include      <errno.h>
                     14: # include      <sys/ioctl.h>
                     15: # ifndef HPUX
                     16: # include      <sys/time.h>
                     17: # else
                     18: # include      <time.h>
                     19: # endif
                     20: 
                     21: # ifndef pdp11
                     22: # define       RN      (((Seed = Seed * 11109 + 13849) >> 16) & 0xffff)
                     23: # else pdp11
                     24: # define       RN      ((Seed = Seed * 11109 + 13849) & 0x7fff)
                     25: # endif pdp11
                     26: 
                     27: int    Seed = 0;
                     28: 
                     29: 
                     30: SOCKET Daemon;
                     31: char   *First_arg;             /* pointer to argv[0] */
                     32: char   *Last_arg;              /* pointer to end of argv/environ */
                     33: # ifdef        INTERNET
                     34: int    Test_socket;            /* test socket to answer datagrams */
                     35: FLAG   inetd_spawned;          /* invoked via inetd */
                     36: FLAG   standard_port = TRUE;   /* true if listening on standard port */
                     37: u_short        sock_port;              /* port # of tcp listen socket */
                     38: u_short        stat_port;              /* port # of statistics tcp socket */
                     39: # define       DAEMON_SIZE     (sizeof Daemon)
                     40: # else INTERNET
                     41: # define       DAEMON_SIZE     (sizeof Daemon - 1)
                     42: # endif        INTERNET
                     43: 
                     44: /*
                     45:  * main:
                     46:  *     The main program.
                     47:  */
                     48: main(ac, av, ep)
                     49: int    ac;
                     50: char   **av, **ep;
                     51: {
                     52:        register PLAYER *pp;
                     53:        register int    had_char;
                     54: # ifdef INTERNET
                     55:        register long   test_mask;
                     56:        u_short         msg;
                     57:        short           port_num, reply;
                     58:        int             namelen;
                     59:        SOCKET          test;
                     60: # endif INTERNET
                     61:        static long     read_fds;
                     62:        static FLAG     first = TRUE;
                     63:        static FLAG     server = FALSE;
                     64:        extern int      optind;
                     65:        extern char     *optarg;
                     66:        int             c;
                     67:        static struct timeval   linger = {      90, 0   };
                     68: 
                     69:        First_arg = av[0];
                     70:        if (ep == NULL || *ep == NULL)
                     71:                ep = av + ac;
                     72:        while (*ep)
                     73:                ep++;
                     74:        Last_arg = ep[-1] + strlen(ep[-1]);
                     75: 
                     76:        while ((c = getopt(ac, av, "sp:")) != EOF) {
                     77:                switch (c) {
                     78:                  case 's':
                     79:                        server = TRUE;
                     80:                        break;
                     81: # ifdef INTERNET
                     82:                  case 'p':
                     83:                        standard_port = FALSE;
                     84:                        Test_port = atoi(optarg);
                     85:                        break;
                     86: # endif
                     87:                  default:
                     88: erred:
                     89:                        fprintf(stderr, "Usage: %s [-s] [-p port]\n", av[0]);
                     90:                        exit(1);
                     91:                }
                     92:        }
                     93:        if (optind < ac)
                     94:                goto erred;
                     95: 
                     96:        init();
                     97:        Sock_mask = (1 << Socket);
                     98:        Stat_mask = (1 << Status);
                     99: # ifdef INTERNET
                    100:        test_mask = (1 << Test_socket);
                    101: # endif INTERNET
                    102: 
                    103: 
                    104: again:
                    105:        do {
                    106:                read_fds = Fds_mask;
                    107:                errno = 0;
                    108:                while (select(Num_fds, &read_fds, (int *) NULL,
                    109:                    (int *) NULL, (struct timeval *) NULL) < 0)
                    110:                {
                    111:                        if (errno != EINTR)
                    112: # ifdef LOG
                    113:                                syslog(LOG_WARNING, "select: %m");
                    114: # else LOG
                    115:                                perror("select");
                    116: # endif LOG
                    117:                        errno = 0;
                    118:                }
                    119:                Have_inp = read_fds;
                    120: # ifdef INTERNET
                    121:                if (read_fds & test_mask) {
                    122:                        namelen = DAEMON_SIZE;
                    123:                        port_num = htons(sock_port);
                    124:                        (void) recvfrom(Test_socket, (char *) &msg, sizeof msg,
                    125:                                0, (struct sockaddr *) &test, &namelen);
                    126:                        switch (ntohs(msg)) {
                    127:                          case C_MESSAGE:
                    128:                                if (Nplayer <= 0)
                    129:                                        break;
                    130:                                reply = htons((u_short) Nplayer);
                    131:                                (void) sendto(Test_socket, (char *) &reply,
                    132:                                        sizeof reply, 0,
                    133:                                        (struct sockaddr *) &test, DAEMON_SIZE);
                    134:                                break;
                    135:                          case C_SCORES:
                    136:                                reply = htons(stat_port);
                    137:                                (void) sendto(Test_socket, (char *) &reply,
                    138:                                        sizeof reply, 0,
                    139:                                        (struct sockaddr *) &test, DAEMON_SIZE);
                    140:                                break;
                    141:                          case C_PLAYER:
                    142:                          case C_MONITOR:
                    143:                                if (msg == C_MONITOR && Nplayer <= 0)
                    144:                                        break;
                    145:                                reply = htons(sock_port);
                    146:                                (void) sendto(Test_socket, (char *) &reply,
                    147:                                        sizeof reply, 0,
                    148:                                        (struct sockaddr *) &test, DAEMON_SIZE);
                    149:                                break;
                    150:                        }
                    151:                }
                    152: # endif INTERNET
                    153:                for (;;) {
                    154:                        had_char = FALSE;
                    155:                        for (pp = Player; pp < End_player; pp++)
                    156:                                if (havechar(pp)) {
                    157:                                        execute(pp);
                    158:                                        pp->p_nexec++;
                    159:                                        had_char++;
                    160:                                }
                    161: # ifdef MONITOR
                    162:                        for (pp = Monitor; pp < End_monitor; pp++)
                    163:                                if (havechar(pp)) {
                    164:                                        mon_execute(pp);
                    165:                                        pp->p_nexec++;
                    166:                                        had_char++;
                    167:                                }
                    168: # endif MONITOR
                    169:                        if (!had_char)
                    170:                                break;
                    171:                        moveshots();
                    172:                        for (pp = Player; pp < End_player; )
                    173:                                if (pp->p_death[0] != '\0')
                    174:                                        zap(pp, TRUE);
                    175:                                else
                    176:                                        pp++;
                    177: # ifdef MONITOR
                    178:                        for (pp = Monitor; pp < End_monitor; )
                    179:                                if (pp->p_death[0] != '\0')
                    180:                                        zap(pp, FALSE);
                    181:                                else
                    182:                                        pp++;
                    183: # endif MONITOR
                    184:                }
                    185:                if (read_fds & Sock_mask)
                    186:                        if (answer()) {
                    187: # ifdef INTERNET
                    188:                                if (first && standard_port)
                    189:                                        faketalk();
                    190: # endif
                    191:                                first = FALSE;
                    192:                        }
                    193:                if (read_fds & Stat_mask)
                    194:                        send_stats();
                    195:                for (pp = Player; pp < End_player; pp++) {
                    196:                        if (read_fds & pp->p_mask)
                    197:                                sendcom(pp, READY, pp->p_nexec);
                    198:                        pp->p_nexec = 0;
                    199:                        (void) fflush(pp->p_output);
                    200:                }
                    201: # ifdef MONITOR
                    202:                for (pp = Monitor; pp < End_monitor; pp++) {
                    203:                        if (read_fds & pp->p_mask)
                    204:                                sendcom(pp, READY, pp->p_nexec);
                    205:                        pp->p_nexec = 0;
                    206:                        (void) fflush(pp->p_output);
                    207:                }
                    208: # endif MONITOR
                    209:        } while (Nplayer > 0);
                    210: 
                    211:        read_fds = Fds_mask;
                    212:        if (select(Num_fds, &read_fds, (int *) NULL, (int *) NULL,
                    213:                   &linger) > 0) {
                    214:                goto again;
                    215:        }
                    216:        if (server) {
                    217:                clear_scores();
                    218:                makemaze();
                    219:                clearwalls();
                    220: # ifdef BOOTS
                    221:                makeboots();
                    222: # endif BOOTS
                    223:                first = TRUE;
                    224:                goto again;
                    225:        }
                    226: 
                    227: # ifdef MONITOR
                    228:        for (pp = Monitor; pp < End_monitor; )
                    229:                zap(pp, FALSE);
                    230: # endif MONITOR
                    231:        cleanup(0);
                    232: }
                    233: 
                    234: /*
                    235:  * init:
                    236:  *     Initialize the global parameters.
                    237:  */
                    238: init()
                    239: {
                    240:        register int    i;
                    241: # ifdef        INTERNET
                    242:        auto SOCKET     test_port;
                    243:        auto int        msg;
                    244:        auto int        len;
                    245: # endif        INTERNET
                    246: 
                    247: # ifndef DEBUG
                    248: # ifdef TIOCNOTTY
                    249:        (void) ioctl(fileno(stdout), TIOCNOTTY, NULL);
                    250: # endif
                    251:        (void) setpgrp(getpid(), getpid());
                    252:        (void) signal(SIGHUP, SIG_IGN);
                    253:        (void) signal(SIGINT, SIG_IGN);
                    254:        (void) signal(SIGQUIT, SIG_IGN);
                    255:        (void) signal(SIGTERM, cleanup);
                    256: # endif DEBUG
                    257: 
                    258:        (void) chdir("/usr/tmp");       /* just in case it core dumps */
                    259:        (void) umask(0);                /* No privacy at all! */
                    260:        (void) signal(SIGPIPE, SIG_IGN);
                    261: 
                    262: # ifdef LOG
                    263: # ifdef        SYSLOG_43
                    264:        openlog("HUNT", LOG_PID, LOG_DAEMON);
                    265: # endif
                    266: # ifdef        SYSLOG_42
                    267:        openlog("HUNT", LOG_PID);
                    268: # endif
                    269: # endif
                    270: 
                    271:        /*
                    272:         * Initialize statistics socket
                    273:         */
                    274: # ifdef        INTERNET
                    275:        Daemon.sin_family = SOCK_FAMILY;
                    276:        Daemon.sin_addr.s_addr = INADDR_ANY;
                    277:        Daemon.sin_port = 0;
                    278: # else INTERNET
                    279:        Daemon.sun_family = SOCK_FAMILY;
                    280:        (void) strcpy(Daemon.sun_path, Stat_name);
                    281: # endif INTERNET
                    282: 
                    283:        Status = socket(SOCK_FAMILY, SOCK_STREAM, 0);
                    284:        if (bind(Status, (struct sockaddr *) &Daemon, DAEMON_SIZE) < 0) {
                    285:                if (errno == EADDRINUSE)
                    286:                        exit(0);
                    287:                else {
                    288: # ifdef LOG
                    289:                        syslog(LOG_ERR, "bind: %m");
                    290: # else LOG
                    291:                        perror("bind");
                    292: # endif LOG
                    293:                        cleanup(1);
                    294:                }
                    295:        }
                    296:        (void) listen(Status, 5);
                    297: 
                    298: # ifdef INTERNET
                    299:        len = sizeof (SOCKET);
                    300:        if (getsockname(Status, (struct sockaddr *) &Daemon, &len) < 0)  {
                    301: # ifdef LOG
                    302:                syslog(LOG_ERR, "getsockname: %m");
                    303: # else LOG
                    304:                perror("getsockname");
                    305: # endif LOG
                    306:                exit(1);
                    307:        }
                    308:        stat_port = ntohs(Daemon.sin_port);
                    309: # endif INTERNET
                    310: 
                    311:        /*
                    312:         * Initialize main socket
                    313:         */
                    314: # ifdef        INTERNET
                    315:        Daemon.sin_family = SOCK_FAMILY;
                    316:        Daemon.sin_addr.s_addr = INADDR_ANY;
                    317:        Daemon.sin_port = 0;
                    318: # else INTERNET
                    319:        Daemon.sun_family = SOCK_FAMILY;
                    320:        (void) strcpy(Daemon.sun_path, Sock_name);
                    321: # endif INTERNET
                    322: 
                    323:        Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0);
                    324: # if defined(INTERNET)
                    325:        msg = 1;
                    326:        if (setsockopt(Socket, SOL_SOCKET, SO_USELOOPBACK, &msg, sizeof msg)<0)
                    327: # ifdef LOG
                    328:                syslog(LOG_WARNING, "setsockopt loopback %m");
                    329: # else LOG
                    330:                perror("setsockopt loopback");
                    331: # endif LOG
                    332: # endif INTERNET
                    333:        if (bind(Socket, (struct sockaddr *) &Daemon, DAEMON_SIZE) < 0) {
                    334:                if (errno == EADDRINUSE)
                    335:                        exit(0);
                    336:                else {
                    337: # ifdef LOG
                    338:                        syslog(LOG_ERR, "bind: %m");
                    339: # else LOG
                    340:                        perror("bind");
                    341: # endif LOG
                    342:                        cleanup(1);
                    343:                }
                    344:        }
                    345:        (void) listen(Socket, 5);
                    346: 
                    347: # ifdef INTERNET
                    348:        len = sizeof (SOCKET);
                    349:        if (getsockname(Socket, (struct sockaddr *) &Daemon, &len) < 0)  {
                    350: # ifdef LOG
                    351:                syslog(LOG_ERR, "getsockname: %m");
                    352: # else LOG
                    353:                perror("getsockname");
                    354: # endif LOG
                    355:                exit(1);
                    356:        }
                    357:        sock_port = ntohs(Daemon.sin_port);
                    358: # endif INTERNET
                    359: 
                    360:        /*
                    361:         * Initialize minimal select mask
                    362:         */
                    363:        Fds_mask = (1 << Socket) | (1 << Status);
                    364:        Num_fds = ((Socket > Status) ? Socket : Status) + 1;
                    365: 
                    366: # ifdef INTERNET
                    367:        len = sizeof (SOCKET);
                    368:        if (getsockname(0, (struct sockaddr *) &test_port, &len) >= 0
                    369:        && test_port.sin_family == AF_INET) {
                    370:                inetd_spawned = TRUE;
                    371:                Test_socket = 0;
                    372:                if (test_port.sin_port != htons((u_short) Test_port)) {
                    373:                        standard_port = FALSE;
                    374:                        Test_port = ntohs(test_port.sin_port);
                    375:                }
                    376:        } else {
                    377:                test_port = Daemon;
                    378:                test_port.sin_port = htons((u_short) Test_port);
                    379: 
                    380:                Test_socket = socket(SOCK_FAMILY, SOCK_DGRAM, 0);
                    381:                if (bind(Test_socket, (struct sockaddr *) &test_port,
                    382:                    DAEMON_SIZE) < 0) {
                    383: # ifdef LOG
                    384:                        syslog(LOG_ERR, "bind: %m");
                    385: # else LOG
                    386:                        perror("bind");
                    387: # endif LOG
                    388:                        exit(1);
                    389:                }
                    390:                (void) listen(Test_socket, 5);
                    391:        }
                    392: 
                    393:        Fds_mask |= (1 << Test_socket);
                    394:        if (Test_socket + 1 > Num_fds)
                    395:                Num_fds = Test_socket + 1;
                    396: # endif        INTERNET
                    397: 
                    398:        Seed = getpid() + time((time_t *) NULL);
                    399:        makemaze();
                    400: # ifdef BOOTS
                    401:        makeboots();
                    402: # endif BOOTS
                    403: 
                    404:        for (i = 0; i < NASCII; i++)
                    405:                See_over[i] = TRUE;
                    406:        See_over[DOOR] = FALSE;
                    407:        See_over[WALL1] = FALSE;
                    408:        See_over[WALL2] = FALSE;
                    409:        See_over[WALL3] = FALSE;
                    410: # ifdef REFLECT
                    411:        See_over[WALL4] = FALSE;
                    412:        See_over[WALL5] = FALSE;
                    413: # endif REFLECT
                    414: 
                    415: }
                    416: 
                    417: # ifdef BOOTS
                    418: /*
                    419:  * makeboots:
                    420:  *     Put the boots in the maze
                    421:  */
                    422: makeboots()
                    423: {
                    424:        register int    x, y;
                    425:        register PLAYER *pp;
                    426: 
                    427:        do {
                    428:                x = rand_num(WIDTH - 1) + 1;
                    429:                y = rand_num(HEIGHT - 1) + 1;
                    430:        } while (Maze[y][x] != SPACE);
                    431:        Maze[y][x] = BOOT_PAIR;
                    432:        for (pp = Boot; pp < &Boot[NBOOTS]; pp++)
                    433:                pp->p_flying = -1;
                    434: }
                    435: # endif
                    436: 
                    437: 
                    438: /*
                    439:  * checkdam:
                    440:  *     Check the damage to the given player, and see if s/he is killed
                    441:  */
                    442: checkdam(ouch, gotcha, credit, amt, shot_type)
                    443: register PLAYER        *ouch, *gotcha;
                    444: register IDENT *credit;
                    445: int            amt;
                    446: char           shot_type;
                    447: {
                    448:        register char   *cp;
                    449: 
                    450:        if (ouch->p_death[0] != '\0')
                    451:                return;
                    452: # ifdef BOOTS
                    453:        if (shot_type == SLIME)
                    454:                switch (ouch->p_nboots) {
                    455:                  default:
                    456:                        break;
                    457:                  case 1:
                    458:                        amt = (amt + 1) / 2;
                    459:                        break;
                    460:                  case 2:
                    461:                        if (gotcha != NULL)
                    462:                                message(gotcha, "He has boots on!");
                    463:                        return;
                    464:                }
                    465: # endif
                    466:        ouch->p_damage += amt;
                    467:        if (ouch->p_damage <= ouch->p_damcap) {
                    468:                (void) sprintf(Buf, "%2d", ouch->p_damage);
                    469:                cgoto(ouch, STAT_DAM_ROW, STAT_VALUE_COL);
                    470:                outstr(ouch, Buf, 2);
                    471:                return;
                    472:        }
                    473: 
                    474:        /* Someone DIED */
                    475:        switch (shot_type) {
                    476:          default:
                    477:                cp = "Killed";
                    478:                break;
                    479: # ifdef FLY
                    480:          case FALL:
                    481:                cp = "Killed on impact";
                    482:                break;
                    483: # endif FLY
                    484:          case KNIFE:
                    485:                cp = "Stabbed to death";
                    486:                ouch->p_ammo = 0;               /* No exploding */
                    487:                break;
                    488:          case SHOT:
                    489:                cp = "Shot to death";
                    490:                break;
                    491:          case GRENADE:
                    492:          case SATCHEL:
                    493:          case BOMB:
                    494:                cp = "Bombed";
                    495:                break;
                    496:          case MINE:
                    497:          case GMINE:
                    498:                cp = "Blown apart";
                    499:                break;
                    500: # ifdef        OOZE
                    501:          case SLIME:
                    502:                cp = "Slimed";
                    503:                if (credit != NULL)
                    504:                        credit->i_slime++;
                    505:                break;
                    506: # endif OOZE
                    507: # ifdef        VOLCANO
                    508:          case LAVA:
                    509:                cp = "Baked";
                    510:                break;
                    511: # endif VOLCANO
                    512: # ifdef DRONE
                    513:          case DSHOT:
                    514:                cp = "Eliminated";
                    515:                break;
                    516: # endif DRONE
                    517:        }
                    518:        if (credit == NULL) {
                    519:                (void) sprintf(ouch->p_death, "| %s by %s |", cp,
                    520:                        (shot_type == MINE || shot_type == GMINE) ?
                    521:                        "a mine" : "act of God");
                    522:                return;
                    523:        }
                    524: 
                    525:        (void) sprintf(ouch->p_death, "| %s by %s |", cp, credit->i_name);
                    526: 
                    527:        if (ouch == gotcha) {           /* No use killing yourself */
                    528:                credit->i_kills--;
                    529:                credit->i_bkills++;
                    530:        }
                    531:        else if (ouch->p_ident->i_team == ' '
                    532:        || ouch->p_ident->i_team != credit->i_team) {
                    533:                credit->i_kills++;
                    534:                credit->i_gkills++;
                    535:        }
                    536:        else {
                    537:                credit->i_kills--;
                    538:                credit->i_bkills++;
                    539:        }
                    540:        credit->i_score = credit->i_kills / (double) credit->i_entries;
                    541:        ouch->p_ident->i_deaths++;
                    542:        if (ouch->p_nchar == 0)
                    543:                ouch->p_ident->i_stillb++;
                    544:        if (gotcha == NULL)
                    545:                return;
                    546:        gotcha->p_damcap += STABDAM;
                    547:        gotcha->p_damage -= STABDAM;
                    548:        if (gotcha->p_damage < 0)
                    549:                gotcha->p_damage = 0;
                    550:        (void) sprintf(Buf, "%2d/%2d", gotcha->p_damage, gotcha->p_damcap);
                    551:        cgoto(gotcha, STAT_DAM_ROW, STAT_VALUE_COL);
                    552:        outstr(gotcha, Buf, 5);
                    553:        (void) sprintf(Buf, "%3d", (gotcha->p_damcap - MAXDAM) / 2);
                    554:        cgoto(gotcha, STAT_KILL_ROW, STAT_VALUE_COL);
                    555:        outstr(gotcha, Buf, 3);
                    556:        (void) sprintf(Buf, "%5.2f", gotcha->p_ident->i_score);
                    557:        for (ouch = Player; ouch < End_player; ouch++) {
                    558:                cgoto(ouch, STAT_PLAY_ROW + 1 + (gotcha - Player),
                    559:                        STAT_NAME_COL);
                    560:                outstr(ouch, Buf, 5);
                    561:        }
                    562: # ifdef MONITOR
                    563:        for (ouch = Monitor; ouch < End_monitor; ouch++) {
                    564:                cgoto(ouch, STAT_PLAY_ROW + 1 + (gotcha - Player),
                    565:                        STAT_NAME_COL);
                    566:                outstr(ouch, Buf, 5);
                    567:        }
                    568: # endif MONITOR
                    569: }
                    570: 
                    571: /*
                    572:  * zap:
                    573:  *     Kill off a player and take him out of the game.
                    574:  */
                    575: zap(pp, was_player)
                    576: register PLAYER        *pp;
                    577: FLAG           was_player;
                    578: {
                    579:        register int    i, len;
                    580:        register BULLET *bp;
                    581:        register PLAYER *np;
                    582:        register int    x, y;
                    583:        int             savefd, savemask;
                    584: 
                    585:        if (was_player) {
                    586:                if (pp->p_undershot)
                    587:                        fixshots(pp->p_y, pp->p_x, pp->p_over);
                    588:                drawplayer(pp, FALSE);
                    589:                Nplayer--;
                    590:        }
                    591: 
                    592:        len = strlen(pp->p_death);      /* Display the cause of death */
                    593:        x = (WIDTH - len) / 2;
                    594:        cgoto(pp, HEIGHT / 2, x);
                    595:        outstr(pp, pp->p_death, len);
                    596:        for (i = 1; i < len; i++)
                    597:                pp->p_death[i] = '-';
                    598:        pp->p_death[0] = '+';
                    599:        pp->p_death[len - 1] = '+';
                    600:        cgoto(pp, HEIGHT / 2 - 1, x);
                    601:        outstr(pp, pp->p_death, len);
                    602:        cgoto(pp, HEIGHT / 2 + 1, x);
                    603:        outstr(pp, pp->p_death, len);
                    604:        cgoto(pp, HEIGHT, 0);
                    605: 
                    606:        savefd = pp->p_fd;
                    607:        savemask = pp->p_mask;
                    608: 
                    609: # ifdef MONITOR
                    610:        if (was_player) {
                    611: # endif MONITOR
                    612:                for (bp = Bullets; bp != NULL; bp = bp->b_next) {
                    613:                        if (bp->b_owner == pp)
                    614:                                bp->b_owner = NULL;
                    615:                        if (bp->b_x == pp->p_x && bp->b_y == pp->p_y)
                    616:                                bp->b_over = SPACE;
                    617:                }
                    618: 
                    619:                i = rand_num(pp->p_ammo);
                    620:                x = rand_num(pp->p_ammo);
                    621:                if (x > i)
                    622:                        i = x;
                    623:                if (pp->p_ammo == 0)
                    624:                        x = 0;
                    625:                else if (i == pp->p_ammo - 1) {
                    626:                        x = pp->p_ammo;
                    627:                        len = SLIME;
                    628:                }
                    629:                else {
                    630:                        for (x = MAXBOMB - 1; x > 0; x--)
                    631:                                if (i >= shot_req[x])
                    632:                                        break;
                    633:                        for (y = MAXSLIME - 1; y > 0; y--)
                    634:                                if (i >= slime_req[y])
                    635:                                        break;
                    636:                        if (y >= 0 && slime_req[y] > shot_req[x]) {
                    637:                                x = slime_req[y];
                    638:                                len = SLIME;
                    639:                        }
                    640:                        else if (x != 0) {
                    641:                                len = shot_type[x];
                    642:                                x = shot_req[x];
                    643:                        }
                    644:                }
                    645:                if (x > 0) {
                    646:                        (void) add_shot(len, pp->p_y, pp->p_x, pp->p_face, x,
                    647:                                (PLAYER *) NULL, TRUE, SPACE);
                    648:                        (void) sprintf(Buf, "%s detonated.",
                    649:                                pp->p_ident->i_name);
                    650:                        for (np = Player; np < End_player; np++)
                    651:                                message(np, Buf);
                    652: # ifdef MONITOR
                    653:                        for (np = Monitor; np < End_monitor; np++)
                    654:                                message(np, Buf);
                    655: # endif MONITOR
                    656: # ifdef BOOTS
                    657:                        while (pp->p_nboots-- > 0) {
                    658:                                for (np = Boot; np < &Boot[NBOOTS]; np++)
                    659:                                        if (np->p_flying < 0)
                    660:                                                break;
                    661:                                if (np >= &Boot[NBOOTS])
                    662:                                        abort(1, "Too many boots");
                    663:                                np->p_undershot = FALSE;
                    664:                                np->p_x = pp->p_x;
                    665:                                np->p_y = pp->p_y;
                    666:                                np->p_flying = rand_num(20);
                    667:                                np->p_flyx = 2 * rand_num(6) - 5;
                    668:                                np->p_flyy = 2 * rand_num(6) - 5;
                    669:                                np->p_over = SPACE;
                    670:                                np->p_face = BOOT;
                    671:                                showexpl(np->p_y, np->p_x, BOOT);
                    672:                        }
                    673: # endif BOOTS
                    674:                }
                    675: # ifdef BOOTS
                    676:                else if (pp->p_nboots > 0) {
                    677:                        if (pp->p_nboots == 2)
                    678:                                Maze[pp->p_y][pp->p_x] = BOOT_PAIR;
                    679:                        else
                    680:                                Maze[pp->p_y][pp->p_x] = BOOT;
                    681:                        if (pp->p_undershot)
                    682:                                fixshots(pp->p_y, pp->p_x,
                    683:                                        Maze[pp->p_y][pp->p_x]);
                    684:                }
                    685: # endif BOOTS
                    686: 
                    687: # ifdef VOLCANO
                    688:                volcano += pp->p_ammo - x;
                    689:                if (rand_num(100) < volcano / 50) {
                    690:                        do {
                    691:                                x = rand_num(WIDTH / 2) + WIDTH / 4;
                    692:                                y = rand_num(HEIGHT / 2) + HEIGHT / 4;
                    693:                        } while (Maze[y][x] != SPACE);
                    694:                        (void) add_shot(LAVA, y, x, LEFTS, volcano,
                    695:                                (PLAYER *) NULL, TRUE, SPACE);
                    696:                        for (np = Player; np < End_player; np++)
                    697:                                message(np, "Volcano eruption.");
                    698:                        volcano = 0;
                    699:                }
                    700: # endif VOLCANO
                    701: 
                    702: # ifdef        DRONE
                    703:                if (rand_num(100) < 2) {
                    704:                        do {
                    705:                                x = rand_num(WIDTH / 2) + WIDTH / 4;
                    706:                                y = rand_num(HEIGHT / 2) + HEIGHT / 4;
                    707:                        } while (Maze[y][x] != SPACE);
                    708:                        add_shot(DSHOT, y, x, rand_dir(),
                    709:                                shot_req[MINDSHOT +
                    710:                                rand_num(MAXBOMB - MINDSHOT)],
                    711:                                (PLAYER *) NULL, FALSE, SPACE);
                    712:                }
                    713: # endif        DRONE
                    714: 
                    715:                sendcom(pp, ENDWIN);
                    716:                (void) fclose(pp->p_output);
                    717: 
                    718:                End_player--;
                    719:                if (pp != End_player) {
                    720:                        bcopy((char *) End_player, (char *) pp,
                    721:                                sizeof (PLAYER));
                    722:                        (void) sprintf(Buf, "%5.2f%c%-10.10s %c",
                    723:                                pp->p_ident->i_score, stat_char(pp),
                    724:                                pp->p_ident->i_name, pp->p_ident->i_team);
                    725:                        i = STAT_PLAY_ROW + 1 + (pp - Player);
                    726:                        for (np = Player; np < End_player; np++) {
                    727:                                cgoto(np, i, STAT_NAME_COL);
                    728:                                outstr(np, Buf, STAT_NAME_LEN);
                    729:                        }
                    730: # ifdef MONITOR
                    731:                        for (np = Monitor; np < End_monitor; np++) {
                    732:                                cgoto(np, i, STAT_NAME_COL);
                    733:                                outstr(np, Buf, STAT_NAME_LEN);
                    734:                        }
                    735: # endif MONITOR
                    736:                }
                    737: 
                    738:                /* Erase the last player */
                    739:                i = STAT_PLAY_ROW + 1 + Nplayer;
                    740:                for (np = Player; np < End_player; np++) {
                    741:                        cgoto(np, i, STAT_NAME_COL);
                    742:                        ce(np);
                    743:                }
                    744: # ifdef MONITOR
                    745:                for (np = Monitor; np < End_monitor; np++) {
                    746:                        cgoto(np, i, STAT_NAME_COL);
                    747:                        ce(np);
                    748:                }
                    749:        }
                    750:        else {
                    751:                sendcom(pp, ENDWIN);
                    752:                (void) putc(LAST_PLAYER, pp->p_output);
                    753:                (void) fclose(pp->p_output);
                    754: 
                    755:                End_monitor--;
                    756:                if (pp != End_monitor) {
                    757:                        bcopy((char *) End_monitor, (char *) pp,
                    758:                                sizeof (PLAYER));
                    759:                        (void) sprintf(Buf, "%5.5s %-10.10s %c", " ",
                    760:                                pp->p_ident->i_name, pp->p_ident->i_team);
                    761:                        i = STAT_MON_ROW + 1 + (pp - Player);
                    762:                        for (np = Player; np < End_player; np++) {
                    763:                                cgoto(np, i, STAT_NAME_COL);
                    764:                                outstr(np, Buf, STAT_NAME_LEN);
                    765:                        }
                    766:                        for (np = Monitor; np < End_monitor; np++) {
                    767:                                cgoto(np, i, STAT_NAME_COL);
                    768:                                outstr(np, Buf, STAT_NAME_LEN);
                    769:                        }
                    770:                }
                    771: 
                    772:                /* Erase the last monitor */
                    773:                i = STAT_MON_ROW + 1 + (End_monitor - Monitor);
                    774:                for (np = Player; np < End_player; np++) {
                    775:                        cgoto(np, i, STAT_NAME_COL);
                    776:                        ce(np);
                    777:                }
                    778:                for (np = Monitor; np < End_monitor; np++) {
                    779:                        cgoto(np, i, STAT_NAME_COL);
                    780:                        ce(np);
                    781:                }
                    782: 
                    783:        }
                    784: # endif MONITOR
                    785: 
                    786:        Fds_mask &= ~savemask;
                    787:        if (Num_fds == savefd + 1) {
                    788:                Num_fds = Socket;
                    789: # ifdef INTERNET
                    790:                if (Test_socket > Socket)
                    791:                        Num_fds = Test_socket;
                    792: # endif INTERNET
                    793:                for (np = Player; np < End_player; np++)
                    794:                        if (np->p_fd > Num_fds)
                    795:                                Num_fds = np->p_fd;
                    796: # ifdef MONITOR
                    797:                for (np = Monitor; np < End_monitor; np++)
                    798:                        if (np->p_fd > Num_fds)
                    799:                                Num_fds = np->p_fd;
                    800: # endif MONITOR
                    801:                Num_fds++;
                    802:        }
                    803: }
                    804: 
                    805: /*
                    806:  * rand_num:
                    807:  *     Return a random number in a given range.
                    808:  */
                    809: rand_num(range)
                    810: int    range;
                    811: {
                    812:        return (range == 0 ? 0 : RN % range);
                    813: }
                    814: 
                    815: /*
                    816:  * havechar:
                    817:  *     Check to see if we have any characters in the input queue; if
                    818:  *     we do, read them, stash them away, and return TRUE; else return
                    819:  *     FALSE.
                    820:  */
                    821: havechar(pp)
                    822: register PLAYER        *pp;
                    823: {
                    824:        extern int      errno;
                    825: 
                    826:        if (pp->p_ncount < pp->p_nchar)
                    827:                return TRUE;
                    828:        if (!(Have_inp & pp->p_mask))
                    829:                return FALSE;
                    830:        Have_inp &= ~pp->p_mask;
                    831: check_again:
                    832:        errno = 0;
                    833:        if ((pp->p_nchar = read(pp->p_fd, pp->p_cbuf, sizeof pp->p_cbuf)) <= 0)
                    834:        {
                    835:                if (errno == EINTR)
                    836:                        goto check_again;
                    837:                pp->p_cbuf[0] = 'q';
                    838:        }
                    839:        pp->p_ncount = 0;
                    840:        return TRUE;
                    841: }
                    842: 
                    843: /*
                    844:  * cleanup:
                    845:  *     Exit with the given value, cleaning up any droppings lying around
                    846:  */
                    847: cleanup(eval)
                    848: int    eval;
                    849: {
                    850:        register PLAYER *pp;
                    851: 
                    852:        for (pp = Player; pp < End_player; pp++) {
                    853:                cgoto(pp, HEIGHT, 0);
                    854:                sendcom(pp, ENDWIN);
                    855:                (void) putc(LAST_PLAYER, pp->p_output);
                    856:                (void) fclose(pp->p_output);
                    857:        }
                    858: # ifdef MONITOR
                    859:        for (pp = Monitor; pp < End_monitor; pp++) {
                    860:                cgoto(pp, HEIGHT, 0);
                    861:                sendcom(pp, ENDWIN);
                    862:                (void) putc(LAST_PLAYER, pp->p_output);
                    863:                (void) fclose(pp->p_output);
                    864:        }
                    865: # endif MONITOR
                    866:        (void) close(Socket);
                    867: # ifdef AF_UNIX_HACK
                    868:        (void) unlink(Sock_name);
                    869: # endif AF_UNIX_HACK
                    870: 
                    871:        exit(eval);
                    872: }
                    873: 
                    874: /*
                    875:  * send_stats:
                    876:  *     Print stats to requestor
                    877:  */
                    878: send_stats()
                    879: {
                    880:        register IDENT  *ip;
                    881:        register FILE   *fp;
                    882:        int             s;
                    883:        SOCKET          sockstruct;
                    884:        int             socklen;
                    885: 
                    886:        /*
                    887:         * Get the output stream ready
                    888:         */
                    889: # ifdef INTERNET
                    890:        socklen = sizeof sockstruct;
                    891: # else
                    892:        socklen = sizeof sockstruct - 1;
                    893: # endif INTERNET
                    894:        s = accept(Status, (struct sockaddr *) &sockstruct, &socklen);
                    895:        if (s < 0) {
                    896:                if (errno == EINTR)
                    897:                        return;
                    898: # ifdef LOG
                    899:                syslog(LOG_ERR, "accept: %m");
                    900: # else LOG
                    901:                perror("accept");
                    902: # endif LOG
                    903:                return;
                    904:        }
                    905:        fp = fdopen(s, "w");
                    906:        if (fp == NULL) {
                    907: # ifdef LOG
                    908:                syslog(LOG_ERR, "fdopen: %m");
                    909: # else
                    910:                perror("fdopen");
                    911: # endif
                    912:                (void) close(s);
                    913:                return;
                    914:        }
                    915: 
                    916:        /*
                    917:         * Send output to requestor
                    918:         */
                    919:        fputs("Name\t\tScore\tDucked\tAbsorb\tFaced\tShot\tRobbed\tMissed\tSlimeK\n", fp);
                    920:        for (ip = Scores; ip != NULL; ip = ip->i_next) {
                    921:                fprintf(fp, "%s\t", ip->i_name);
                    922:                if (strlen(ip->i_name) < 8)
                    923:                        putc('\t', fp);
                    924:                fprintf(fp, "%.2f\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
                    925:                        ip->i_score, ip->i_ducked, ip->i_absorbed,
                    926:                        ip->i_faced, ip->i_shot, ip->i_robbed,
                    927:                        ip->i_missed, ip->i_slime);
                    928:        }
                    929:        fputs("\n\nName\t\tEnemy\tFriend\tDeaths\tStill\tSaved\n", fp);
                    930:        for (ip = Scores; ip != NULL; ip = ip->i_next) {
                    931:                if (ip->i_team == ' ') {
                    932:                        fprintf(fp, "%s\t", ip->i_name);
                    933:                        if (strlen(ip->i_name) < 8)
                    934:                                putc('\t', fp);
                    935:                }
                    936:                else {
                    937:                        fprintf(fp, "%s[%c]\t", ip->i_name, ip->i_team);
                    938:                        if (strlen(ip->i_name) + 3 < 8)
                    939:                                putc('\t', fp);
                    940:                }
                    941:                fprintf(fp, "%d\t%d\t%d\t%d\t%d\n",
                    942:                        ip->i_gkills, ip->i_bkills, ip->i_deaths,
                    943:                        ip->i_stillb, ip->i_saved);
                    944:        }
                    945: 
                    946:        (void) fclose(fp);
                    947: }
                    948: 
                    949: /*
                    950:  * clear_scores:
                    951:  *     Clear out the scores so the next session start clean
                    952:  */
                    953: clear_scores()
                    954: {
                    955:        register IDENT  *ip, *nextip;
                    956: 
                    957:        for (ip = Scores; ip != NULL; ip = nextip) {
                    958:                nextip = ip->i_next;
                    959:                (void) free((char *) ip);
                    960:        }
                    961:        Scores = NULL;
                    962: }

unix.superglobalmegacorp.com

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