Home | History | Annotate | Line # | Download | only in huntd
expl.c revision 1.3
      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 }
    251