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