expl.c revision 1.2 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