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:     register int    i;
  28: 
  29:     rollexpl();
  30:     if (Bullets == NULL)
  31:         goto ret;
  32: 
  33:     /*
  34: 	 * First we move through the bullet list BULSPD times, looking
  35: 	 * for things we may have run into.  If we do run into
  36: 	 * something, we set up the explosion and disappear, checking
  37: 	 * for damage to any player who got in the way.
  38: 	 */
  39: 
  40:     blist = Bullets;
  41:     Bullets = NULL;
  42:     for (bp = blist; bp != NULL; bp = next) {
  43:         next = bp->b_next;
  44:         x = bp->b_x;
  45:         y = bp->b_y;
  46:         Maze[y][x] = bp->b_over;
  47:         for (pp = Player; pp < End_player; pp++)
  48:             check(pp, y, x);
  49: # ifdef MONITOR
  50:         for (pp = Monitor; pp < End_monitor; pp++)
  51:             check(pp, y, x);
  52: # endif MONITOR
  53: 
  54:         for (i = 0; i < BULSPD; i++) {
  55:             if (bp->b_expl)
  56:                 break;
  57: 
  58:             x = bp->b_x;
  59:             y = bp->b_y;
  60: 
  61:             switch (bp->b_face) {
  62:               case LEFTS:
  63:                 x--;
  64:                 break;
  65:               case RIGHT:
  66:                 x++;
  67:                 break;
  68:               case ABOVE:
  69:                 y--;
  70:                 break;
  71:               case BELOW:
  72:                 y++;
  73:                 break;
  74:             }
  75: 
  76:             switch (Maze[y][x]) {
  77:               case SHOT:
  78:                 if (rand_num(100) < 5) {
  79:                     zapshot(Bullets, bp);
  80:                     zapshot(next, bp);
  81:                 }
  82:                 break;
  83:               case GRENADE:
  84:                 if (rand_num(100) < 10) {
  85:                     zapshot(Bullets, bp);
  86:                     zapshot(next, bp);
  87:                 }
  88:                 break;
  89: # ifdef REFLECT
  90:               case WALL4:   /* reflecting walls */
  91:                 switch (bp->b_face) {
  92:                   case LEFTS:
  93:                     bp->b_face = BELOW;
  94:                     break;
  95:                   case RIGHT:
  96:                     bp->b_face = ABOVE;
  97:                     break;
  98:                   case ABOVE:
  99:                     bp->b_face = RIGHT;
 100:                     break;
 101:                   case BELOW:
 102:                     bp->b_face = LEFTS;
 103:                     break;
 104:                 }
 105:                 Maze[y][x] = WALL5;
 106: # ifdef MONITOR
 107:                 for (pp = Monitor; pp < End_monitor; pp++)
 108:                     check(pp, y, x);
 109: # endif MONITOR
 110:                 break;
 111:               case WALL5:
 112:                 switch (bp->b_face) {
 113:                   case LEFTS:
 114:                     bp->b_face = ABOVE;
 115:                     break;
 116:                   case RIGHT:
 117:                     bp->b_face = BELOW;
 118:                     break;
 119:                   case ABOVE:
 120:                     bp->b_face = LEFTS;
 121:                     break;
 122:                   case BELOW:
 123:                     bp->b_face = RIGHT;
 124:                     break;
 125:                 }
 126:                 Maze[y][x] = WALL4;
 127: # ifdef MONITOR
 128:                 for (pp = Monitor; pp < End_monitor; pp++)
 129:                     check(pp, y, x);
 130: # endif MONITOR
 131:                 break;
 132: # endif REFLECT
 133: # ifdef RANDOM
 134:               case DOOR:
 135:                 switch (rand_num(4)) {
 136:                   case 0:
 137:                     bp->b_face = ABOVE;
 138:                     break;
 139:                   case 1:
 140:                     bp->b_face = BELOW;
 141:                     break;
 142:                   case 2:
 143:                     bp->b_face = LEFTS;
 144:                     break;
 145:                   case 3:
 146:                     bp->b_face = RIGHT;
 147:                     break;
 148:                 }
 149:                 break;
 150: # endif RANDOM
 151:               case LEFTS:
 152:               case RIGHT:
 153:               case BELOW:
 154:               case ABOVE:
 155: # ifdef FLY
 156:               case FLYER:
 157: # endif FLY
 158:                 /*
 159: 				 * give the person a chance to catch a
 160: 				 * grenade if s/he is facing it
 161: 				 */
 162:                 if (rand_num(100) < 10
 163:                     && opposite(bp->b_face, Maze[y][x])) {
 164:                     if (bp->b_owner != NULL)
 165:                         message(bp->b_owner,
 166:                         "Your charge was absorbed!");
 167:                     pp = play_at(y, x);
 168:                     pp->p_ammo += bp->b_charge;
 169:                     (void) sprintf(Buf,
 170:                         "Absorbed charge (good shield!)");
 171:                     message(pp, Buf);
 172:                     free((char *) bp);
 173:                     (void) sprintf(Buf, "%3d", pp->p_ammo);
 174:                     cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
 175:                     outstr(pp, Buf, 3);
 176:                     goto next_bullet;
 177:                 }
 178:                 /* FALLTHROUGH */
 179: # ifndef RANDOM
 180:               case DOOR:
 181: # endif RANDOM
 182:               case WALL1:
 183:               case WALL2:
 184:               case WALL3:
 185:                 bp->b_expl = TRUE;
 186:                 break;
 187:             }
 188: 
 189:             bp->b_x = x;
 190:             bp->b_y = y;
 191:         }
 192: 
 193:         bp->b_next = Bullets;
 194:         Bullets = bp;
 195: next_bullet:
 196:         ;
 197:     }
 198: 
 199:     blist = Bullets;
 200:     Bullets = NULL;
 201:     for (bp = blist; bp != NULL; bp = next) {
 202:         next = bp->b_next;
 203:         if (!bp->b_expl) {
 204:             save_bullet(bp);
 205: # ifdef MONITOR
 206:             for (pp = Monitor; pp < End_monitor; pp++)
 207:                 check(pp, bp->b_y, bp->b_x);
 208: # endif MONITOR
 209:             continue;
 210:         }
 211: 
 212:         chkshot(bp);
 213:         free((char *) bp);
 214:     }
 215:     for (pp = Player; pp < End_player; pp++)
 216:         Maze[pp->p_y][pp->p_x] = pp->p_face;
 217: ret:
 218:     for (pp = Player; pp < End_player; pp++) {
 219: # ifdef FLY
 220:         if (pp->p_flying >= 0) {
 221:             Maze[pp->p_y][pp->p_x] = pp->p_over;
 222:             x = pp->p_x + pp->p_flyx;
 223:             y = pp->p_y + pp->p_flyy;
 224:             if (x < 1) {
 225:                 x = 1 - x;
 226:                 pp->p_flyx = -pp->p_flyx;
 227:             }
 228:             else if (x > WIDTH - 2) {
 229:                 x = (WIDTH - 2) - (x - (WIDTH - 2));
 230:                 pp->p_flyx = -pp->p_flyx;
 231:             }
 232:             if (y < 1) {
 233:                 y = 1 - y;
 234:                 pp->p_flyy = -pp->p_flyy;
 235:             }
 236:             else if (y > HEIGHT - 2) {
 237:                 y = (HEIGHT - 2) - (y - (HEIGHT - 2));
 238:                 pp->p_flyy = -pp->p_flyy;
 239:             }
 240: again:          switch (Maze[y][x]) {
 241:               case LEFTS:
 242:               case RIGHT:
 243:               case ABOVE:
 244:               case BELOW:
 245:               case FLYER:
 246:                 switch (rand_num(4)) {
 247:                   case 0:
 248:                     PLUS_DELTA(x, WIDTH - 2);
 249:                     break;
 250:                   case 1:
 251:                     MINUS_DELTA(x, 1);
 252:                     break;
 253:                   case 2:
 254:                     PLUS_DELTA(y, HEIGHT - 2);
 255:                     break;
 256:                   case 3:
 257:                     MINUS_DELTA(y, 1);
 258:                     break;
 259:                 }
 260:                 goto again;
 261:               case WALL1:
 262:               case WALL2:
 263:               case WALL3:
 264: # ifdef REFLECT
 265:               case WALL4:
 266:               case WALL5:
 267: # endif REFLECT
 268: # ifdef RANDOM
 269:               case DOOR:
 270: # endif	RANDOM
 271:                 if (pp->p_flying == 0)
 272:                     pp->p_flying++;
 273:                 break;
 274:               case MINE:
 275:                 checkdam(pp, NULL, NULL, MINDAM, MINE);
 276:                 Maze[y][x] = SPACE;
 277:                 break;
 278:               case GMINE:
 279:                 checkdam(pp, NULL, NULL, MINDAM, GMINE);
 280:                 checkdam(pp, NULL, NULL, MINDAM, GMINE);
 281:                 Maze[y][x] = SPACE;
 282:                 break;
 283:             }
 284:             pp->p_y = y;
 285:             pp->p_x = x;
 286:             pp->p_over = Maze[y][x];
 287:             if (pp->p_flying-- == 0) {
 288:                 checkdam(pp, NULL, NULL,
 289:                     rand_num(pp->p_damage / 5), FALL);
 290:                 rand_face(pp);
 291:                 showstat(pp);
 292:             }
 293:             Maze[y][x] = pp->p_face;
 294:             showexpl(y, x, pp->p_face);
 295:         }
 296: # endif FLY
 297:         sendcom(pp, REFRESH);   /* Flush out the explosions */
 298:         look(pp);
 299:         sendcom(pp, REFRESH);
 300:     }
 301: # ifdef MONITOR
 302:     for (pp = Monitor; pp < End_monitor; pp++)
 303:         sendcom(pp, REFRESH);
 304: # endif MONITOR
 305: 
 306: # ifdef CONSTANT_MOVE
 307:     if (Bullets != NULL) {
 308:         bul_alarm(1);
 309:         return;
 310:     }
 311:     for (i = 0; i < EXPLEN; i++)
 312:         if (Expl[i] != NULL) {
 313:             bul_alarm(1);
 314:             return;
 315:         }
 316:     bul_alarm(0);
 317: # endif CONSTANT_MOVE
 318: 
 319:     return;
 320: }
 321: 
 322: save_bullet(bp)
 323: register BULLET *bp;
 324: {
 325:     bp->b_over = Maze[bp->b_y][bp->b_x];
 326:     switch (bp->b_over) {
 327:       case SHOT:
 328:       case GRENADE:
 329:       case SATCHEL:
 330:       case BOMB:
 331: # ifdef OOZE
 332:       case SLIME:
 333: # ifdef VOLCANO
 334:       case LAVA:
 335: # endif VOLCANO
 336: # endif OOZE
 337:         find_under(Bullets, bp);
 338:         break;
 339:     }
 340: 
 341:     switch (bp->b_over) {
 342:       case LEFTS:
 343:       case RIGHT:
 344:       case ABOVE:
 345:       case BELOW:
 346: # ifdef FLY
 347:       case FLYER:
 348: # endif FLY
 349:         mark_player(bp);
 350:         break;
 351: 
 352:       default:
 353:         Maze[bp->b_y][bp->b_x] = bp->b_type;
 354:         break;
 355:     }
 356: 
 357:     bp->b_next = Bullets;
 358:     Bullets = bp;
 359: }
 360: 
 361: /*
 362:  * chkshot
 363:  *	Handle explosions
 364:  */
 365: chkshot(bp)
 366: register BULLET *bp;
 367: {
 368:     register int    y, x;
 369:     register int    dy, dx, absdy;
 370:     register int    delta, damage;
 371:     register char   expl;
 372:     register PLAYER *pp;
 373: 
 374:     switch (bp->b_type) {
 375:       case SHOT:
 376:       case MINE:
 377:         delta = 0;
 378:         break;
 379:       case GRENADE:
 380:       case GMINE:
 381:         delta = 1;
 382:         break;
 383:       case SATCHEL:
 384:         delta = 2;
 385:         break;
 386:       case BOMB:
 387:         delta = 3;
 388:         break;
 389: # ifdef OOZE
 390:       case SLIME:
 391: # ifdef VOLCANO
 392:       case LAVA:
 393: # endif VOLCANO
 394:         chkslime(bp);
 395:         return;
 396: # endif	OOZE
 397:     }
 398:     for (y = bp->b_y - delta; y <= bp->b_y + delta; y++) {
 399:         if (y < 0 || y >= HEIGHT)
 400:             continue;
 401:         dy = y - bp->b_y;
 402:         absdy = (dy < 0) ? -dy : dy;
 403:         for (x = bp->b_x - delta; x <= bp->b_x + delta; x++) {
 404:             if (x < 0 || x >= WIDTH)
 405:                 continue;
 406:             dx = x - bp->b_x;
 407:             if (dx == 0)
 408:                 expl = (dy == 0) ? '*' : '|';
 409:             else if (dy == 0)
 410:                 expl = '-';
 411:             else if (dx == dy)
 412:                 expl = '\\';
 413:             else if (dx == -dy)
 414:                 expl = '/';
 415:             else
 416:                 expl = '*';
 417:             showexpl(y, x, expl);
 418:             switch (Maze[y][x]) {
 419:               case LEFTS:
 420:               case RIGHT:
 421:               case ABOVE:
 422:               case BELOW:
 423: # ifdef FLY
 424:               case FLYER:
 425: # endif FLY
 426:                 if (dx < 0)
 427:                     dx = -dx;
 428:                 if (absdy > dx)
 429:                     damage = delta - absdy + 1;
 430:                 else
 431:                     damage = delta - dx + 1;
 432:                 pp = play_at(y, x);
 433:                 while (damage-- > 0)
 434:                     checkdam(pp, bp->b_owner, bp->b_score,
 435:                         MINDAM, bp->b_type);
 436:                 break;
 437:               case GMINE:
 438:               case MINE:
 439:                 add_shot((Maze[y][x] == GMINE) ?
 440:                     GRENADE : SHOT,
 441:                     y, x, LEFTS,
 442:                     (Maze[y][x] == GMINE) ?
 443:                     GRENREQ : BULREQ,
 444:                     (PLAYER *) NULL, TRUE, SPACE);
 445:                 Maze[y][x] = SPACE;
 446:                 break;
 447:             }
 448:         }
 449:     }
 450: }
 451: 
 452: # ifdef OOZE
 453: /*
 454:  * chkslime:
 455:  *	handle slime shot exploding
 456:  */
 457: chkslime(bp)
 458: register BULLET *bp;
 459: {
 460:     register BULLET *nbp;
 461: 
 462:     switch (Maze[bp->b_y][bp->b_x]) {
 463:       case WALL1:
 464:       case WALL2:
 465:       case WALL3:
 466: # ifdef REFLECT
 467:       case WALL4:
 468:       case WALL5:
 469: # endif REFLECT
 470: # ifdef RANDOM
 471:       case DOOR:
 472: # endif	RANDOM
 473:         switch (bp->b_face) {
 474:           case LEFTS:
 475:             bp->b_x++;
 476:             break;
 477:           case RIGHT:
 478:             bp->b_x--;
 479:             break;
 480:           case ABOVE:
 481:             bp->b_y++;
 482:             break;
 483:           case BELOW:
 484:             bp->b_y--;
 485:             break;
 486:         }
 487:         break;
 488:     }
 489:     nbp = (BULLET *) malloc(sizeof (BULLET));
 490:     *nbp = *bp;
 491: # ifdef VOLCANO
 492:     moveslime(nbp, nbp->b_type == SLIME ? SLIMESPEED : LAVASPEED);
 493: # else VOLCANO
 494:     moveslime(nbp, SLIMESPEED);
 495: # endif VOLCANO
 496: }
 497: 
 498: /*
 499:  * moveslime:
 500:  *	move the given slime shot speed times and add it back if
 501:  *	it hasn't fizzled yet
 502:  */
 503: moveslime(bp, speed)
 504: register BULLET *bp;
 505: register int    speed;
 506: {
 507:     register int    i, j, dirmask, count;
 508:     register PLAYER *pp;
 509:     register BULLET *nbp;
 510: 
 511:     if (speed == 0) {
 512:         if (bp->b_charge <= 0)
 513:             free((char *) bp);
 514:         else
 515:             save_bullet(bp);
 516:         return;
 517:     }
 518: 
 519: # ifdef VOLCANO
 520:     showexpl(bp->b_y, bp->b_x, bp->b_type == LAVA ? LAVA : '*');
 521: # else VOLCANO
 522:     showexpl(bp->b_y, bp->b_x, '*');
 523: # endif VOLCANO
 524:     switch (Maze[bp->b_y][bp->b_x]) {
 525:       case LEFTS:
 526:       case RIGHT:
 527:       case ABOVE:
 528:       case BELOW:
 529: # ifdef FLY
 530:       case FLYER:
 531: # endif FLY
 532:         pp = play_at(bp->b_y, bp->b_x);
 533:         message(pp, "You've been slimed.");
 534:         checkdam(pp, bp->b_owner, bp->b_score, MINDAM, bp->b_type);
 535:         break;
 536:     }
 537: 
 538:     if (--bp->b_charge <= 0) {
 539:         free((char *) bp);
 540:         return;
 541:     }
 542: 
 543:     dirmask = 0;
 544:     count = 0;
 545:     switch (bp->b_face) {
 546:       case LEFTS:
 547:         if (!iswall(bp->b_y, bp->b_x - 1))
 548:             dirmask |= WEST, count++;
 549:         if (!iswall(bp->b_y - 1, bp->b_x))
 550:             dirmask |= NORTH, count++;
 551:         if (!iswall(bp->b_y + 1, bp->b_x))
 552:             dirmask |= SOUTH, count++;
 553:         if (dirmask == 0)
 554:             if (!iswall(bp->b_y, bp->b_x + 1))
 555:                 dirmask |= EAST, count++;
 556:         break;
 557:       case RIGHT:
 558:         if (!iswall(bp->b_y, bp->b_x + 1))
 559:             dirmask |= EAST, count++;
 560:         if (!iswall(bp->b_y - 1, bp->b_x))
 561:             dirmask |= NORTH, count++;
 562:         if (!iswall(bp->b_y + 1, bp->b_x))
 563:             dirmask |= SOUTH, count++;
 564:         if (dirmask == 0)
 565:             if (!iswall(bp->b_y, bp->b_x - 1))
 566:                 dirmask |= WEST, count++;
 567:         break;
 568:       case ABOVE:
 569:         if (!iswall(bp->b_y - 1, bp->b_x))
 570:             dirmask |= NORTH, count++;
 571:         if (!iswall(bp->b_y, bp->b_x - 1))
 572:             dirmask |= WEST, count++;
 573:         if (!iswall(bp->b_y, bp->b_x + 1))
 574:             dirmask |= EAST, count++;
 575:         if (dirmask == 0)
 576:             if (!iswall(bp->b_y + 1, bp->b_x))
 577:                 dirmask |= SOUTH, count++;
 578:         break;
 579:       case BELOW:
 580:         if (!iswall(bp->b_y + 1, bp->b_x))
 581:             dirmask |= SOUTH, count++;
 582:         if (!iswall(bp->b_y, bp->b_x - 1))
 583:             dirmask |= WEST, count++;
 584:         if (!iswall(bp->b_y, bp->b_x + 1))
 585:             dirmask |= EAST, count++;
 586:         if (dirmask == 0)
 587:             if (!iswall(bp->b_y - 1, bp->b_x))
 588:                 dirmask |= NORTH, count++;
 589:         break;
 590:     }
 591:     if (count == 0) {
 592:         /*
 593: 		 * No place to go.  Just sit here for a while and wait
 594: 		 * for adjacent squares to clear out.
 595: 		 */
 596:         save_bullet(bp);
 597:         return;
 598:     }
 599:     if (bp->b_charge < count) {
 600:         /* Only bp->b_charge paths may be taken */
 601:         while (count > bp->b_charge) {
 602:             if (dirmask & WEST)
 603:                 dirmask &= ~WEST;
 604:             else if (dirmask & EAST)
 605:                 dirmask &= ~EAST;
 606:             else if (dirmask & NORTH)
 607:                 dirmask &= ~NORTH;
 608:             else if (dirmask & SOUTH)
 609:                 dirmask &= ~SOUTH;
 610:             count--;
 611:         }
 612:     }
 613: 
 614:     i = bp->b_charge / count;
 615:     j = bp->b_charge % count;
 616:     if (dirmask & WEST) {
 617:         count--;
 618:         nbp = create_shot(bp->b_type, bp->b_y, bp->b_x - 1, LEFTS,
 619:             i, bp->b_owner, bp->b_score, TRUE, SPACE);
 620:         moveslime(nbp, speed - 1);
 621:     }
 622:     if (dirmask & EAST) {
 623:         count--;
 624:         nbp = create_shot(bp->b_type, bp->b_y, bp->b_x + 1, RIGHT,
 625:             (count < j) ? i + 1 : i, bp->b_owner, bp->b_score,
 626:             TRUE, SPACE);
 627:         moveslime(nbp, speed - 1);
 628:     }
 629:     if (dirmask & NORTH) {
 630:         count--;
 631:         nbp = create_shot(bp->b_type, bp->b_y - 1, bp->b_x, ABOVE,
 632:             (count < j) ? i + 1 : i, bp->b_owner, bp->b_score,
 633:             TRUE, SPACE);
 634:         moveslime(nbp, speed - 1);
 635:     }
 636:     if (dirmask & SOUTH) {
 637:         count--;
 638:         nbp = create_shot(bp->b_type, bp->b_y + 1, bp->b_x, BELOW,
 639:             (count < j) ? i + 1 : i, bp->b_owner, bp->b_score,
 640:             TRUE, SPACE);
 641:         moveslime(nbp, speed - 1);
 642:     }
 643: 
 644:     free((char *) bp);
 645: }
 646: 
 647: /*
 648:  * iswall:
 649:  *	returns whether the given location is a wall
 650:  */
 651: iswall(y, x)
 652: register int    y, x;
 653: {
 654:     if (y < 0 || x < 0 || y >= HEIGHT || x >= WIDTH)
 655:         return TRUE;
 656:     switch (Maze[y][x]) {
 657:       case WALL1:
 658:       case WALL2:
 659:       case WALL3:
 660: # ifdef REFLECT
 661:       case WALL4:
 662:       case WALL5:
 663: # endif	REFLECT
 664: # ifdef RANDOM
 665:       case DOOR:
 666: # endif	RANDOM
 667: # ifdef VOLCANO
 668:       case LAVA:
 669: # endif VOLCANO
 670:         return TRUE;
 671:     }
 672:     return FALSE;
 673: }
 674: # endif	OOZE
 675: 
 676: /*
 677:  * zapshot:
 678:  *	Take a shot out of the air.
 679:  */
 680: zapshot(blist, obp)
 681: register BULLET *blist, *obp;
 682: {
 683:     register BULLET *bp;
 684:     register FLAG   explode;
 685: 
 686:     explode = FALSE;
 687:     for (bp = blist; bp != NULL; bp = bp->b_next) {
 688:         if (bp->b_x != obp->b_x || bp->b_y != obp->b_y)
 689:             continue;
 690:         if (bp->b_face == obp->b_face)
 691:             continue;
 692:         explode = TRUE;
 693:         break;
 694:     }
 695:     if (!explode)
 696:         return;
 697:     explshot(blist, obp->b_y, obp->b_x);
 698: }
 699: 
 700: /*
 701:  * explshot -
 702:  *	Make all shots at this location blow up
 703:  */
 704: explshot(blist, y, x)
 705: register BULLET *blist;
 706: register int    y, x;
 707: {
 708:     register BULLET *bp;
 709: 
 710:     for (bp = blist; bp != NULL; bp = bp->b_next)
 711:         if (bp->b_x == x && bp->b_y == y) {
 712:             bp->b_expl = TRUE;
 713:             if (bp->b_owner != NULL)
 714:                 message(bp->b_owner, "Shot intercepted");
 715:         }
 716: }
 717: 
 718: /*
 719:  * play_at:
 720:  *	Return a pointer to the player at the given location
 721:  */
 722: PLAYER *
 723: play_at(y, x)
 724: register int    y, x;
 725: {
 726:     register PLAYER *pp;
 727: 
 728:     for (pp = Player; pp < End_player; pp++)
 729:         if (pp->p_x == x && pp->p_y == y)
 730:             return pp;
 731:     fprintf(stderr, "driver: couldn't find player at (%d,%d)\n", x, y);
 732:     abort();
 733:     /* NOTREACHED */
 734: }
 735: 
 736: /*
 737:  * opposite:
 738:  *	Return TRUE if the bullet direction faces the opposite direction
 739:  *	of the player in the maze
 740:  */
 741: opposite(face, dir)
 742: int face;
 743: char    dir;
 744: {
 745:     switch (face) {
 746:       case LEFTS:
 747:         return (dir == RIGHT);
 748:       case RIGHT:
 749:         return (dir == LEFTS);
 750:       case ABOVE:
 751:         return (dir == BELOW);
 752:       case BELOW:
 753:         return (dir == ABOVE);
 754:       default:
 755:         return FALSE;
 756:     }
 757: }
 758: 
 759: /*
 760:  * is_bullet:
 761:  *	Is there a bullet at the given coordinates?  If so, return
 762:  *	a pointer to the bullet, otherwise return NULL
 763:  */
 764: BULLET *
 765: is_bullet(y, x)
 766: register int    y, x;
 767: {
 768:     register BULLET *bp;
 769: 
 770:     for (bp = Bullets; bp != NULL; bp = bp->b_next)
 771:         if (bp->b_y == y && bp->b_x == x)
 772:             return bp;
 773:     return NULL;
 774: }
 775: 
 776: /*
 777:  * fixshots:
 778:  *	change the underlying character of the shots at a location
 779:  *	to the given character.
 780:  */
 781: fixshots(y, x, over)
 782: register int    y, x;
 783: char        over;
 784: {
 785:     register BULLET *bp;
 786: 
 787:     for (bp = Bullets; bp != NULL; bp = bp->b_next)
 788:         if (bp->b_y == y && bp->b_x == x)
 789:             bp->b_over = over;
 790: }
 791: 
 792: /*
 793:  * find_under:
 794:  *	find the underlying character for a bullet when it lands
 795:  *	on another bullet.
 796:  */
 797: find_under(blist, bp)
 798: register BULLET *blist, *bp;
 799: {
 800:     register BULLET *nbp;
 801: 
 802:     for (nbp = blist; nbp != NULL; nbp = nbp->b_next)
 803:         if (bp->b_y == nbp->b_y && bp->b_x == nbp->b_x) {
 804:             bp->b_over = nbp->b_over;
 805:             break;
 806:         }
 807: }
 808: 
 809: /*
 810:  * mark_player:
 811:  *	mark a player as under a shot
 812:  */
 813: mark_player(bp)
 814: register BULLET *bp;
 815: {
 816:     register PLAYER *pp;
 817: 
 818:     for (pp = Player; pp < End_player; pp++)
 819:         if (pp->p_y == bp->b_y && pp->p_x == bp->b_x) {
 820:             pp->p_undershot = TRUE;
 821:             break;
 822:         }
 823: }

Defined functions

chkshot defined in line 365; used 1 times
chkslime defined in line 457; used 1 times
explshot defined in line 704; used 1 times
find_under defined in line 797; used 1 times
fixshots defined in line 781; used 1 times
is_bullet defined in line 764; used 2 times
iswall defined in line 651; used 16 times
mark_player defined in line 813; used 1 times
moveshots defined in line 21; used 2 times
moveslime defined in line 503; used 6 times
opposite defined in line 741; used 2 times
play_at defined in line 722; used 6 times
save_bullet defined in line 322; used 3 times
zapshot defined in line 680; used 4 times

Defined macros

MINUS_DELTA defined in line 15; used 2 times
PLUS_DELTA defined in line 14; used 2 times
Last modified: 1986-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4366
Valid CSS Valid XHTML 1.0 Strict