xref: /netbsd/games/hunt/huntd/expl.c (revision bf9ec67e)
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