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