📄 shots.c
字号:
/* * Hunt * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold * San Francisco, California */# include "hunt.h"# include <signal.h># define PLUS_DELTA(x, max) if (x < max) x++; else x--# define MINUS_DELTA(x, min) if (x > min) x--; else x++/* * moveshots: * Move the shots already in the air, taking explosions into account */moveshots(){ register BULLET *bp, *next; register PLAYER *pp; register int x, y; register BULLET *blist; rollexpl(); if (Bullets == NULL) goto ret; /* * First we move through the bullet list BULSPD times, looking * for things we may have run into. If we do run into * something, we set up the explosion and disappear, checking * for damage to any player who got in the way. */ blist = Bullets; Bullets = NULL; for (bp = blist; bp != NULL; bp = next) { next = bp->b_next; x = bp->b_x; y = bp->b_y; Maze[y][x] = bp->b_over; for (pp = Player; pp < End_player; pp++) check(pp, y, x);# ifdef MONITOR for (pp = Monitor; pp < End_monitor; pp++) check(pp, y, x);# endif switch (bp->b_type) { case SHOT: case GRENADE: case SATCHEL: case BOMB: if (move_normal_shot(bp)) { bp->b_next = Bullets; Bullets = bp; } break;# ifdef OOZE case SLIME: if (bp->b_expl || move_normal_shot(bp)) { bp->b_next = Bullets; Bullets = bp; } break;# endif# ifdef DRONE case DSHOT: if (move_drone(bp)) { bp->b_next = Bullets; Bullets = bp; } break;# endif default: bp->b_next = Bullets; Bullets = bp; break; } } blist = Bullets; Bullets = NULL; for (bp = blist; bp != NULL; bp = next) { next = bp->b_next; if (!bp->b_expl) { save_bullet(bp);# ifdef MONITOR for (pp = Monitor; pp < End_monitor; pp++) check(pp, bp->b_y, bp->b_x);# endif# ifdef DRONE if (bp->b_type == DSHOT) for (pp = Player; pp < End_player; pp++) if (pp->p_scan >= 0) check(pp, bp->b_y, bp->b_x);# endif continue; } chkshot(bp, next); free((char *) bp); } for (pp = Player; pp < End_player; pp++) Maze[pp->p_y][pp->p_x] = pp->p_face;ret:# ifdef BOOTS for (pp = Boot; pp < &Boot[NBOOTS]; pp++) if (pp->p_flying >= 0) move_flyer(pp);# endif for (pp = Player; pp < End_player; pp++) {# ifdef FLY if (pp->p_flying >= 0) move_flyer(pp);# endif sendcom(pp, REFRESH); /* Flush out the explosions */ look(pp); sendcom(pp, REFRESH); }# ifdef MONITOR for (pp = Monitor; pp < End_monitor; pp++) sendcom(pp, REFRESH);# endif return;}/* * move_normal_shot: * Move a normal shot along its trajectory */move_normal_shot(bp)register BULLET *bp;{ register int i, x, y; register PLAYER *pp; for (i = 0; i < BULSPD; i++) { if (bp->b_expl) break; x = bp->b_x; y = bp->b_y; switch (bp->b_face) { case LEFTS: x--; break; case RIGHT: x++; break; case ABOVE: y--; break; case BELOW: y++; break; } switch (Maze[y][x]) { case SHOT: if (rand_num(100) < 5) { zapshot(Bullets, bp); zapshot(bp->b_next, bp); } break; case GRENADE: if (rand_num(100) < 10) { zapshot(Bullets, bp); zapshot(bp->b_next, bp); } break;# ifdef REFLECT case WALL4: /* reflecting walls */ switch (bp->b_face) { case LEFTS: bp->b_face = BELOW; break; case RIGHT: bp->b_face = ABOVE; break; case ABOVE: bp->b_face = RIGHT; break; case BELOW: bp->b_face = LEFTS; break; } Maze[y][x] = WALL5;# ifdef MONITOR for (pp = Monitor; pp < End_monitor; pp++) check(pp, y, x);# endif break; case WALL5: switch (bp->b_face) { case LEFTS: bp->b_face = ABOVE; break; case RIGHT: bp->b_face = BELOW; break; case ABOVE: bp->b_face = LEFTS; break; case BELOW: bp->b_face = RIGHT; break; } Maze[y][x] = WALL4;# ifdef MONITOR for (pp = Monitor; pp < End_monitor; pp++) check(pp, y, x);# endif break;# endif# ifdef RANDOM case DOOR: switch (rand_num(4)) { case 0: bp->b_face = ABOVE; break; case 1: bp->b_face = BELOW; break; case 2: bp->b_face = LEFTS; break; case 3: bp->b_face = RIGHT; break; } break;# endif# ifdef FLY case FLYER: pp = play_at(y, x); message(pp, "Zing!"); break;# endif case LEFTS: case RIGHT: case BELOW: case ABOVE: /* * give the person a chance to catch a * grenade if s/he is facing it */ pp = play_at(y, x); pp->p_ident->i_shot += bp->b_charge; if (opposite(bp->b_face, Maze[y][x])) { if (rand_num(100) < 10) { if (bp->b_owner != NULL) message(bp->b_owner, "Your charge was absorbed!"); if (bp->b_score != NULL) bp->b_score->i_robbed += bp->b_charge; pp->p_ammo += bp->b_charge; if (pp->p_damage + bp->b_size * MINDAM > pp->p_damcap) pp->p_ident->i_saved++; message(pp, "Absorbed charge (good shield!)"); pp->p_ident->i_absorbed += bp->b_charge; free((char *) bp); (void) sprintf(Buf, "%3d", pp->p_ammo); cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); outstr(pp, Buf, 3); return FALSE; } pp->p_ident->i_faced += bp->b_charge; } /* * Small chance that the bullet just misses the * person. If so, the bullet just goes on its * merry way without exploding. */ if (rand_num(100) < 5) { pp->p_ident->i_ducked += bp->b_charge; if (pp->p_damage + bp->b_size * MINDAM > pp->p_damcap) pp->p_ident->i_saved++; if (bp->b_score != NULL) bp->b_score->i_missed += bp->b_charge; message(pp, "Zing!"); if (bp->b_owner == NULL) break; message(bp->b_owner, ((bp->b_score->i_missed & 0x7) == 0x7) ? "My! What a bad shot you are!" : "Missed him"); break; } /* * The shot hit that sucker! Blow it up. */ /* FALLTHROUGH */# ifndef RANDOM case DOOR:# endif case WALL1: case WALL2: case WALL3: bp->b_expl = TRUE; break; } bp->b_x = x; bp->b_y = y; } return TRUE;}# ifdef DRONE/* * move_drone: * Move the drone to the next square */move_drone(bp)register BULLET *bp;{ register int mask, count; register int n, dir; register PLAYER *pp; /* * See if we can give someone a blast */ if (isplayer(Maze[bp->b_y][bp->b_x - 1])) { dir = WEST; goto drone_move; } if (isplayer(Maze[bp->b_y - 1][bp->b_x])) { dir = NORTH; goto drone_move; } if (isplayer(Maze[bp->b_y + 1][bp->b_x])) { dir = SOUTH; goto drone_move; } if (isplayer(Maze[bp->b_y][bp->b_x + 1])) { dir = EAST; goto drone_move; } /* * Find out what directions are clear */ mask = count = 0; if (!iswall(bp->b_y, bp->b_x - 1)) mask |= WEST, count++; if (!iswall(bp->b_y - 1, bp->b_x)) mask |= NORTH, count++; if (!iswall(bp->b_y + 1, bp->b_x)) mask |= SOUTH, count++; if (!iswall(bp->b_y, bp->b_x + 1)) mask |= EAST, count++; /* * All blocked up, just you wait */ if (count == 0) return TRUE; /* * Only one way to go. */ if (count == 1) { dir = mask; goto drone_move; } /* * Get rid of the direction that we came from */ switch (bp->b_face) { case LEFTS: if (mask & EAST) mask &= ~EAST, count--; break; case RIGHT: if (mask & WEST) mask &= ~WEST, count--; break; case ABOVE: if (mask & SOUTH) mask &= ~SOUTH, count--; break; case BELOW: if (mask & NORTH) mask &= ~NORTH, count--; break; } /* * Pick one of the remaining directions */ n = rand_num(count); if (n >= 0 && mask & NORTH) dir = NORTH, n--; if (n >= 0 && mask & SOUTH) dir = SOUTH, n--; if (n >= 0 && mask & EAST) dir = EAST, n--; if (n >= 0 && mask & WEST) dir = WEST, n--; /* * Now that we know the direction of movement, * just update the position of the drone */drone_move: switch (dir) { case WEST: bp->b_x--; bp->b_face = LEFTS; break; case EAST: bp->b_x++; bp->b_face = RIGHT; break; case NORTH: bp->b_y--; bp->b_face = ABOVE; break; case SOUTH: bp->b_y++; bp->b_face = BELOW; break; } switch (Maze[bp->b_y][bp->b_x]) { case LEFTS: case RIGHT: case BELOW: case ABOVE: /* * give the person a chance to catch a * drone if s/he is facing it */ if (rand_num(100) < 1 && opposite(bp->b_face, Maze[bp->b_y][bp->b_x])) { pp = play_at(bp->b_y, bp->b_x); pp->p_ammo += bp->b_charge; message(pp, "**** Absorbed drone ****"); free((char *) bp); (void) sprintf(Buf, "%3d", pp->p_ammo); cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); outstr(pp, Buf, 3); return FALSE; } bp->b_expl = TRUE; break; } return TRUE;}# endif/* * save_bullet: * Put this bullet back onto the bullet list */save_bullet(bp)register BULLET *bp;{ bp->b_over = Maze[bp->b_y][bp->b_x]; switch (bp->b_over) { case SHOT: case GRENADE: case SATCHEL: case BOMB:# ifdef OOZE case SLIME:# ifdef VOLCANO case LAVA:# endif# endif# ifdef DRONE case DSHOT:# endif find_under(Bullets, bp); break; } switch (bp->b_over) { case LEFTS: case RIGHT: case ABOVE: case BELOW:# ifdef FLY case FLYER:# endif mark_player(bp); break;# ifdef BOOTS case BOOT: case BOOT_PAIR: mark_boot(bp);# endif default: Maze[bp->b_y][bp->b_x] = bp->b_type; break; } bp->b_next = Bullets; Bullets = bp;}/* * move_flyer: * Update the position of a player in flight */move_flyer(pp)register PLAYER *pp;{ register int x, y; if (pp->p_undershot) { fixshots(pp->p_y, pp->p_x, pp->p_over); pp->p_undershot = FALSE; } Maze[pp->p_y][pp->p_x] = pp->p_over; x = pp->p_x + pp->p_flyx; y = pp->p_y + pp->p_flyy; if (x < 1) { x = 1 - x; pp->p_flyx = -pp->p_flyx; } else if (x > WIDTH - 2) { x = (WIDTH - 2) - (x - (WIDTH - 2)); pp->p_flyx = -pp->p_flyx; } if (y < 1) { y = 1 - y; pp->p_flyy = -pp->p_flyy; } else if (y > HEIGHT - 2) { y = (HEIGHT - 2) - (y - (HEIGHT - 2)); pp->p_flyy = -pp->p_flyy; }again: switch (Maze[y][x]) { default: switch (rand_num(4)) { case 0: PLUS_DELTA(x, WIDTH - 2); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -