📄 shots.c
字号:
case 1: MINUS_DELTA(x, 1); break; case 2: PLUS_DELTA(y, HEIGHT - 2); break; case 3: MINUS_DELTA(y, 1); break; } goto again; case WALL1: case WALL2: case WALL3:# ifdef REFLECT case WALL4: case WALL5:# endif# ifdef RANDOM case DOOR:# endif if (pp->p_flying == 0) pp->p_flying++; break; case SPACE: break; } pp->p_y = y; pp->p_x = x; if (pp->p_flying-- == 0) {# ifdef BOOTS if (pp->p_face != BOOT && pp->p_face != BOOT_PAIR) {# endif checkdam(pp, (PLAYER *) NULL, (IDENT *) NULL, rand_num(pp->p_damage / 5), FALL); pp->p_face = rand_dir(); showstat(pp);# ifdef BOOTS } else { if (Maze[y][x] == BOOT) pp->p_face = BOOT_PAIR; Maze[y][x] = SPACE; }# endif } pp->p_over = Maze[y][x]; Maze[y][x] = pp->p_face; showexpl(y, x, pp->p_face);}/* * chkshot * Handle explosions */chkshot(bp, next)register BULLET *bp;BULLET *next;{ register int y, x; register int dy, dx, absdy; register int delta, damage; register char expl; register PLAYER *pp; switch (bp->b_type) { case SHOT: case MINE: case GRENADE: case GMINE: case SATCHEL: case BOMB: delta = bp->b_size - 1; break;# ifdef OOZE case SLIME:# ifdef VOLCANO case LAVA:# endif chkslime(bp, next); return;# endif# ifdef DRONE case DSHOT: bp->b_type = SLIME; chkslime(bp, next); return;# endif } for (y = bp->b_y - delta; y <= bp->b_y + delta; y++) { if (y < 0 || y >= HEIGHT) continue; dy = y - bp->b_y; absdy = (dy < 0) ? -dy : dy; for (x = bp->b_x - delta; x <= bp->b_x + delta; x++) { if (x < 0 || x >= WIDTH) continue; dx = x - bp->b_x; if (dx == 0) expl = (dy == 0) ? '*' : '|'; else if (dy == 0) expl = '-'; else if (dx == dy) expl = '\\'; else if (dx == -dy) expl = '/'; else expl = '*'; showexpl(y, x, expl); switch (Maze[y][x]) { case LEFTS: case RIGHT: case ABOVE: case BELOW:# ifdef FLY case FLYER:# endif if (dx < 0) dx = -dx; if (absdy > dx) damage = bp->b_size - absdy; else damage = bp->b_size - dx; pp = play_at(y, x); checkdam(pp, bp->b_owner, bp->b_score, damage * MINDAM, bp->b_type); break; case GMINE: case MINE: add_shot((Maze[y][x] == GMINE) ? GRENADE : SHOT, y, x, LEFTS, (Maze[y][x] == GMINE) ? GRENREQ : BULREQ, (PLAYER *) NULL, TRUE, SPACE); Maze[y][x] = SPACE; break; } } }}# ifdef OOZE/* * chkslime: * handle slime shot exploding */chkslime(bp, next)register BULLET *bp;BULLET *next;{ register BULLET *nbp; switch (Maze[bp->b_y][bp->b_x]) { case WALL1: case WALL2: case WALL3:# ifdef REFLECT case WALL4: case WALL5:# endif# ifdef RANDOM case DOOR:# endif switch (bp->b_face) { case LEFTS: bp->b_x++; break; case RIGHT: bp->b_x--; break; case ABOVE: bp->b_y++; break; case BELOW: bp->b_y--; break; } break; } nbp = (BULLET *) malloc(sizeof (BULLET)); *nbp = *bp;# ifdef VOLCANO move_slime(nbp, nbp->b_type == SLIME ? SLIMESPEED : LAVASPEED, next);# else move_slime(nbp, SLIMESPEED, next);# endif}/* * move_slime: * move the given slime shot speed times and add it back if * it hasn't fizzled yet */move_slime(bp, speed, next)register BULLET *bp;register int speed;BULLET *next;{ register int i, j, dirmask, count; register PLAYER *pp; register BULLET *nbp; if (speed == 0) { if (bp->b_charge <= 0) free((char *) bp); else save_bullet(bp); return; }# ifdef VOLCANO showexpl(bp->b_y, bp->b_x, bp->b_type == LAVA ? LAVA : '*');# else showexpl(bp->b_y, bp->b_x, '*');# endif switch (Maze[bp->b_y][bp->b_x]) { case LEFTS: case RIGHT: case ABOVE: case BELOW:# ifdef FLY case FLYER:# endif pp = play_at(bp->b_y, bp->b_x); message(pp, "You've been slimed."); checkdam(pp, bp->b_owner, bp->b_score, MINDAM, bp->b_type); break; case SHOT: case GRENADE: case SATCHEL: case BOMB:# ifdef DRONE case DSHOT:# endif explshot(next, bp->b_y, bp->b_x); explshot(Bullets, bp->b_y, bp->b_x); break; } if (--bp->b_charge <= 0) { free((char *) bp); return; } dirmask = 0; count = 0; switch (bp->b_face) { case LEFTS: if (!iswall(bp->b_y, bp->b_x - 1)) dirmask |= WEST, count++; if (!iswall(bp->b_y - 1, bp->b_x)) dirmask |= NORTH, count++; if (!iswall(bp->b_y + 1, bp->b_x)) dirmask |= SOUTH, count++; if (dirmask == 0) if (!iswall(bp->b_y, bp->b_x + 1)) dirmask |= EAST, count++; break; case RIGHT: if (!iswall(bp->b_y, bp->b_x + 1)) dirmask |= EAST, count++; if (!iswall(bp->b_y - 1, bp->b_x)) dirmask |= NORTH, count++; if (!iswall(bp->b_y + 1, bp->b_x)) dirmask |= SOUTH, count++; if (dirmask == 0) if (!iswall(bp->b_y, bp->b_x - 1)) dirmask |= WEST, count++; break; case ABOVE: if (!iswall(bp->b_y - 1, bp->b_x)) dirmask |= NORTH, count++; if (!iswall(bp->b_y, bp->b_x - 1)) dirmask |= WEST, count++; if (!iswall(bp->b_y, bp->b_x + 1)) dirmask |= EAST, count++; if (dirmask == 0) if (!iswall(bp->b_y + 1, bp->b_x)) dirmask |= SOUTH, count++; break; case BELOW: if (!iswall(bp->b_y + 1, bp->b_x)) dirmask |= SOUTH, count++; if (!iswall(bp->b_y, bp->b_x - 1)) dirmask |= WEST, count++; if (!iswall(bp->b_y, bp->b_x + 1)) dirmask |= EAST, count++; if (dirmask == 0) if (!iswall(bp->b_y - 1, bp->b_x)) dirmask |= NORTH, count++; break; } if (count == 0) { /* * No place to go. Just sit here for a while and wait * for adjacent squares to clear out. */ save_bullet(bp); return; } if (bp->b_charge < count) { /* Only bp->b_charge paths may be taken */ while (count > bp->b_charge) { if (dirmask & WEST) dirmask &= ~WEST; else if (dirmask & EAST) dirmask &= ~EAST; else if (dirmask & NORTH) dirmask &= ~NORTH; else if (dirmask & SOUTH) dirmask &= ~SOUTH; count--; } } i = bp->b_charge / count; j = bp->b_charge % count; if (dirmask & WEST) { count--; nbp = create_shot(bp->b_type, bp->b_y, bp->b_x - 1, LEFTS, i, bp->b_size, bp->b_owner, bp->b_score, TRUE, SPACE); move_slime(nbp, speed - 1, next); } if (dirmask & EAST) { count--; nbp = create_shot(bp->b_type, bp->b_y, bp->b_x + 1, RIGHT, (count < j) ? i + 1 : i, bp->b_size, bp->b_owner, bp->b_score, TRUE, SPACE); move_slime(nbp, speed - 1, next); } if (dirmask & NORTH) { count--; nbp = create_shot(bp->b_type, bp->b_y - 1, bp->b_x, ABOVE, (count < j) ? i + 1 : i, bp->b_size, bp->b_owner, bp->b_score, TRUE, SPACE); move_slime(nbp, speed - 1, next); } if (dirmask & SOUTH) { count--; nbp = create_shot(bp->b_type, bp->b_y + 1, bp->b_x, BELOW, (count < j) ? i + 1 : i, bp->b_size, bp->b_owner, bp->b_score, TRUE, SPACE); move_slime(nbp, speed - 1, next); } free((char *) bp);}/* * iswall: * returns whether the given location is a wall */iswall(y, x)register int y, x;{ if (y < 0 || x < 0 || y >= HEIGHT || x >= WIDTH) return TRUE; switch (Maze[y][x]) { case WALL1: case WALL2: case WALL3:# ifdef REFLECT case WALL4: case WALL5:# endif# ifdef RANDOM case DOOR:# endif# ifdef OOZE case SLIME:# ifdef VOLCANO case LAVA:# endif# endif return TRUE; } return FALSE;}# endif/* * zapshot: * Take a shot out of the air. */zapshot(blist, obp)register BULLET *blist, *obp;{ register BULLET *bp; register FLAG explode; explode = FALSE; for (bp = blist; bp != NULL; bp = bp->b_next) { if (bp->b_x != obp->b_x || bp->b_y != obp->b_y) continue; if (bp->b_face == obp->b_face) continue; explode = TRUE; break; } if (!explode) return; explshot(blist, obp->b_y, obp->b_x);}/* * explshot - * Make all shots at this location blow up */explshot(blist, y, x)register BULLET *blist;register int y, x;{ register BULLET *bp; for (bp = blist; bp != NULL; bp = bp->b_next) if (bp->b_x == x && bp->b_y == y) { bp->b_expl = TRUE; if (bp->b_owner != NULL) message(bp->b_owner, "Shot intercepted"); }}/* * play_at: * Return a pointer to the player at the given location */PLAYER *play_at(y, x)register int y, x;{ register PLAYER *pp; for (pp = Player; pp < End_player; pp++) if (pp->p_x == x && pp->p_y == y) return pp; fprintf(stderr, "driver: couldn't find player at (%d,%d)\n", x, y); abort(); /* NOTREACHED */}/* * opposite: * Return TRUE if the bullet direction faces the opposite direction * of the player in the maze */opposite(face, dir)int face;char dir;{ switch (face) { case LEFTS: return (dir == RIGHT); case RIGHT: return (dir == LEFTS); case ABOVE: return (dir == BELOW); case BELOW: return (dir == ABOVE); default: return FALSE; }}/* * is_bullet: * Is there a bullet at the given coordinates? If so, return * a pointer to the bullet, otherwise return NULL */BULLET *is_bullet(y, x)register int y, x;{ register BULLET *bp; for (bp = Bullets; bp != NULL; bp = bp->b_next) if (bp->b_y == y && bp->b_x == x) return bp; return NULL;}/* * fixshots: * change the underlying character of the shots at a location * to the given character. */fixshots(y, x, over)register int y, x;char over;{ register BULLET *bp; for (bp = Bullets; bp != NULL; bp = bp->b_next) if (bp->b_y == y && bp->b_x == x) bp->b_over = over;}/* * find_under: * find the underlying character for a bullet when it lands * on another bullet. */find_under(blist, bp)register BULLET *blist, *bp;{ register BULLET *nbp; for (nbp = blist; nbp != NULL; nbp = nbp->b_next) if (bp->b_y == nbp->b_y && bp->b_x == nbp->b_x) { bp->b_over = nbp->b_over; break; }}/* * mark_player: * mark a player as under a shot */mark_player(bp)register BULLET *bp;{ register PLAYER *pp; for (pp = Player; pp < End_player; pp++) if (pp->p_y == bp->b_y && pp->p_x == bp->b_x) { pp->p_undershot = TRUE; break; }}# ifdef BOOTS/* * mark_boot: * mark a boot as under a shot */mark_boot(bp)register BULLET *bp;{ register PLAYER *pp; for (pp = Boot; pp < &Boot[NBOOTS]; pp++) if (pp->p_y == bp->b_y && pp->p_x == bp->b_x) { pp->p_undershot = TRUE; break; }}# endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -