expl.c revision 1.2
1/* $NetBSD: expl.c,v 1.2 1997/10/10 16:33:18 lukem Exp $ */ 2/* $OpenBSD: expl.c,v 1.2 1999/01/21 05:47:41 d Exp $ */ 3/* 4 * Hunt 5 * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold 6 * San Francisco, California 7 */ 8 9# include <stdlib.h> 10# include "hunt.h" 11 12static void remove_wall __P((int, int)); 13 14 15/* 16 * showexpl: 17 * Show the explosions as they currently are 18 */ 19void 20showexpl(y, x, type) 21 int y, x; 22 char type; 23{ 24 PLAYER *pp; 25 EXPL *ep; 26 27 if (y < 0 || y >= HEIGHT) 28 return; 29 if (x < 0 || x >= WIDTH) 30 return; 31 ep = (EXPL *) malloc(sizeof (EXPL)); /* NOSTRICT */ 32 ep->e_y = y; 33 ep->e_x = x; 34 ep->e_char = type; 35 ep->e_next = NULL; 36 if (Last_expl == NULL) 37 Expl[0] = ep; 38 else 39 Last_expl->e_next = ep; 40 Last_expl = ep; 41 for (pp = Player; pp < End_player; pp++) { 42 if (pp->p_maze[y][x] == type) 43 continue; 44 pp->p_maze[y][x] = type; 45 cgoto(pp, y, x); 46 outch(pp, type); 47 } 48# ifdef MONITOR 49 for (pp = Monitor; pp < End_monitor; pp++) { 50 if (pp->p_maze[y][x] == type) 51 continue; 52 pp->p_maze[y][x] = type; 53 cgoto(pp, y, x); 54 outch(pp, type); 55 } 56# endif 57 switch (Maze[y][x]) { 58 case WALL1: 59 case WALL2: 60 case WALL3: 61# ifdef RANDOM 62 case DOOR: 63# endif 64# ifdef REFLECT 65 case WALL4: 66 case WALL5: 67# endif 68 if (y >= UBOUND && y < DBOUND && x >= LBOUND && x < RBOUND) 69 remove_wall(y, x); 70 break; 71 } 72} 73 74/* 75 * rollexpl: 76 * Roll the explosions over, so the next one in the list is at the 77 * top 78 */ 79void 80rollexpl() 81{ 82 EXPL *ep; 83 PLAYER *pp; 84 int y, x; 85 char c; 86 EXPL *nextep; 87 88 for (ep = Expl[EXPLEN - 1]; ep != NULL; ep = nextep) { 89 nextep = ep->e_next; 90 y = ep->e_y; 91 x = ep->e_x; 92 if (y < UBOUND || y >= DBOUND || x < LBOUND || x >= RBOUND) 93 c = Maze[y][x]; 94 else 95 c = SPACE; 96 for (pp = Player; pp < End_player; pp++) 97 if (pp->p_maze[y][x] == ep->e_char) { 98 pp->p_maze[y][x] = c; 99 cgoto(pp, y, x); 100 outch(pp, c); 101 } 102# ifdef MONITOR 103 for (pp = Monitor; pp < End_monitor; pp++) 104 check(pp, y, x); 105# endif 106 free((char *) ep); 107 } 108 for (x = EXPLEN - 1; x > 0; x--) 109 Expl[x] = Expl[x - 1]; 110 Last_expl = Expl[0] = NULL; 111} 112 113/* There's about 700 walls in the initial maze. So we pick a number 114 * that keeps the maze relatively full. */ 115# define MAXREMOVE 40 116 117static REGEN removed[MAXREMOVE]; 118static REGEN *rem_index = removed; 119 120/* 121 * remove_wall - add a location where the wall was blown away. 122 * if there is no space left over, put the a wall at 123 * the location currently pointed at. 124 */ 125static void 126remove_wall(y, x) 127 int y, x; 128{ 129 REGEN *r; 130# if defined(MONITOR) || defined(FLY) 131 PLAYER *pp; 132# endif 133# ifdef FLY 134 char save_char = 0; 135# endif 136 137 r = rem_index; 138 while (r->r_y != 0) { 139# ifdef FLY 140 switch (Maze[r->r_y][r->r_x]) { 141 case SPACE: 142 case LEFTS: 143 case RIGHT: 144 case ABOVE: 145 case BELOW: 146 case FLYER: 147 save_char = Maze[r->r_y][r->r_x]; 148 goto found; 149 } 150# else 151 if (Maze[r->r_y][r->r_x] == SPACE) 152 break; 153# endif 154 if (++r >= &removed[MAXREMOVE]) 155 r = removed; 156 } 157 158found: 159 if (r->r_y != 0) { 160 /* Slot being used, put back this wall */ 161# ifdef FLY 162 if (save_char == SPACE) 163 Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x]; 164 else { 165 pp = play_at(r->r_y, r->r_x); 166 if (pp->p_flying >= 0) 167 pp->p_flying += rand_num(10); 168 else { 169 pp->p_flying = rand_num(20); 170 pp->p_flyx = 2 * rand_num(6) - 5; 171 pp->p_flyy = 2 * rand_num(6) - 5; 172 } 173 pp->p_over = Orig_maze[r->r_y][r->r_x]; 174 pp->p_face = FLYER; 175 Maze[r->r_y][r->r_x] = FLYER; 176 showexpl(r->r_y, r->r_x, FLYER); 177 } 178# else 179 Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x]; 180# endif 181# ifdef RANDOM 182 if (rand_num(100) == 0) 183 Maze[r->r_y][r->r_x] = DOOR; 184# endif 185# ifdef REFLECT 186 if (rand_num(100) == 0) /* one percent of the time */ 187 Maze[r->r_y][r->r_x] = WALL4; 188# endif 189# ifdef MONITOR 190 for (pp = Monitor; pp < End_monitor; pp++) 191 check(pp, r->r_y, r->r_x); 192# endif 193 } 194 195 r->r_y = y; 196 r->r_x = x; 197 if (++r >= &removed[MAXREMOVE]) 198 rem_index = removed; 199 else 200 rem_index = r; 201 202 Maze[y][x] = SPACE; 203# ifdef MONITOR 204 for (pp = Monitor; pp < End_monitor; pp++) 205 check(pp, y, x); 206# endif 207} 208 209/* 210 * clearwalls: 211 * Clear out the walls array 212 */ 213void 214clearwalls() 215{ 216 REGEN *rp; 217 218 for (rp = removed; rp < &removed[MAXREMOVE]; rp++) 219 rp->r_y = 0; 220 rem_index = removed; 221} 222