Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / games / hunt / huntd / expl.c
blob0fd341da75d27ee6a95322dcf82379efd9b1cea6
1 /* $NetBSD: expl.c,v 1.6 2009/07/04 02:37:20 dholland 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.
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.
33 #include <sys/cdefs.h>
34 #ifndef lint
35 __RCSID("$NetBSD: expl.c,v 1.6 2009/07/04 02:37:20 dholland Exp $");
36 #endif /* not lint */
38 #include <stdlib.h>
39 #include "hunt.h"
41 static void remove_wall(int, int);
45 * showexpl:
46 * Show the explosions as they currently are
48 void
49 showexpl(int y, int x, char type)
51 PLAYER *pp;
52 EXPL *ep;
54 if (y < 0 || y >= HEIGHT)
55 return;
56 if (x < 0 || x >= WIDTH)
57 return;
58 ep = malloc(sizeof(*ep));
59 ep->e_y = y;
60 ep->e_x = x;
61 ep->e_char = type;
62 ep->e_next = NULL;
63 if (Last_expl == NULL)
64 Expl[0] = ep;
65 else
66 Last_expl->e_next = ep;
67 Last_expl = ep;
68 for (pp = Player; pp < End_player; pp++) {
69 if (pp->p_maze[y][x] == type)
70 continue;
71 pp->p_maze[y][x] = type;
72 cgoto(pp, y, x);
73 outch(pp, type);
75 #ifdef MONITOR
76 for (pp = Monitor; pp < End_monitor; pp++) {
77 if (pp->p_maze[y][x] == type)
78 continue;
79 pp->p_maze[y][x] = type;
80 cgoto(pp, y, x);
81 outch(pp, type);
83 #endif
84 switch (Maze[y][x]) {
85 case WALL1:
86 case WALL2:
87 case WALL3:
88 #ifdef RANDOM
89 case DOOR:
90 #endif
91 #ifdef REFLECT
92 case WALL4:
93 case WALL5:
94 #endif
95 if (y >= UBOUND && y < DBOUND && x >= LBOUND && x < RBOUND)
96 remove_wall(y, x);
97 break;
102 * rollexpl:
103 * Roll the explosions over, so the next one in the list is at the
104 * top
106 void
107 rollexpl(void)
109 EXPL *ep;
110 PLAYER *pp;
111 int y, x;
112 char c;
113 EXPL *nextep;
115 for (ep = Expl[EXPLEN - 1]; ep != NULL; ep = nextep) {
116 nextep = ep->e_next;
117 y = ep->e_y;
118 x = ep->e_x;
119 if (y < UBOUND || y >= DBOUND || x < LBOUND || x >= RBOUND)
120 c = Maze[y][x];
121 else
122 c = SPACE;
123 for (pp = Player; pp < End_player; pp++)
124 if (pp->p_maze[y][x] == ep->e_char) {
125 pp->p_maze[y][x] = c;
126 cgoto(pp, y, x);
127 outch(pp, c);
129 #ifdef MONITOR
130 for (pp = Monitor; pp < End_monitor; pp++)
131 check(pp, y, x);
132 #endif
133 free(ep);
135 for (x = EXPLEN - 1; x > 0; x--)
136 Expl[x] = Expl[x - 1];
137 Last_expl = Expl[0] = NULL;
140 /* There's about 700 walls in the initial maze. So we pick a number
141 * that keeps the maze relatively full. */
142 #define MAXREMOVE 40
144 static REGEN removed[MAXREMOVE];
145 static REGEN *rem_index = removed;
148 * remove_wall - add a location where the wall was blown away.
149 * if there is no space left over, put the a wall at
150 * the location currently pointed at.
152 static void
153 remove_wall(int y, int x)
155 REGEN *r;
156 #if defined(MONITOR) || defined(FLY)
157 PLAYER *pp;
158 #endif
159 #ifdef FLY
160 char save_char = 0;
161 #endif
163 r = rem_index;
164 while (r->r_y != 0) {
165 #ifdef FLY
166 switch (Maze[r->r_y][r->r_x]) {
167 case SPACE:
168 case LEFTS:
169 case RIGHT:
170 case ABOVE:
171 case BELOW:
172 case FLYER:
173 save_char = Maze[r->r_y][r->r_x];
174 goto found;
176 #else
177 if (Maze[r->r_y][r->r_x] == SPACE)
178 break;
179 #endif
180 if (++r >= &removed[MAXREMOVE])
181 r = removed;
184 found:
185 if (r->r_y != 0) {
186 /* Slot being used, put back this wall */
187 #ifdef FLY
188 if (save_char == SPACE)
189 Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
190 else {
191 pp = play_at(r->r_y, r->r_x);
192 if (pp->p_flying >= 0)
193 pp->p_flying += rand_num(10);
194 else {
195 pp->p_flying = rand_num(20);
196 pp->p_flyx = 2 * rand_num(6) - 5;
197 pp->p_flyy = 2 * rand_num(6) - 5;
199 pp->p_over = Orig_maze[r->r_y][r->r_x];
200 pp->p_face = FLYER;
201 Maze[r->r_y][r->r_x] = FLYER;
202 showexpl(r->r_y, r->r_x, FLYER);
204 #else
205 Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
206 #endif
207 #ifdef RANDOM
208 if (rand_num(100) == 0)
209 Maze[r->r_y][r->r_x] = DOOR;
210 #endif
211 #ifdef REFLECT
212 if (rand_num(100) == 0) /* one percent of the time */
213 Maze[r->r_y][r->r_x] = WALL4;
214 #endif
215 #ifdef MONITOR
216 for (pp = Monitor; pp < End_monitor; pp++)
217 check(pp, r->r_y, r->r_x);
218 #endif
221 r->r_y = y;
222 r->r_x = x;
223 if (++r >= &removed[MAXREMOVE])
224 rem_index = removed;
225 else
226 rem_index = r;
228 Maze[y][x] = SPACE;
229 #ifdef MONITOR
230 for (pp = Monitor; pp < End_monitor; pp++)
231 check(pp, y, x);
232 #endif
236 * clearwalls:
237 * Clear out the walls array
239 void
240 clearwalls(void)
242 REGEN *rp;
244 for (rp = removed; rp < &removed[MAXREMOVE]; rp++)
245 rp->r_y = 0;
246 rem_index = removed;