/* * fire_slime: * Fire a slime shot in the given direction */ static void fire_slime(PLAYER *pp, int req_index) { if (pp == NULL) return; /* Check configuration: */ if (!conf_ooze) return; /* Drop the slime type back util we can afford it: */ while (req_index >= 0 && pp->p_ammo < slime_req[req_index]) req_index--; /* Can we afford to slime at all? */ if (req_index < 0) { message(pp, "Not enough charges."); return; } /* Is the gun too hot? */ if (pp->p_ncshot > conf_maxncshot) return; /* Heat up the gun: */ if (pp->p_ncshot++ == conf_maxncshot) { /* The gun has overheated: */ outyx(pp, STAT_GUN_ROW, STAT_VALUE_COL, " "); } /* Use up some ammo: */ pp->p_ammo -= slime_req[req_index]; ammo_update(pp); /* Start the slime moving: */ add_shot(SLIME, pp->p_y, pp->p_x, pp->p_face, slime_req[req_index] * conf_slimefactor, pp, FALSE, pp->p_face); pp->p_undershot = TRUE; /* Show the object to everyone: */ showexpl(pp->p_y, pp->p_x, SLIME); sendcom(ALL_PLAYERS, REFRESH); }
/* * fire_slime: * Fire a slime shot in the given direction */ static void fire_slime(PLAYER *pp, int req_index) { if (pp == NULL) return; #ifdef DEBUG if (req_index < 0 || req_index >= MAXSLIME) message(pp, "What you do?"); #endif while (req_index >= 0 && pp->p_ammo < slime_req[req_index]) req_index--; if (req_index < 0) { message(pp, "Not enough charges."); return; } if (pp->p_ncshot > MAXNCSHOT) return; if (pp->p_ncshot++ == MAXNCSHOT) { cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL); outstr(pp, " ", 3); } pp->p_ammo -= slime_req[req_index]; (void) snprintf(Buf, sizeof(Buf), "%3d", pp->p_ammo); cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); outstr(pp, Buf, 3); add_shot(SLIME, pp->p_y, pp->p_x, pp->p_face, slime_req[req_index] * SLIME_FACTOR, pp, false, pp->p_face); pp->p_undershot = true; /* * Show the object to everyone */ showexpl(pp->p_y, pp->p_x, SLIME); for (pp = Player; pp < End_player; pp++) sendcom(pp, REFRESH); #ifdef MONITOR for (pp = Monitor; pp < End_monitor; pp++) sendcom(pp, REFRESH); #endif }
/* * fire: * Fire a shot of the given type in the given direction */ static void fire(PLAYER *pp, int req_index) { if (pp == NULL) return; /* Drop the shot type down until we can afford it: */ while (req_index >= 0 && pp->p_ammo < shot_req[req_index]) req_index--; /* Can we shoot at all? */ if (req_index < 0) { message(pp, "Not enough charges."); return; } /* Check if the gun is too hot: */ if (pp->p_ncshot > conf_maxncshot) return; /* Heat up the gun: */ if (pp->p_ncshot++ == conf_maxncshot) { /* The gun has overheated: */ outyx(pp, STAT_GUN_ROW, STAT_VALUE_COL, " "); } /* Use up some ammo: */ pp->p_ammo -= shot_req[req_index]; ammo_update(pp); /* Start the bullet moving: */ add_shot(shot_type[req_index], pp->p_y, pp->p_x, pp->p_face, shot_req[req_index], pp, FALSE, pp->p_face); pp->p_undershot = TRUE; /* Show the bullet to everyone: */ showexpl(pp->p_y, pp->p_x, shot_type[req_index]); sendcom(ALL_PLAYERS, REFRESH); }
/* * remove_wall - add a location where the wall was blown away. * if there is no space left over, put the a wall at * the location currently pointed at. */ static void remove_wall(int y, int x) { REGEN *r; #if defined(MONITOR) || defined(FLY) PLAYER *pp; #endif #ifdef FLY char save_char = 0; #endif r = rem_index; while (r->r_y != 0) { #ifdef FLY switch (Maze[r->r_y][r->r_x]) { case SPACE: case LEFTS: case RIGHT: case ABOVE: case BELOW: case FLYER: save_char = Maze[r->r_y][r->r_x]; goto found; } #else if (Maze[r->r_y][r->r_x] == SPACE) break; #endif if (++r >= &removed[MAXREMOVE]) r = removed; } found: if (r->r_y != 0) { /* Slot being used, put back this wall */ #ifdef FLY if (save_char == SPACE) Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x]; else { pp = play_at(r->r_y, r->r_x); if (pp->p_flying >= 0) pp->p_flying += rand_num(10); else { pp->p_flying = rand_num(20); pp->p_flyx = 2 * rand_num(6) - 5; pp->p_flyy = 2 * rand_num(6) - 5; } pp->p_over = Orig_maze[r->r_y][r->r_x]; pp->p_face = FLYER; Maze[r->r_y][r->r_x] = FLYER; showexpl(r->r_y, r->r_x, FLYER); } #else Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x]; #endif #ifdef RANDOM if (rand_num(100) == 0) Maze[r->r_y][r->r_x] = DOOR; #endif #ifdef REFLECT if (rand_num(100) == 0) /* one percent of the time */ Maze[r->r_y][r->r_x] = WALL4; #endif #ifdef MONITOR for (pp = Monitor; pp < End_monitor; pp++) check(pp, r->r_y, r->r_x); #endif } r->r_y = y; r->r_x = x; if (++r >= &removed[MAXREMOVE]) rem_index = removed; else rem_index = r; Maze[y][x] = SPACE; #ifdef MONITOR for (pp = Monitor; pp < End_monitor; pp++) check(pp, y, x); #endif }
/* * move_slime: * move the given slime shot speed times and add it back if * it hasn't fizzled yet */ static void move_slime(BULLET *bp, int speed, BULLET *next) { int i, j, dirmask, count; PLAYER *pp; BULLET *nbp; if (speed == 0) { if (bp->b_charge <= 0) free(bp); else save_bullet(bp); return; } /* Draw it: */ showexpl(bp->b_y, bp->b_x, bp->b_type == LAVA ? LAVA : '*'); switch (Maze[bp->b_y][bp->b_x]) { /* Someone got hit by slime or lava: */ case LEFTS: case RIGHT: case ABOVE: case BELOW: case FLYER: pp = play_at(bp->b_y, bp->b_x); message(pp, "You've been slimed."); checkdam(pp, bp->b_owner, bp->b_score, conf_mindam, bp->b_type); break; /* Bullets detonate in slime and lava: */ case SHOT: case GRENADE: case SATCHEL: case BOMB: case DSHOT: explshot(next, bp->b_y, bp->b_x); explshot(Bullets, bp->b_y, bp->b_x); break; } /* Drain the slime/lava of some energy: */ if (--bp->b_charge <= 0) { /* It fizzled: */ free(bp); return; } /* Figure out which way the slime should flow: */ 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--; } } /* Spawn little slimes off in every possible direction: */ 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(bp); }
/* * chkshot * Handle explosions */ static void chkshot(BULLET *bp, BULLET *next) { int y, x; int dy, dx, absdy; int delta, damage; char expl; PLAYER *pp; delta = 0; switch (bp->b_type) { case SHOT: case MINE: case GRENADE: case GMINE: case SATCHEL: case BOMB: delta = bp->b_size - 1; break; case SLIME: case LAVA: chkslime(bp, next); return; case DSHOT: bp->b_type = SLIME; chkslime(bp, next); return; } /* Draw the explosion square: */ 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++) { /* Draw a part of the explosion cloud: */ 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); /* Check what poor bastard was in the explosion: */ switch (Maze[y][x]) { case LEFTS: case RIGHT: case ABOVE: case BELOW: case FLYER: if (dx < 0) dx = -dx; if (absdy > dx) damage = bp->b_size - absdy; else damage = bp->b_size - dx; /* Everybody hurts, sometimes. */ pp = play_at(y, x); checkdam(pp, bp->b_owner, bp->b_score, damage * conf_mindam, bp->b_type); break; case GMINE: case MINE: /* Mines detonate in a chain reaction: */ add_shot((Maze[y][x] == GMINE) ? GRENADE : SHOT, y, x, LEFTS, (Maze[y][x] == GMINE) ? GRENREQ : BULREQ, NULL, TRUE, SPACE); Maze[y][x] = SPACE; break; } } } }
/* * move_flyer: * Update the position of a player in flight */ static void move_flyer(PLAYER *pp) { int x, y; if (pp->p_undershot) { fixshots(pp->p_y, pp->p_x, pp->p_over); pp->p_undershot = FALSE; } /* Restore what the flier was flying over */ Maze[pp->p_y][pp->p_x] = pp->p_over; /* Fly: */ x = pp->p_x + pp->p_flyx; y = pp->p_y + pp->p_flyy; /* Bouncing off the edges of the maze: */ 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; } /* Make sure we don't land on something we can't: */ again: switch (Maze[y][x]) { default: /* * Flier is over something other than space, a wall * or a door. Randomly move (drift) the flier a little bit * and then try again: */ switch (rand_num(4)) { case 0: PLUS_DELTA(x, WIDTH - 2); break; case 1: MINUS_DELTA(x, 1); break; case 2: PLUS_DELTA(y, HEIGHT - 2); break; case 3: MINUS_DELTA(y, 1); break; } goto again; /* Give a little boost when about to land on a wall or door: */ case WALL1: case WALL2: case WALL3: case WALL4: case WALL5: case DOOR: if (pp->p_flying == 0) pp->p_flying++; break; /* Spaces are okay: */ case SPACE: break; } /* Update flier's coordinates: */ pp->p_y = y; pp->p_x = x; /* Consume 'flying' time: */ if (pp->p_flying-- == 0) { /* Land: */ if (pp->p_face != BOOT && pp->p_face != BOOT_PAIR) { /* Land a player - they stustain a fall: */ checkdam(pp, NULL, NULL, rand_num(pp->p_damage / conf_fall_frac), FALL); pp->p_face = rand_dir(); showstat(pp); } else { /* Land boots: */ if (Maze[y][x] == BOOT) pp->p_face = BOOT_PAIR; Maze[y][x] = SPACE; } } /* Save under the flier: */ pp->p_over = Maze[y][x]; /* Draw in the flier: */ Maze[y][x] = pp->p_face; showexpl(y, x, pp->p_face); }
/* * zap: * Kill off a player and take them out of the game. * The 'was_player' flag indicates that the player was not * a monitor and needs extra cleaning up. */ static void zap(PLAYER *pp, FLAG was_player) { int len; BULLET *bp; PLAYER *np; int x, y; int savefd; if (was_player) { /* If they died from a shot, clean up shrapnel */ if (pp->p_undershot) fixshots(pp->p_y, pp->p_x, pp->p_over); /* Let the player see their last position: */ drawplayer(pp, FALSE); /* Remove from game: */ Nplayer--; } /* Display the cause of death in the centre of the screen: */ len = strlen(pp->p_death); x = (WIDTH - len) / 2; outyx(pp, HEIGHT / 2, x, "%s", pp->p_death); /* Put some horizontal lines around and below the death message: */ memset(pp->p_death + 1, '-', len - 2); pp->p_death[0] = '+'; pp->p_death[len - 1] = '+'; outyx(pp, HEIGHT / 2 - 1, x, "%s", pp->p_death); outyx(pp, HEIGHT / 2 + 1, x, "%s", pp->p_death); /* Move to bottom left */ cgoto(pp, HEIGHT, 0); savefd = pp->p_fd; if (was_player) { int expl_charge; int expl_type; int ammo_exploding; /* Check all the bullets: */ for (bp = Bullets; bp != NULL; bp = bp->b_next) { if (bp->b_owner == pp) /* Zapped players can't own bullets: */ bp->b_owner = NULL; if (bp->b_x == pp->p_x && bp->b_y == pp->p_y) /* Bullets over the player are now over air: */ bp->b_over = SPACE; } /* Explode a random fraction of the player's ammo: */ ammo_exploding = rand_num(pp->p_ammo); /* Determine the type and amount of detonation: */ expl_charge = rand_num(ammo_exploding + 1); if (pp->p_ammo == 0) /* Ignore the no-ammo case: */ expl_charge = expl_type = 0; else if (ammo_exploding >= pp->p_ammo - 1) { /* Maximal explosions always appear as slime: */ expl_charge = pp->p_ammo; expl_type = SLIME; } else { /* * Figure out the best effective explosion * type to use, given the amount of charge */ int btype, stype; for (btype = MAXBOMB - 1; btype > 0; btype--) if (expl_charge >= shot_req[btype]) break; for (stype = MAXSLIME - 1; stype > 0; stype--) if (expl_charge >= slime_req[stype]) break; /* Pick the larger of the bomb or slime: */ if (btype >= 0 && stype >= 0) { if (shot_req[btype] > slime_req[btype]) btype = -1; } if (btype >= 0) { expl_type = shot_type[btype]; expl_charge = shot_req[btype]; } else expl_type = SLIME; } if (expl_charge > 0) { char buf[BUFSIZ]; /* Detonate: */ (void) add_shot(expl_type, pp->p_y, pp->p_x, pp->p_face, expl_charge, NULL, TRUE, SPACE); /* Explain what the explosion is about. */ snprintf(buf, sizeof buf, "%s detonated.", pp->p_ident->i_name); message(ALL_PLAYERS, buf); while (pp->p_nboots-- > 0) { /* Throw one of the boots away: */ for (np = Boot; np < &Boot[NBOOTS]; np++) if (np->p_flying < 0) break; #ifdef DIAGNOSTIC if (np >= &Boot[NBOOTS]) err(1, "Too many boots"); #endif /* Start the boots from where the player is */ np->p_undershot = FALSE; np->p_x = pp->p_x; np->p_y = pp->p_y; /* Throw for up to 20 steps */ np->p_flying = rand_num(20); np->p_flyx = 2 * rand_num(6) - 5; np->p_flyy = 2 * rand_num(6) - 5; np->p_over = SPACE; np->p_face = BOOT; showexpl(np->p_y, np->p_x, BOOT); } } /* No explosion. Leave the player's boots behind. */ else if (pp->p_nboots > 0) { if (pp->p_nboots == 2) Maze[pp->p_y][pp->p_x] = BOOT_PAIR; else Maze[pp->p_y][pp->p_x] = BOOT; if (pp->p_undershot) fixshots(pp->p_y, pp->p_x, Maze[pp->p_y][pp->p_x]); } /* Any unexploded ammo builds up in the volcano: */ volcano += pp->p_ammo - expl_charge; /* Volcano eruption: */ if (conf_volcano && rand_num(100) < volcano / conf_volcano_max) { /* Erupt near the middle of the map */ do { x = rand_num(WIDTH / 2) + WIDTH / 4; y = rand_num(HEIGHT / 2) + HEIGHT / 4; } while (Maze[y][x] != SPACE); /* Convert volcano charge into lava: */ (void) add_shot(LAVA, y, x, LEFTS, volcano, NULL, TRUE, SPACE); volcano = 0; /* Tell eveyone what's happening */ message(ALL_PLAYERS, "Volcano eruption."); } /* Drone: */ if (conf_drone && rand_num(100) < 2) { /* Find a starting place near the middle of the map: */ do { x = rand_num(WIDTH / 2) + WIDTH / 4; y = rand_num(HEIGHT / 2) + HEIGHT / 4; } while (Maze[y][x] != SPACE); /* Start the drone going: */ add_shot(DSHOT, y, x, rand_dir(), shot_req[conf_mindshot + rand_num(MAXBOMB - conf_mindshot)], NULL, FALSE, SPACE); } /* Tell the zapped player's client to shut down. */ sendcom(pp, ENDWIN, ' '); (void) fclose(pp->p_output); /* Close up the gap in the Player array: */ End_player--; if (pp != End_player) { /* Move the last player into the gap: */ memcpy(pp, End_player, sizeof *pp); outyx(ALL_PLAYERS, STAT_PLAY_ROW + 1 + (pp - Player), STAT_NAME_COL, "%5.2f%c%-10.10s %c", pp->p_ident->i_score, stat_char(pp), pp->p_ident->i_name, pp->p_ident->i_team); } /* Erase the last player from the display: */ cgoto(ALL_PLAYERS, STAT_PLAY_ROW + 1 + Nplayer, STAT_NAME_COL); ce(ALL_PLAYERS); } else { /* Zap a monitor */ /* Close the session: */ sendcom(pp, ENDWIN, LAST_PLAYER); (void) fclose(pp->p_output); /* shuffle the monitor table */ End_monitor--; if (pp != End_monitor) { memcpy(pp, End_monitor, sizeof *pp); outyx(ALL_PLAYERS, STAT_MON_ROW + 1 + (pp - Player), STAT_NAME_COL, "%5.5s %-10.10s %c", " ", pp->p_ident->i_name, pp->p_ident->i_team); } /* Erase the last monitor in the list */ cgoto(ALL_PLAYERS, STAT_MON_ROW + 1 + (End_monitor - Monitor), STAT_NAME_COL); ce(ALL_PLAYERS); } /* Update the file descriptor sets used by select: */ FD_CLR(savefd, &Fds_mask); if (Num_fds == savefd + 1) { Num_fds = Socket; if (Server_socket > Socket) Num_fds = Server_socket; for (np = Player; np < End_player; np++) if (np->p_fd > Num_fds) Num_fds = np->p_fd; for (np = Monitor; np < End_monitor; np++) if (np->p_fd > Num_fds) Num_fds = np->p_fd; Num_fds++; } }
/** * Initializes a player status. * @param[out] newpp The new player to initialize. * @param[in] enter_status The enter mode of a player. * [PSR] */ void stplayer(PLAYER *newpp, int enter_status) { int x, y; PLAYER *pp; nplayer++; for (y = 0; y < UBOUND; y++) { for (x = 0; x < WIDTH; x++) { newpp->p_maze[y][x] = maze[y][x]; } } for (; y < DBOUND; y++) { for (x = 0; x < LBOUND; x++) { newpp->p_maze[y][x] = maze[y][x]; } for (; x < RBOUND; x++) { newpp->p_maze[y][x] = SPACE; } for (; x < WIDTH; x++) { newpp->p_maze[y][x] = maze[y][x]; } } for (; y < HEIGHT; y++) { for (x = 0; x < WIDTH; x++) { newpp->p_maze[y][x] = maze[y][x]; } } do { x = rand_num(WIDTH - 1) + 1; y = rand_num(HEIGHT - 1) + 1; } while (maze[y][x] != SPACE); newpp->p_over = SPACE; newpp->p_x = x; newpp->p_y = y; newpp->p_undershot = false; # ifdef FLY if (enter_status == Q_FLY) { newpp->p_flying = rand_num(20); newpp->p_flyx = 2 * rand_num(6) - 5; newpp->p_flyy = 2 * rand_num(6) - 5; newpp->p_face = FLYER; } else # endif { # ifdef FLY newpp->p_flying = -1; # endif newpp->p_face = rand_dir(); } newpp->p_damage = 0; newpp->p_damcap = MAXDAM; newpp->p_nchar = 0; newpp->p_ncount = 0; newpp->p_nexec = 0; newpp->p_ammo = ISHOTS; # ifdef BOOTS newpp->p_nboots = 0; # endif if (enter_status == Q_SCAN) { newpp->p_scan = SCANLEN; newpp->p_cloak = 0; } else { newpp->p_scan = 0; newpp->p_cloak = CLOAKLEN; } newpp->p_ncshot = 0; do { x = rand_num(WIDTH - 1) + 1; y = rand_num(HEIGHT - 1) + 1; } while (maze[y][x] != SPACE); maze[y][x] = GMINE; # ifdef MONITOR for (pp = monitor; pp < end_monitor; pp++) { check(pp, y, x); } # endif do { x = rand_num(WIDTH - 1) + 1; y = rand_num(HEIGHT - 1) + 1; } while (maze[y][x] != SPACE); maze[y][x] = MINE; # ifdef MONITOR for (pp = monitor; pp < end_monitor; pp++) { check(pp, y, x); } # endif (void) sprintf(gen_buf, "%5.2f%c%-10.10s %c", newpp->p_ident->i_score, stat_char(newpp), newpp->p_ident->i_name, newpp->p_ident->i_team); y = STAT_PLAY_ROW + 1 + (newpp - player); for (pp = player; pp < end_player; pp++) { if (pp != newpp) { char smallbuf[10]; pp->p_ammo += NSHOTS; newpp->p_ammo += NSHOTS; cgoto(pp, y, STAT_NAME_COL); outstr(pp, gen_buf, STAT_NAME_LEN); (void) sprintf(smallbuf, "%3d", pp->p_ammo); cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); outstr(pp, smallbuf, 3); } } # ifdef MONITOR for (pp = monitor; pp < end_monitor; pp++) { cgoto(pp, y, STAT_NAME_COL); outstr(pp, gen_buf, STAT_NAME_LEN); } # endif drawmaze(newpp); drawplayer(newpp, true); look(newpp); # ifdef FLY if (enter_status == Q_FLY) { /* Make sure that the position you enter in will be erased */ showexpl(newpp->p_y, newpp->p_x, FLYER); } # endif sendcom(newpp, REFRESH); sendcom(newpp, READY, 0); (void) fflush(newpp->p_output); }
/* * remove_wall - add a location where the wall was blown away. * if there is no space left over, put the a wall at * the location currently pointed at. */ static void remove_wall(int y, int x) { REGEN *r; PLAYER *pp; char save_char = 0; if (removed == NULL) clearwalls(); r = rem_index; while (r->r_y != 0) { switch (Maze[r->r_y][r->r_x]) { case SPACE: case LEFTS: case RIGHT: case ABOVE: case BELOW: case FLYER: save_char = Maze[r->r_y][r->r_x]; goto found; } if (++r >= removed + conf_maxremove) r = removed; } found: if (r->r_y != 0) { /* Slot being used, put back this wall */ if (save_char == SPACE) Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x]; else { /* We throw the player off the wall: */ pp = play_at(r->r_y, r->r_x); if (pp->p_flying >= 0) pp->p_flying += rand_num(conf_flytime / 2); else { pp->p_flying = rand_num(conf_flytime); pp->p_flyx = 2 * rand_num(conf_flystep + 1) - conf_flystep; pp->p_flyy = 2 * rand_num(conf_flystep + 1) - conf_flystep; } pp->p_over = Orig_maze[r->r_y][r->r_x]; pp->p_face = FLYER; Maze[r->r_y][r->r_x] = FLYER; showexpl(r->r_y, r->r_x, FLYER); } Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x]; if (conf_random && rand_num(100) < conf_prandom) Maze[r->r_y][r->r_x] = DOOR; if (conf_reflect && rand_num(100) == conf_preflect) Maze[r->r_y][r->r_x] = WALL4; for (pp = Monitor; pp < End_monitor; pp++) check(pp, r->r_y, r->r_x); } r->r_y = y; r->r_x = x; if (++r >= removed + conf_maxremove) rem_index = removed; else rem_index = r; Maze[y][x] = SPACE; for (pp = Monitor; pp < End_monitor; pp++) check(pp, y, x); }