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