Annotation of 43BSDReno/games/hunt/NEW/shots.c, revision 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: 
        !            14: # define       PLUS_DELTA(x, max)      if (x < max) x++; else x--
        !            15: # define       MINUS_DELTA(x, min)     if (x > min) x--; else x++
        !            16: 
        !            17: /*
        !            18:  * moveshots:
        !            19:  *     Move the shots already in the air, taking explosions into account
        !            20:  */
        !            21: moveshots()
        !            22: {
        !            23:        register BULLET *bp, *next;
        !            24:        register PLAYER *pp;
        !            25:        register int    x, y;
        !            26:        register BULLET *blist;
        !            27: 
        !            28:        rollexpl();
        !            29:        if (Bullets == NULL)
        !            30:                goto ret;
        !            31: 
        !            32:        /*
        !            33:         * First we move through the bullet list BULSPD times, looking
        !            34:         * for things we may have run into.  If we do run into
        !            35:         * something, we set up the explosion and disappear, checking
        !            36:         * for damage to any player who got in the way.
        !            37:         */
        !            38: 
        !            39:        blist = Bullets;
        !            40:        Bullets = NULL;
        !            41:        for (bp = blist; bp != NULL; bp = next) {
        !            42:                next = bp->b_next;
        !            43:                x = bp->b_x;
        !            44:                y = bp->b_y;
        !            45:                Maze[y][x] = bp->b_over;
        !            46:                for (pp = Player; pp < End_player; pp++)
        !            47:                        check(pp, y, x);
        !            48: # ifdef MONITOR
        !            49:                for (pp = Monitor; pp < End_monitor; pp++)
        !            50:                        check(pp, y, x);
        !            51: # endif MONITOR
        !            52: 
        !            53:                switch (bp->b_type) {
        !            54:                  case SHOT:
        !            55:                  case GRENADE:
        !            56:                  case SATCHEL:
        !            57:                  case BOMB:
        !            58:                        if (move_normal_shot(bp)) {
        !            59:                                bp->b_next = Bullets;
        !            60:                                Bullets = bp;
        !            61:                        }
        !            62:                        break;
        !            63: # ifdef OOZE
        !            64:                  case SLIME:
        !            65:                        if (bp->b_expl || move_normal_shot(bp)) {
        !            66:                                bp->b_next = Bullets;
        !            67:                                Bullets = bp;
        !            68:                        }
        !            69:                        break;
        !            70: # endif OOZE
        !            71: # ifdef DRONE
        !            72:                  case DSHOT:
        !            73:                        if (move_drone(bp)) {
        !            74:                                bp->b_next = Bullets;
        !            75:                                Bullets = bp;
        !            76:                        }
        !            77:                        break;
        !            78: # endif DRONE
        !            79:                  default:
        !            80:                        bp->b_next = Bullets;
        !            81:                        Bullets = bp;
        !            82:                        break;
        !            83:                }
        !            84:        }
        !            85: 
        !            86:        blist = Bullets;
        !            87:        Bullets = NULL;
        !            88:        for (bp = blist; bp != NULL; bp = next) {
        !            89:                next = bp->b_next;
        !            90:                if (!bp->b_expl) {
        !            91:                        save_bullet(bp);
        !            92: # ifdef MONITOR
        !            93:                        for (pp = Monitor; pp < End_monitor; pp++)
        !            94:                                check(pp, bp->b_y, bp->b_x);
        !            95: # endif MONITOR
        !            96: # ifdef DRONE
        !            97:                        if (bp->b_type == DSHOT)
        !            98:                                for (pp = Player; pp < End_player; pp++)
        !            99:                                        if (pp->p_scan >= 0)
        !           100:                                                check(pp, bp->b_y, bp->b_x);
        !           101: # endif        DRONE
        !           102:                        continue;
        !           103:                }
        !           104: 
        !           105:                chkshot(bp, next);
        !           106:                free((char *) bp);
        !           107:        }
        !           108: 
        !           109:        for (pp = Player; pp < End_player; pp++)
        !           110:                Maze[pp->p_y][pp->p_x] = pp->p_face;
        !           111: 
        !           112: ret:
        !           113: # ifdef BOOTS
        !           114:        for (pp = Boot; pp < &Boot[NBOOTS]; pp++)
        !           115:                if (pp->p_flying >= 0)
        !           116:                        move_flyer(pp);
        !           117: # endif        BOOTS
        !           118:        for (pp = Player; pp < End_player; pp++) {
        !           119: # ifdef FLY
        !           120:                if (pp->p_flying >= 0)
        !           121:                        move_flyer(pp);
        !           122: # endif FLY
        !           123:                sendcom(pp, REFRESH);   /* Flush out the explosions */
        !           124:                look(pp);
        !           125:                sendcom(pp, REFRESH);
        !           126:        }
        !           127: # ifdef MONITOR
        !           128:        for (pp = Monitor; pp < End_monitor; pp++)
        !           129:                sendcom(pp, REFRESH);
        !           130: # endif MONITOR
        !           131: 
        !           132:        return;
        !           133: }
        !           134: 
        !           135: /*
        !           136:  * move_normal_shot:
        !           137:  *     Move a normal shot along its trajectory
        !           138:  */
        !           139: move_normal_shot(bp)
        !           140: register BULLET        *bp;
        !           141: {
        !           142:        register int    i, x, y;
        !           143:        register PLAYER *pp;
        !           144: 
        !           145:        for (i = 0; i < BULSPD; i++) {
        !           146:                if (bp->b_expl)
        !           147:                        break;
        !           148: 
        !           149:                x = bp->b_x;
        !           150:                y = bp->b_y;
        !           151: 
        !           152:                switch (bp->b_face) {
        !           153:                  case LEFTS:
        !           154:                        x--;
        !           155:                        break;
        !           156:                  case RIGHT:
        !           157:                        x++;
        !           158:                        break;
        !           159:                  case ABOVE:
        !           160:                        y--;
        !           161:                        break;
        !           162:                  case BELOW:
        !           163:                        y++;
        !           164:                        break;
        !           165:                }
        !           166: 
        !           167:                switch (Maze[y][x]) {
        !           168:                  case SHOT:
        !           169:                        if (rand_num(100) < 5) {
        !           170:                                zapshot(Bullets, bp);
        !           171:                                zapshot(bp->b_next, bp);
        !           172:                        }
        !           173:                        break;
        !           174:                  case GRENADE:
        !           175:                        if (rand_num(100) < 10) {
        !           176:                                zapshot(Bullets, bp);
        !           177:                                zapshot(bp->b_next, bp);
        !           178:                        }
        !           179:                        break;
        !           180: # ifdef        REFLECT
        !           181:                  case WALL4:   /* reflecting walls */
        !           182:                        switch (bp->b_face) {
        !           183:                          case LEFTS:
        !           184:                                bp->b_face = BELOW;
        !           185:                                break;
        !           186:                          case RIGHT:
        !           187:                                bp->b_face = ABOVE;
        !           188:                                break;
        !           189:                          case ABOVE:
        !           190:                                bp->b_face = RIGHT;
        !           191:                                break;
        !           192:                          case BELOW:
        !           193:                                bp->b_face = LEFTS;
        !           194:                                break;
        !           195:                        }
        !           196:                        Maze[y][x] = WALL5;
        !           197: # ifdef MONITOR
        !           198:                        for (pp = Monitor; pp < End_monitor; pp++)
        !           199:                                check(pp, y, x);
        !           200: # endif MONITOR
        !           201:                        break;
        !           202:                  case WALL5:
        !           203:                        switch (bp->b_face) {
        !           204:                          case LEFTS:
        !           205:                                bp->b_face = ABOVE;
        !           206:                                break;
        !           207:                          case RIGHT:
        !           208:                                bp->b_face = BELOW;
        !           209:                                break;
        !           210:                          case ABOVE:
        !           211:                                bp->b_face = LEFTS;
        !           212:                                break;
        !           213:                          case BELOW:
        !           214:                                bp->b_face = RIGHT;
        !           215:                                break;
        !           216:                        }
        !           217:                        Maze[y][x] = WALL4;
        !           218: # ifdef MONITOR
        !           219:                        for (pp = Monitor; pp < End_monitor; pp++)
        !           220:                                check(pp, y, x);
        !           221: # endif MONITOR
        !           222:                        break;
        !           223: # endif REFLECT
        !           224: # ifdef RANDOM
        !           225:                  case DOOR:
        !           226:                        switch (rand_num(4)) {
        !           227:                          case 0:
        !           228:                                bp->b_face = ABOVE;
        !           229:                                break;
        !           230:                          case 1:
        !           231:                                bp->b_face = BELOW;
        !           232:                                break;
        !           233:                          case 2:
        !           234:                                bp->b_face = LEFTS;
        !           235:                                break;
        !           236:                          case 3:
        !           237:                                bp->b_face = RIGHT;
        !           238:                                break;
        !           239:                        }
        !           240:                        break;
        !           241: # endif RANDOM
        !           242: # ifdef FLY
        !           243:                  case FLYER:
        !           244:                        pp = play_at(y, x);
        !           245:                        message(pp, "Zing!");
        !           246:                        break;
        !           247: # endif FLY
        !           248:                  case LEFTS:
        !           249:                  case RIGHT:
        !           250:                  case BELOW:
        !           251:                  case ABOVE:
        !           252:                        /*
        !           253:                         * give the person a chance to catch a
        !           254:                         * grenade if s/he is facing it
        !           255:                         */
        !           256:                        pp = play_at(y, x);
        !           257:                        pp->p_ident->i_shot += bp->b_charge;
        !           258:                        if (opposite(bp->b_face, Maze[y][x])) {
        !           259:                            if (rand_num(100) < 10) {
        !           260:                                if (bp->b_owner != NULL)
        !           261:                                        message(bp->b_owner,
        !           262:                                            "Your charge was absorbed!");
        !           263:                                if (bp->b_score != NULL)
        !           264:                                        bp->b_score->i_robbed += bp->b_charge;
        !           265:                                pp->p_ammo += bp->b_charge;
        !           266:                                if (pp->p_damage + bp->b_size * MINDAM
        !           267:                                    > pp->p_damcap)
        !           268:                                        pp->p_ident->i_saved++;
        !           269:                                message(pp, "Absorbed charge (good shield!)");
        !           270:                                pp->p_ident->i_absorbed += bp->b_charge;
        !           271:                                free((char *) bp);
        !           272:                                (void) sprintf(Buf, "%3d", pp->p_ammo);
        !           273:                                cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
        !           274:                                outstr(pp, Buf, 3);
        !           275:                                return FALSE;
        !           276:                            }
        !           277:                            pp->p_ident->i_faced += bp->b_charge;
        !           278:                        }
        !           279:                        /*
        !           280:                         * Small chance that the bullet just misses the
        !           281:                         * person.  If so, the bullet just goes on its
        !           282:                         * merry way without exploding.
        !           283:                         */
        !           284:                        if (rand_num(100) < 5) {
        !           285:                                pp->p_ident->i_ducked += bp->b_charge;
        !           286:                                if (pp->p_damage + bp->b_size * MINDAM
        !           287:                                    > pp->p_damcap)
        !           288:                                        pp->p_ident->i_saved++;
        !           289:                                if (bp->b_score != NULL)
        !           290:                                        bp->b_score->i_missed += bp->b_charge;
        !           291:                                message(pp, "Zing!");
        !           292:                                if (bp->b_owner == NULL)
        !           293:                                        break;
        !           294:                                message(bp->b_owner,
        !           295:                                        ((bp->b_score->i_missed & 0x7) == 0x7) ?
        !           296:                                        "My!  What a bad shot you are!" :
        !           297:                                        "Missed him");
        !           298:                                break;
        !           299:                        }
        !           300:                        /*
        !           301:                         * The shot hit that sucker!  Blow it up.
        !           302:                         */
        !           303:                        /* FALLTHROUGH */
        !           304: # ifndef RANDOM
        !           305:                  case DOOR:
        !           306: # endif RANDOM
        !           307:                  case WALL1:
        !           308:                  case WALL2:
        !           309:                  case WALL3:
        !           310:                        bp->b_expl = TRUE;
        !           311:                        break;
        !           312:                }
        !           313: 
        !           314:                bp->b_x = x;
        !           315:                bp->b_y = y;
        !           316:        }
        !           317:        return TRUE;
        !           318: }
        !           319: 
        !           320: # ifdef        DRONE
        !           321: /*
        !           322:  * move_drone:
        !           323:  *     Move the drone to the next square
        !           324:  */
        !           325: move_drone(bp)
        !           326: register BULLET        *bp;
        !           327: {
        !           328:        register int    mask, count;
        !           329:        register int    n, dir;
        !           330:        register PLAYER *pp;
        !           331: 
        !           332:        /*
        !           333:         * See if we can give someone a blast
        !           334:         */
        !           335:        if (isplayer(Maze[bp->b_y][bp->b_x - 1])) {
        !           336:                dir = WEST;
        !           337:                goto drone_move;
        !           338:        }
        !           339:        if (isplayer(Maze[bp->b_y - 1][bp->b_x])) {
        !           340:                dir = NORTH;
        !           341:                goto drone_move;
        !           342:        }
        !           343:        if (isplayer(Maze[bp->b_y + 1][bp->b_x])) {
        !           344:                dir = SOUTH;
        !           345:                goto drone_move;
        !           346:        }
        !           347:        if (isplayer(Maze[bp->b_y][bp->b_x + 1])) {
        !           348:                dir = EAST;
        !           349:                goto drone_move;
        !           350:        }
        !           351: 
        !           352:        /*
        !           353:         * Find out what directions are clear
        !           354:         */
        !           355:        mask = count = 0;
        !           356:        if (!iswall(bp->b_y, bp->b_x - 1))
        !           357:                mask |= WEST, count++;
        !           358:        if (!iswall(bp->b_y - 1, bp->b_x))
        !           359:                mask |= NORTH, count++;
        !           360:        if (!iswall(bp->b_y + 1, bp->b_x))
        !           361:                mask |= SOUTH, count++;
        !           362:        if (!iswall(bp->b_y, bp->b_x + 1))
        !           363:                mask |= EAST, count++;
        !           364: 
        !           365:        /*
        !           366:         * All blocked up, just you wait
        !           367:         */
        !           368:        if (count == 0)
        !           369:                return TRUE;
        !           370: 
        !           371:        /*
        !           372:         * Only one way to go.
        !           373:         */
        !           374:        if (count == 1) {
        !           375:                dir = mask;
        !           376:                goto drone_move;
        !           377:        }
        !           378: 
        !           379:        /*
        !           380:         * Get rid of the direction that we came from
        !           381:         */
        !           382:        switch (bp->b_face) {
        !           383:          case LEFTS:
        !           384:                if (mask & EAST)
        !           385:                        mask &= ~EAST, count--;
        !           386:                break;
        !           387:          case RIGHT:
        !           388:                if (mask & WEST)
        !           389:                        mask &= ~WEST, count--;
        !           390:                break;
        !           391:          case ABOVE:
        !           392:                if (mask & SOUTH)
        !           393:                        mask &= ~SOUTH, count--;
        !           394:                break;
        !           395:          case BELOW:
        !           396:                if (mask & NORTH)
        !           397:                        mask &= ~NORTH, count--;
        !           398:                break;
        !           399:        }
        !           400: 
        !           401:        /*
        !           402:         * Pick one of the remaining directions
        !           403:         */
        !           404:        n = rand_num(count);
        !           405:        if (n >= 0 && mask & NORTH)
        !           406:                dir = NORTH, n--;
        !           407:        if (n >= 0 && mask & SOUTH)
        !           408:                dir = SOUTH, n--;
        !           409:        if (n >= 0 && mask & EAST)
        !           410:                dir = EAST, n--;
        !           411:        if (n >= 0 && mask & WEST)
        !           412:                dir = WEST, n--;
        !           413: 
        !           414:        /*
        !           415:         * Now that we know the direction of movement,
        !           416:         * just update the position of the drone
        !           417:         */
        !           418: drone_move:
        !           419:        switch (dir) {
        !           420:          case WEST:
        !           421:                bp->b_x--;
        !           422:                bp->b_face = LEFTS;
        !           423:                break;
        !           424:          case EAST:
        !           425:                bp->b_x++;
        !           426:                bp->b_face = RIGHT;
        !           427:                break;
        !           428:          case NORTH:
        !           429:                bp->b_y--;
        !           430:                bp->b_face = ABOVE;
        !           431:                break;
        !           432:          case SOUTH:
        !           433:                bp->b_y++;
        !           434:                bp->b_face = BELOW;
        !           435:                break;
        !           436:        }
        !           437:        switch (Maze[bp->b_y][bp->b_x]) {
        !           438:          case LEFTS:
        !           439:          case RIGHT:
        !           440:          case BELOW:
        !           441:          case ABOVE:
        !           442:                /*
        !           443:                 * give the person a chance to catch a
        !           444:                 * drone if s/he is facing it
        !           445:                 */
        !           446:                if (rand_num(100) < 1 &&
        !           447:                opposite(bp->b_face, Maze[bp->b_y][bp->b_x])) {
        !           448:                        pp = play_at(bp->b_y, bp->b_x);
        !           449:                        pp->p_ammo += bp->b_charge;
        !           450:                        message(pp, "**** Absorbed drone ****");
        !           451:                        free((char *) bp);
        !           452:                        (void) sprintf(Buf, "%3d", pp->p_ammo);
        !           453:                        cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
        !           454:                        outstr(pp, Buf, 3);
        !           455:                        return FALSE;
        !           456:                }
        !           457:                bp->b_expl = TRUE;
        !           458:                break;
        !           459:        }
        !           460:        return TRUE;
        !           461: }
        !           462: # endif DRONE
        !           463: 
        !           464: /*
        !           465:  * save_bullet:
        !           466:  *     Put this bullet back onto the bullet list
        !           467:  */
        !           468: save_bullet(bp)
        !           469: register BULLET        *bp;
        !           470: {
        !           471:        bp->b_over = Maze[bp->b_y][bp->b_x];
        !           472:        switch (bp->b_over) {
        !           473:          case SHOT:
        !           474:          case GRENADE:
        !           475:          case SATCHEL:
        !           476:          case BOMB:
        !           477: # ifdef OOZE
        !           478:          case SLIME:
        !           479: # ifdef VOLCANO
        !           480:          case LAVA:
        !           481: # endif VOLCANO
        !           482: # endif OOZE
        !           483: # ifdef DRONE
        !           484:          case DSHOT:
        !           485: # endif DRONE
        !           486:                find_under(Bullets, bp);
        !           487:                break;
        !           488:        }
        !           489: 
        !           490:        switch (bp->b_over) {
        !           491:          case LEFTS:
        !           492:          case RIGHT:
        !           493:          case ABOVE:
        !           494:          case BELOW:
        !           495: # ifdef FLY
        !           496:          case FLYER:
        !           497: # endif FLY
        !           498:                mark_player(bp);
        !           499:                break;
        !           500: # ifdef BOOTS
        !           501:          case BOOT:
        !           502:          case BOOT_PAIR:
        !           503:                mark_boot(bp);
        !           504: # endif BOOTS
        !           505:                
        !           506:          default:
        !           507:                Maze[bp->b_y][bp->b_x] = bp->b_type;
        !           508:                break;
        !           509:        }
        !           510: 
        !           511:        bp->b_next = Bullets;
        !           512:        Bullets = bp;
        !           513: }
        !           514: 
        !           515: /*
        !           516:  * move_flyer:
        !           517:  *     Update the position of a player in flight
        !           518:  */
        !           519: move_flyer(pp)
        !           520: register PLAYER        *pp;
        !           521: {
        !           522:        register int    x, y;
        !           523: 
        !           524:        if (pp->p_undershot) {
        !           525:                fixshots(pp->p_y, pp->p_x, pp->p_over);
        !           526:                pp->p_undershot = FALSE;
        !           527:        }
        !           528:        Maze[pp->p_y][pp->p_x] = pp->p_over;
        !           529:        x = pp->p_x + pp->p_flyx;
        !           530:        y = pp->p_y + pp->p_flyy;
        !           531:        if (x < 1) {
        !           532:                x = 1 - x;
        !           533:                pp->p_flyx = -pp->p_flyx;
        !           534:        }
        !           535:        else if (x > WIDTH - 2) {
        !           536:                x = (WIDTH - 2) - (x - (WIDTH - 2));
        !           537:                pp->p_flyx = -pp->p_flyx;
        !           538:        }
        !           539:        if (y < 1) {
        !           540:                y = 1 - y;
        !           541:                pp->p_flyy = -pp->p_flyy;
        !           542:        }
        !           543:        else if (y > HEIGHT - 2) {
        !           544:                y = (HEIGHT - 2) - (y - (HEIGHT - 2));
        !           545:                pp->p_flyy = -pp->p_flyy;
        !           546:        }
        !           547: again:
        !           548:        switch (Maze[y][x]) {
        !           549:          default:
        !           550:                switch (rand_num(4)) {
        !           551:                  case 0:
        !           552:                        PLUS_DELTA(x, WIDTH - 2);
        !           553:                        break;
        !           554:                  case 1:
        !           555:                        MINUS_DELTA(x, 1);
        !           556:                        break;
        !           557:                  case 2:
        !           558:                        PLUS_DELTA(y, HEIGHT - 2);
        !           559:                        break;
        !           560:                  case 3:
        !           561:                        MINUS_DELTA(y, 1);
        !           562:                        break;
        !           563:                }
        !           564:                goto again;
        !           565:          case WALL1:
        !           566:          case WALL2:
        !           567:          case WALL3:
        !           568: # ifdef        REFLECT
        !           569:          case WALL4:
        !           570:          case WALL5:
        !           571: # endif REFLECT
        !           572: # ifdef        RANDOM
        !           573:          case DOOR:
        !           574: # endif        RANDOM
        !           575:                if (pp->p_flying == 0)
        !           576:                        pp->p_flying++;
        !           577:                break;
        !           578:          case SPACE:
        !           579:                break;
        !           580:        }
        !           581:        pp->p_y = y;
        !           582:        pp->p_x = x;
        !           583:        if (pp->p_flying-- == 0) {
        !           584: # ifdef BOOTS
        !           585:                if (pp->p_face != BOOT && pp->p_face != BOOT_PAIR) {
        !           586: # endif
        !           587:                        checkdam(pp, (PLAYER *) NULL, (IDENT *) NULL,
        !           588:                                rand_num(pp->p_damage / 5), FALL);
        !           589:                        pp->p_face = rand_dir();
        !           590:                        showstat(pp);
        !           591: # ifdef BOOTS
        !           592:                }
        !           593:                else {
        !           594:                        if (Maze[y][x] == BOOT)
        !           595:                                pp->p_face = BOOT_PAIR;
        !           596:                        Maze[y][x] = SPACE;
        !           597:                }
        !           598: # endif BOOTS
        !           599:        }
        !           600:        pp->p_over = Maze[y][x];
        !           601:        Maze[y][x] = pp->p_face;
        !           602:        showexpl(y, x, pp->p_face);
        !           603: }
        !           604: 
        !           605: /*
        !           606:  * chkshot
        !           607:  *     Handle explosions
        !           608:  */
        !           609: chkshot(bp, next)
        !           610: register BULLET        *bp;
        !           611: BULLET         *next;
        !           612: {
        !           613:        register int    y, x;
        !           614:        register int    dy, dx, absdy;
        !           615:        register int    delta, damage;
        !           616:        register char   expl;
        !           617:        register PLAYER *pp;
        !           618: 
        !           619:        switch (bp->b_type) {
        !           620:          case SHOT:
        !           621:          case MINE:
        !           622:          case GRENADE:
        !           623:          case GMINE:
        !           624:          case SATCHEL:
        !           625:          case BOMB:
        !           626:                delta = bp->b_size - 1;
        !           627:                break;
        !           628: # ifdef        OOZE
        !           629:          case SLIME:
        !           630: # ifdef VOLCANO
        !           631:          case LAVA:
        !           632: # endif VOLCANO
        !           633:                chkslime(bp, next);
        !           634:                return;
        !           635: # endif        OOZE
        !           636: # ifdef DRONE
        !           637:          case DSHOT:
        !           638:                bp->b_type = SLIME;
        !           639:                chkslime(bp, next);
        !           640:                return;
        !           641: # endif DRONE
        !           642:        }
        !           643:        for (y = bp->b_y - delta; y <= bp->b_y + delta; y++) {
        !           644:                if (y < 0 || y >= HEIGHT)
        !           645:                        continue;
        !           646:                dy = y - bp->b_y;
        !           647:                absdy = (dy < 0) ? -dy : dy;
        !           648:                for (x = bp->b_x - delta; x <= bp->b_x + delta; x++) {
        !           649:                        if (x < 0 || x >= WIDTH)
        !           650:                                continue;
        !           651:                        dx = x - bp->b_x;
        !           652:                        if (dx == 0)
        !           653:                                expl = (dy == 0) ? '*' : '|';
        !           654:                        else if (dy == 0)
        !           655:                                expl = '-';
        !           656:                        else if (dx == dy)
        !           657:                                expl = '\\';
        !           658:                        else if (dx == -dy)
        !           659:                                expl = '/';
        !           660:                        else
        !           661:                                expl = '*';
        !           662:                        showexpl(y, x, expl);
        !           663:                        switch (Maze[y][x]) {
        !           664:                          case LEFTS:
        !           665:                          case RIGHT:
        !           666:                          case ABOVE:
        !           667:                          case BELOW:
        !           668: # ifdef FLY
        !           669:                          case FLYER:
        !           670: # endif FLY
        !           671:                                if (dx < 0)
        !           672:                                        dx = -dx;
        !           673:                                if (absdy > dx)
        !           674:                                        damage = bp->b_size - absdy;
        !           675:                                else
        !           676:                                        damage = bp->b_size - dx;
        !           677:                                pp = play_at(y, x);
        !           678:                                checkdam(pp, bp->b_owner, bp->b_score,
        !           679:                                        damage * MINDAM, bp->b_type);
        !           680:                                break;
        !           681:                          case GMINE:
        !           682:                          case MINE:
        !           683:                                add_shot((Maze[y][x] == GMINE) ?
        !           684:                                        GRENADE : SHOT,
        !           685:                                        y, x, LEFTS,
        !           686:                                        (Maze[y][x] == GMINE) ?
        !           687:                                        GRENREQ : BULREQ,
        !           688:                                        (PLAYER *) NULL, TRUE, SPACE);
        !           689:                                Maze[y][x] = SPACE;
        !           690:                                break;
        !           691:                        }
        !           692:                }
        !           693:        }
        !           694: }
        !           695: 
        !           696: # ifdef        OOZE
        !           697: /*
        !           698:  * chkslime:
        !           699:  *     handle slime shot exploding
        !           700:  */
        !           701: chkslime(bp, next)
        !           702: register BULLET        *bp;
        !           703: BULLET         *next;
        !           704: {
        !           705:        register BULLET *nbp;
        !           706: 
        !           707:        switch (Maze[bp->b_y][bp->b_x]) {
        !           708:          case WALL1:
        !           709:          case WALL2:
        !           710:          case WALL3:
        !           711: # ifdef        REFLECT
        !           712:          case WALL4:
        !           713:          case WALL5:
        !           714: # endif REFLECT
        !           715: # ifdef        RANDOM
        !           716:          case DOOR:
        !           717: # endif        RANDOM
        !           718:                switch (bp->b_face) {
        !           719:                  case LEFTS:
        !           720:                        bp->b_x++;
        !           721:                        break;
        !           722:                  case RIGHT:
        !           723:                        bp->b_x--;
        !           724:                        break;
        !           725:                  case ABOVE:
        !           726:                        bp->b_y++;
        !           727:                        break;
        !           728:                  case BELOW:
        !           729:                        bp->b_y--;
        !           730:                        break;
        !           731:                }
        !           732:                break;
        !           733:        }
        !           734:        nbp = (BULLET *) malloc(sizeof (BULLET));
        !           735:        *nbp = *bp;
        !           736: # ifdef VOLCANO
        !           737:        move_slime(nbp, nbp->b_type == SLIME ? SLIMESPEED : LAVASPEED, next);
        !           738: # else VOLCANO
        !           739:        move_slime(nbp, SLIMESPEED, next);
        !           740: # endif VOLCANO
        !           741: }
        !           742: 
        !           743: /*
        !           744:  * move_slime:
        !           745:  *     move the given slime shot speed times and add it back if
        !           746:  *     it hasn't fizzled yet
        !           747:  */
        !           748: move_slime(bp, speed, next)
        !           749: register BULLET        *bp;
        !           750: register int   speed;
        !           751: BULLET         *next;
        !           752: {
        !           753:        register int    i, j, dirmask, count;
        !           754:        register PLAYER *pp;
        !           755:        register BULLET *nbp;
        !           756: 
        !           757:        if (speed == 0) {
        !           758:                if (bp->b_charge <= 0)
        !           759:                        free((char *) bp);
        !           760:                else
        !           761:                        save_bullet(bp);
        !           762:                return;
        !           763:        }
        !           764: 
        !           765: # ifdef VOLCANO
        !           766:        showexpl(bp->b_y, bp->b_x, bp->b_type == LAVA ? LAVA : '*');
        !           767: # else VOLCANO
        !           768:        showexpl(bp->b_y, bp->b_x, '*');
        !           769: # endif VOLCANO
        !           770:        switch (Maze[bp->b_y][bp->b_x]) {
        !           771:          case LEFTS:
        !           772:          case RIGHT:
        !           773:          case ABOVE:
        !           774:          case BELOW:
        !           775: # ifdef FLY
        !           776:          case FLYER:
        !           777: # endif FLY
        !           778:                pp = play_at(bp->b_y, bp->b_x);
        !           779:                message(pp, "You've been slimed.");
        !           780:                checkdam(pp, bp->b_owner, bp->b_score, MINDAM, bp->b_type);
        !           781:                break;
        !           782:          case SHOT:
        !           783:          case GRENADE:
        !           784:          case SATCHEL:
        !           785:          case BOMB:
        !           786: # ifdef DRONE
        !           787:          case DSHOT:
        !           788: # endif DRONE
        !           789:                explshot(next, bp->b_y, bp->b_x);
        !           790:                explshot(Bullets, bp->b_y, bp->b_x);
        !           791:                break;
        !           792:        }
        !           793: 
        !           794:        if (--bp->b_charge <= 0) {
        !           795:                free((char *) bp);
        !           796:                return;
        !           797:        }
        !           798: 
        !           799:        dirmask = 0;
        !           800:        count = 0;
        !           801:        switch (bp->b_face) {
        !           802:          case LEFTS:
        !           803:                if (!iswall(bp->b_y, bp->b_x - 1))
        !           804:                        dirmask |= WEST, count++;
        !           805:                if (!iswall(bp->b_y - 1, bp->b_x))
        !           806:                        dirmask |= NORTH, count++;
        !           807:                if (!iswall(bp->b_y + 1, bp->b_x))
        !           808:                        dirmask |= SOUTH, count++;
        !           809:                if (dirmask == 0)
        !           810:                        if (!iswall(bp->b_y, bp->b_x + 1))
        !           811:                                dirmask |= EAST, count++;
        !           812:                break;
        !           813:          case RIGHT:
        !           814:                if (!iswall(bp->b_y, bp->b_x + 1))
        !           815:                        dirmask |= EAST, count++;
        !           816:                if (!iswall(bp->b_y - 1, bp->b_x))
        !           817:                        dirmask |= NORTH, count++;
        !           818:                if (!iswall(bp->b_y + 1, bp->b_x))
        !           819:                        dirmask |= SOUTH, count++;
        !           820:                if (dirmask == 0)
        !           821:                        if (!iswall(bp->b_y, bp->b_x - 1))
        !           822:                                dirmask |= WEST, count++;
        !           823:                break;
        !           824:          case ABOVE:
        !           825:                if (!iswall(bp->b_y - 1, bp->b_x))
        !           826:                        dirmask |= NORTH, count++;
        !           827:                if (!iswall(bp->b_y, bp->b_x - 1))
        !           828:                        dirmask |= WEST, count++;
        !           829:                if (!iswall(bp->b_y, bp->b_x + 1))
        !           830:                        dirmask |= EAST, count++;
        !           831:                if (dirmask == 0)
        !           832:                        if (!iswall(bp->b_y + 1, bp->b_x))
        !           833:                                dirmask |= SOUTH, count++;
        !           834:                break;
        !           835:          case BELOW:
        !           836:                if (!iswall(bp->b_y + 1, bp->b_x))
        !           837:                        dirmask |= SOUTH, count++;
        !           838:                if (!iswall(bp->b_y, bp->b_x - 1))
        !           839:                        dirmask |= WEST, count++;
        !           840:                if (!iswall(bp->b_y, bp->b_x + 1))
        !           841:                        dirmask |= EAST, count++;
        !           842:                if (dirmask == 0)
        !           843:                        if (!iswall(bp->b_y - 1, bp->b_x))
        !           844:                                dirmask |= NORTH, count++;
        !           845:                break;
        !           846:        }
        !           847:        if (count == 0) {
        !           848:                /*
        !           849:                 * No place to go.  Just sit here for a while and wait
        !           850:                 * for adjacent squares to clear out.
        !           851:                 */
        !           852:                save_bullet(bp);
        !           853:                return;
        !           854:        }
        !           855:        if (bp->b_charge < count) {
        !           856:                /* Only bp->b_charge paths may be taken */
        !           857:                while (count > bp->b_charge) {
        !           858:                        if (dirmask & WEST)
        !           859:                                dirmask &= ~WEST;
        !           860:                        else if (dirmask & EAST)
        !           861:                                dirmask &= ~EAST;
        !           862:                        else if (dirmask & NORTH)
        !           863:                                dirmask &= ~NORTH;
        !           864:                        else if (dirmask & SOUTH)
        !           865:                                dirmask &= ~SOUTH;
        !           866:                        count--;
        !           867:                }
        !           868:        }
        !           869: 
        !           870:        i = bp->b_charge / count;
        !           871:        j = bp->b_charge % count;
        !           872:        if (dirmask & WEST) {
        !           873:                count--;
        !           874:                nbp = create_shot(bp->b_type, bp->b_y, bp->b_x - 1, LEFTS,
        !           875:                        i, bp->b_size, bp->b_owner, bp->b_score, TRUE, SPACE);
        !           876:                move_slime(nbp, speed - 1, next);
        !           877:        }
        !           878:        if (dirmask & EAST) {
        !           879:                count--;
        !           880:                nbp = create_shot(bp->b_type, bp->b_y, bp->b_x + 1, RIGHT,
        !           881:                        (count < j) ? i + 1 : i, bp->b_size, bp->b_owner,
        !           882:                        bp->b_score, TRUE, SPACE);
        !           883:                move_slime(nbp, speed - 1, next);
        !           884:        }
        !           885:        if (dirmask & NORTH) {
        !           886:                count--;
        !           887:                nbp = create_shot(bp->b_type, bp->b_y - 1, bp->b_x, ABOVE,
        !           888:                        (count < j) ? i + 1 : i, bp->b_size, bp->b_owner,
        !           889:                        bp->b_score, TRUE, SPACE);
        !           890:                move_slime(nbp, speed - 1, next);
        !           891:        }
        !           892:        if (dirmask & SOUTH) {
        !           893:                count--;
        !           894:                nbp = create_shot(bp->b_type, bp->b_y + 1, bp->b_x, BELOW,
        !           895:                        (count < j) ? i + 1 : i, bp->b_size, bp->b_owner,
        !           896:                        bp->b_score, TRUE, SPACE);
        !           897:                move_slime(nbp, speed - 1, next);
        !           898:        }
        !           899: 
        !           900:        free((char *) bp);
        !           901: }
        !           902: 
        !           903: /*
        !           904:  * iswall:
        !           905:  *     returns whether the given location is a wall
        !           906:  */
        !           907: iswall(y, x)
        !           908: register int   y, x;
        !           909: {
        !           910:        if (y < 0 || x < 0 || y >= HEIGHT || x >= WIDTH)
        !           911:                return TRUE;
        !           912:        switch (Maze[y][x]) {
        !           913:          case WALL1:
        !           914:          case WALL2:
        !           915:          case WALL3:
        !           916: # ifdef        REFLECT
        !           917:          case WALL4:
        !           918:          case WALL5:
        !           919: # endif        REFLECT
        !           920: # ifdef        RANDOM
        !           921:          case DOOR:
        !           922: # endif        RANDOM
        !           923: # ifdef OOZE
        !           924:          case SLIME:
        !           925: # ifdef VOLCANO
        !           926:          case LAVA:
        !           927: # endif VOLCANO
        !           928: # endif OOZE
        !           929:                return TRUE;
        !           930:        }
        !           931:        return FALSE;
        !           932: }
        !           933: # endif        OOZE
        !           934: 
        !           935: /*
        !           936:  * zapshot:
        !           937:  *     Take a shot out of the air.
        !           938:  */
        !           939: zapshot(blist, obp)
        !           940: register BULLET        *blist, *obp;
        !           941: {
        !           942:        register BULLET *bp;
        !           943:        register FLAG   explode;
        !           944: 
        !           945:        explode = FALSE;
        !           946:        for (bp = blist; bp != NULL; bp = bp->b_next) {
        !           947:                if (bp->b_x != obp->b_x || bp->b_y != obp->b_y)
        !           948:                        continue;
        !           949:                if (bp->b_face == obp->b_face)
        !           950:                        continue;
        !           951:                explode = TRUE;
        !           952:                break;
        !           953:        }
        !           954:        if (!explode)
        !           955:                return;
        !           956:        explshot(blist, obp->b_y, obp->b_x);
        !           957: }
        !           958: 
        !           959: /*
        !           960:  * explshot -
        !           961:  *     Make all shots at this location blow up
        !           962:  */
        !           963: explshot(blist, y, x)
        !           964: register BULLET        *blist;
        !           965: register int   y, x;
        !           966: {
        !           967:        register BULLET *bp;
        !           968: 
        !           969:        for (bp = blist; bp != NULL; bp = bp->b_next)
        !           970:                if (bp->b_x == x && bp->b_y == y) {
        !           971:                        bp->b_expl = TRUE;
        !           972:                        if (bp->b_owner != NULL)
        !           973:                                message(bp->b_owner, "Shot intercepted");
        !           974:                }
        !           975: }
        !           976: 
        !           977: /*
        !           978:  * play_at:
        !           979:  *     Return a pointer to the player at the given location
        !           980:  */
        !           981: PLAYER *
        !           982: play_at(y, x)
        !           983: register int   y, x;
        !           984: {
        !           985:        register PLAYER *pp;
        !           986: 
        !           987:        for (pp = Player; pp < End_player; pp++)
        !           988:                if (pp->p_x == x && pp->p_y == y)
        !           989:                        return pp;
        !           990:        fprintf(stderr, "driver: couldn't find player at (%d,%d)\n", x, y);
        !           991:        abort();
        !           992:        /* NOTREACHED */
        !           993: }
        !           994: 
        !           995: /*
        !           996:  * opposite:
        !           997:  *     Return TRUE if the bullet direction faces the opposite direction
        !           998:  *     of the player in the maze
        !           999:  */
        !          1000: opposite(face, dir)
        !          1001: int    face;
        !          1002: char   dir;
        !          1003: {
        !          1004:        switch (face) {
        !          1005:          case LEFTS:
        !          1006:                return (dir == RIGHT);
        !          1007:          case RIGHT:
        !          1008:                return (dir == LEFTS);
        !          1009:          case ABOVE:
        !          1010:                return (dir == BELOW);
        !          1011:          case BELOW:
        !          1012:                return (dir == ABOVE);
        !          1013:          default:
        !          1014:                return FALSE;
        !          1015:        }
        !          1016: }
        !          1017: 
        !          1018: /*
        !          1019:  * is_bullet:
        !          1020:  *     Is there a bullet at the given coordinates?  If so, return
        !          1021:  *     a pointer to the bullet, otherwise return NULL
        !          1022:  */
        !          1023: BULLET *
        !          1024: is_bullet(y, x)
        !          1025: register int   y, x;
        !          1026: {
        !          1027:        register BULLET *bp;
        !          1028: 
        !          1029:        for (bp = Bullets; bp != NULL; bp = bp->b_next)
        !          1030:                if (bp->b_y == y && bp->b_x == x)
        !          1031:                        return bp;
        !          1032:        return NULL;
        !          1033: }
        !          1034: 
        !          1035: /*
        !          1036:  * fixshots:
        !          1037:  *     change the underlying character of the shots at a location
        !          1038:  *     to the given character.
        !          1039:  */
        !          1040: fixshots(y, x, over)
        !          1041: register int   y, x;
        !          1042: char           over;
        !          1043: {
        !          1044:        register BULLET *bp;
        !          1045: 
        !          1046:        for (bp = Bullets; bp != NULL; bp = bp->b_next)
        !          1047:                if (bp->b_y == y && bp->b_x == x)
        !          1048:                        bp->b_over = over;
        !          1049: }
        !          1050: 
        !          1051: /*
        !          1052:  * find_under:
        !          1053:  *     find the underlying character for a bullet when it lands
        !          1054:  *     on another bullet.
        !          1055:  */
        !          1056: find_under(blist, bp)
        !          1057: register BULLET        *blist, *bp;
        !          1058: {
        !          1059:        register BULLET *nbp;
        !          1060: 
        !          1061:        for (nbp = blist; nbp != NULL; nbp = nbp->b_next)
        !          1062:                if (bp->b_y == nbp->b_y && bp->b_x == nbp->b_x) {
        !          1063:                        bp->b_over = nbp->b_over;
        !          1064:                        break;
        !          1065:                }
        !          1066: }
        !          1067: 
        !          1068: /*
        !          1069:  * mark_player:
        !          1070:  *     mark a player as under a shot
        !          1071:  */
        !          1072: mark_player(bp)
        !          1073: register BULLET        *bp;
        !          1074: {
        !          1075:        register PLAYER *pp;
        !          1076: 
        !          1077:        for (pp = Player; pp < End_player; pp++)
        !          1078:                if (pp->p_y == bp->b_y && pp->p_x == bp->b_x) {
        !          1079:                        pp->p_undershot = TRUE;
        !          1080:                        break;
        !          1081:                }
        !          1082: }
        !          1083: 
        !          1084: # ifdef BOOTS
        !          1085: /*
        !          1086:  * mark_boot:
        !          1087:  *     mark a boot as under a shot
        !          1088:  */
        !          1089: mark_boot(bp)
        !          1090: register BULLET        *bp;
        !          1091: {
        !          1092:        register PLAYER *pp;
        !          1093: 
        !          1094:        for (pp = Boot; pp < &Boot[NBOOTS]; pp++)
        !          1095:                if (pp->p_y == bp->b_y && pp->p_x == bp->b_x) {
        !          1096:                        pp->p_undershot = TRUE;
        !          1097:                        break;
        !          1098:                }
        !          1099: }
        !          1100: # endif BOOTS

unix.superglobalmegacorp.com

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