expl.c revision 1.8 1 1.8 dholland /* $NetBSD: expl.c,v 1.8 2014/03/29 21:33:41 dholland Exp $ */
2 1.1 mrg /*
3 1.3 wiz * Copyright (c) 1983-2003, Regents of the University of California.
4 1.3 wiz * All rights reserved.
5 1.3 wiz *
6 1.3 wiz * Redistribution and use in source and binary forms, with or without
7 1.3 wiz * modification, are permitted provided that the following conditions are
8 1.3 wiz * met:
9 1.3 wiz *
10 1.3 wiz * + Redistributions of source code must retain the above copyright
11 1.3 wiz * notice, this list of conditions and the following disclaimer.
12 1.3 wiz * + Redistributions in binary form must reproduce the above copyright
13 1.3 wiz * notice, this list of conditions and the following disclaimer in the
14 1.3 wiz * documentation and/or other materials provided with the distribution.
15 1.3 wiz * + Neither the name of the University of California, San Francisco nor
16 1.3 wiz * the names of its contributors may be used to endorse or promote
17 1.3 wiz * products derived from this software without specific prior written
18 1.3 wiz * permission.
19 1.3 wiz *
20 1.3 wiz * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 1.3 wiz * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 1.3 wiz * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 1.3 wiz * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 1.3 wiz * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 1.3 wiz * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 1.3 wiz * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 1.3 wiz * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 1.3 wiz * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 1.3 wiz * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 1.3 wiz * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 1.1 mrg */
32 1.1 mrg
33 1.2 lukem #include <sys/cdefs.h>
34 1.2 lukem #ifndef lint
35 1.8 dholland __RCSID("$NetBSD: expl.c,v 1.8 2014/03/29 21:33:41 dholland Exp $");
36 1.2 lukem #endif /* not lint */
37 1.2 lukem
38 1.7 dholland #include <stdlib.h>
39 1.7 dholland #include "hunt.h"
40 1.1 mrg
41 1.8 dholland
42 1.8 dholland static EXPL *Expl[EXPLEN]; /* explosion lists */
43 1.8 dholland static EXPL *Last_expl; /* last explosion on Expl[0] */
44 1.8 dholland
45 1.7 dholland static void remove_wall(int, int);
46 1.2 lukem
47 1.2 lukem
48 1.1 mrg /*
49 1.1 mrg * showexpl:
50 1.1 mrg * Show the explosions as they currently are
51 1.1 mrg */
52 1.2 lukem void
53 1.6 dholland showexpl(int y, int x, char type)
54 1.1 mrg {
55 1.7 dholland PLAYER *pp;
56 1.7 dholland EXPL *ep;
57 1.1 mrg
58 1.1 mrg if (y < 0 || y >= HEIGHT)
59 1.1 mrg return;
60 1.1 mrg if (x < 0 || x >= WIDTH)
61 1.1 mrg return;
62 1.5 dholland ep = malloc(sizeof(*ep));
63 1.1 mrg ep->e_y = y;
64 1.1 mrg ep->e_x = x;
65 1.1 mrg ep->e_char = type;
66 1.1 mrg ep->e_next = NULL;
67 1.1 mrg if (Last_expl == NULL)
68 1.1 mrg Expl[0] = ep;
69 1.1 mrg else
70 1.1 mrg Last_expl->e_next = ep;
71 1.1 mrg Last_expl = ep;
72 1.1 mrg for (pp = Player; pp < End_player; pp++) {
73 1.1 mrg if (pp->p_maze[y][x] == type)
74 1.1 mrg continue;
75 1.1 mrg pp->p_maze[y][x] = type;
76 1.1 mrg cgoto(pp, y, x);
77 1.1 mrg outch(pp, type);
78 1.1 mrg }
79 1.7 dholland #ifdef MONITOR
80 1.1 mrg for (pp = Monitor; pp < End_monitor; pp++) {
81 1.1 mrg if (pp->p_maze[y][x] == type)
82 1.1 mrg continue;
83 1.1 mrg pp->p_maze[y][x] = type;
84 1.1 mrg cgoto(pp, y, x);
85 1.1 mrg outch(pp, type);
86 1.1 mrg }
87 1.7 dholland #endif
88 1.1 mrg switch (Maze[y][x]) {
89 1.1 mrg case WALL1:
90 1.1 mrg case WALL2:
91 1.1 mrg case WALL3:
92 1.7 dholland #ifdef RANDOM
93 1.1 mrg case DOOR:
94 1.7 dholland #endif
95 1.7 dholland #ifdef REFLECT
96 1.1 mrg case WALL4:
97 1.1 mrg case WALL5:
98 1.7 dholland #endif
99 1.1 mrg if (y >= UBOUND && y < DBOUND && x >= LBOUND && x < RBOUND)
100 1.1 mrg remove_wall(y, x);
101 1.1 mrg break;
102 1.1 mrg }
103 1.1 mrg }
104 1.1 mrg
105 1.1 mrg /*
106 1.1 mrg * rollexpl:
107 1.1 mrg * Roll the explosions over, so the next one in the list is at the
108 1.1 mrg * top
109 1.1 mrg */
110 1.2 lukem void
111 1.6 dholland rollexpl(void)
112 1.1 mrg {
113 1.7 dholland EXPL *ep;
114 1.7 dholland PLAYER *pp;
115 1.7 dholland int y, x;
116 1.7 dholland char c;
117 1.7 dholland EXPL *nextep;
118 1.1 mrg
119 1.1 mrg for (ep = Expl[EXPLEN - 1]; ep != NULL; ep = nextep) {
120 1.1 mrg nextep = ep->e_next;
121 1.1 mrg y = ep->e_y;
122 1.1 mrg x = ep->e_x;
123 1.1 mrg if (y < UBOUND || y >= DBOUND || x < LBOUND || x >= RBOUND)
124 1.1 mrg c = Maze[y][x];
125 1.1 mrg else
126 1.1 mrg c = SPACE;
127 1.1 mrg for (pp = Player; pp < End_player; pp++)
128 1.1 mrg if (pp->p_maze[y][x] == ep->e_char) {
129 1.1 mrg pp->p_maze[y][x] = c;
130 1.1 mrg cgoto(pp, y, x);
131 1.1 mrg outch(pp, c);
132 1.1 mrg }
133 1.7 dholland #ifdef MONITOR
134 1.1 mrg for (pp = Monitor; pp < End_monitor; pp++)
135 1.1 mrg check(pp, y, x);
136 1.7 dholland #endif
137 1.5 dholland free(ep);
138 1.1 mrg }
139 1.1 mrg for (x = EXPLEN - 1; x > 0; x--)
140 1.1 mrg Expl[x] = Expl[x - 1];
141 1.1 mrg Last_expl = Expl[0] = NULL;
142 1.1 mrg }
143 1.1 mrg
144 1.1 mrg /* There's about 700 walls in the initial maze. So we pick a number
145 1.1 mrg * that keeps the maze relatively full. */
146 1.7 dholland #define MAXREMOVE 40
147 1.1 mrg
148 1.7 dholland static REGEN removed[MAXREMOVE];
149 1.7 dholland static REGEN *rem_index = removed;
150 1.1 mrg
151 1.1 mrg /*
152 1.1 mrg * remove_wall - add a location where the wall was blown away.
153 1.1 mrg * if there is no space left over, put the a wall at
154 1.1 mrg * the location currently pointed at.
155 1.1 mrg */
156 1.2 lukem static void
157 1.6 dholland remove_wall(int y, int x)
158 1.1 mrg {
159 1.7 dholland REGEN *r;
160 1.7 dholland #if defined(MONITOR) || defined(FLY)
161 1.7 dholland PLAYER *pp;
162 1.7 dholland #endif
163 1.7 dholland #ifdef FLY
164 1.7 dholland char save_char = 0;
165 1.7 dholland #endif
166 1.1 mrg
167 1.1 mrg r = rem_index;
168 1.1 mrg while (r->r_y != 0) {
169 1.7 dholland #ifdef FLY
170 1.1 mrg switch (Maze[r->r_y][r->r_x]) {
171 1.1 mrg case SPACE:
172 1.1 mrg case LEFTS:
173 1.1 mrg case RIGHT:
174 1.1 mrg case ABOVE:
175 1.1 mrg case BELOW:
176 1.1 mrg case FLYER:
177 1.1 mrg save_char = Maze[r->r_y][r->r_x];
178 1.1 mrg goto found;
179 1.1 mrg }
180 1.7 dholland #else
181 1.1 mrg if (Maze[r->r_y][r->r_x] == SPACE)
182 1.1 mrg break;
183 1.7 dholland #endif
184 1.1 mrg if (++r >= &removed[MAXREMOVE])
185 1.1 mrg r = removed;
186 1.1 mrg }
187 1.1 mrg
188 1.1 mrg found:
189 1.1 mrg if (r->r_y != 0) {
190 1.1 mrg /* Slot being used, put back this wall */
191 1.7 dholland #ifdef FLY
192 1.1 mrg if (save_char == SPACE)
193 1.1 mrg Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
194 1.1 mrg else {
195 1.1 mrg pp = play_at(r->r_y, r->r_x);
196 1.1 mrg if (pp->p_flying >= 0)
197 1.1 mrg pp->p_flying += rand_num(10);
198 1.1 mrg else {
199 1.1 mrg pp->p_flying = rand_num(20);
200 1.1 mrg pp->p_flyx = 2 * rand_num(6) - 5;
201 1.1 mrg pp->p_flyy = 2 * rand_num(6) - 5;
202 1.1 mrg }
203 1.1 mrg pp->p_over = Orig_maze[r->r_y][r->r_x];
204 1.1 mrg pp->p_face = FLYER;
205 1.1 mrg Maze[r->r_y][r->r_x] = FLYER;
206 1.1 mrg showexpl(r->r_y, r->r_x, FLYER);
207 1.1 mrg }
208 1.7 dholland #else
209 1.1 mrg Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
210 1.7 dholland #endif
211 1.7 dholland #ifdef RANDOM
212 1.1 mrg if (rand_num(100) == 0)
213 1.1 mrg Maze[r->r_y][r->r_x] = DOOR;
214 1.7 dholland #endif
215 1.7 dholland #ifdef REFLECT
216 1.1 mrg if (rand_num(100) == 0) /* one percent of the time */
217 1.1 mrg Maze[r->r_y][r->r_x] = WALL4;
218 1.7 dholland #endif
219 1.7 dholland #ifdef MONITOR
220 1.1 mrg for (pp = Monitor; pp < End_monitor; pp++)
221 1.1 mrg check(pp, r->r_y, r->r_x);
222 1.7 dholland #endif
223 1.1 mrg }
224 1.1 mrg
225 1.1 mrg r->r_y = y;
226 1.1 mrg r->r_x = x;
227 1.1 mrg if (++r >= &removed[MAXREMOVE])
228 1.1 mrg rem_index = removed;
229 1.1 mrg else
230 1.1 mrg rem_index = r;
231 1.1 mrg
232 1.1 mrg Maze[y][x] = SPACE;
233 1.7 dholland #ifdef MONITOR
234 1.1 mrg for (pp = Monitor; pp < End_monitor; pp++)
235 1.1 mrg check(pp, y, x);
236 1.7 dholland #endif
237 1.1 mrg }
238 1.1 mrg
239 1.1 mrg /*
240 1.1 mrg * clearwalls:
241 1.1 mrg * Clear out the walls array
242 1.1 mrg */
243 1.2 lukem void
244 1.6 dholland clearwalls(void)
245 1.1 mrg {
246 1.7 dholland REGEN *rp;
247 1.1 mrg
248 1.1 mrg for (rp = removed; rp < &removed[MAXREMOVE]; rp++)
249 1.1 mrg rp->r_y = 0;
250 1.1 mrg rem_index = removed;
251 1.1 mrg }
252