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