Annotation of 43BSDReno/games/hunt/NEW/shots.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: 
                     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.