Home | History | Annotate | Line # | Download | only in rogue
trap.c revision 1.5
      1 /*	$NetBSD: trap.c,v 1.5 1998/11/10 13:01:32 hubertf Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1988, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * This code is derived from software contributed to Berkeley by
      8  * Timothy C. Stoehr.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *	This product includes software developed by the University of
     21  *	California, Berkeley and its contributors.
     22  * 4. Neither the name of the University nor the names of its contributors
     23  *    may be used to endorse or promote products derived from this software
     24  *    without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     36  * SUCH DAMAGE.
     37  */
     38 
     39 #include <sys/cdefs.h>
     40 #ifndef lint
     41 #if 0
     42 static char sccsid[] = "@(#)trap.c	8.1 (Berkeley) 5/31/93";
     43 #else
     44 __RCSID("$NetBSD: trap.c,v 1.5 1998/11/10 13:01:32 hubertf Exp $");
     45 #endif
     46 #endif /* not lint */
     47 
     48 /*
     49  * trap.c
     50  *
     51  * This source herein may be modified and/or distributed by anybody who
     52  * so desires, with the following restrictions:
     53  *    1.)  No portion of this notice shall be removed.
     54  *    2.)  Credit shall not be taken for the creation of this source.
     55  *    3.)  This code is not to be traded, sold, or used for personal
     56  *         gain or profit.
     57  *
     58  */
     59 
     60 #include "rogue.h"
     61 
     62 trap traps[MAX_TRAPS];
     63 boolean trap_door = 0;
     64 short bear_trap = 0;
     65 
     66 const char *const trap_strings[TRAPS * 2] = {
     67 	"trap door",
     68 			"you fell down a trap",
     69 	"bear trap",
     70 			"you are caught in a bear trap",
     71 	"teleport trap",
     72 			"teleport",
     73 	"poison dart trap",
     74 			"a small dart just hit you in the shoulder",
     75 	"sleeping gas trap",
     76 			"a strange white mist envelops you and you fall asleep",
     77 	"rust trap",
     78 			"a gush of water hits you on the head"
     79 };
     80 
     81 short
     82 trap_at(row, col)
     83 	int row, col;
     84 {
     85 	short i;
     86 
     87 	for (i = 0; ((i < MAX_TRAPS) && (traps[i].trap_type != NO_TRAP)); i++) {
     88 		if ((traps[i].trap_row == row) && (traps[i].trap_col == col)) {
     89 			return(traps[i].trap_type);
     90 		}
     91 	}
     92 	return(NO_TRAP);
     93 }
     94 
     95 void
     96 trap_player(row, col)
     97 	short row, col;
     98 {
     99 	short t;
    100 
    101 	if ((t = trap_at(row, col)) == NO_TRAP) {
    102 		return;
    103 	}
    104 	dungeon[row][col] &= (~HIDDEN);
    105 	if (rand_percent(rogue.exp + ring_exp)) {
    106 		message("the trap failed", 1);
    107 		return;
    108 	}
    109 	switch(t) {
    110 	case TRAP_DOOR:
    111 		trap_door = 1;
    112 		new_level_message = trap_strings[(t*2)+1];
    113 		break;
    114 	case BEAR_TRAP:
    115 		message(trap_strings[(t*2)+1], 1);
    116 		bear_trap = get_rand(4, 7);
    117 		break;
    118 	case TELE_TRAP:
    119 		mvaddch(rogue.row, rogue.col, '^');
    120 		tele();
    121 		break;
    122 	case DART_TRAP:
    123 		message(trap_strings[(t*2)+1], 1);
    124 		rogue.hp_current -= get_damage("1d6", 1);
    125 		if (rogue.hp_current <= 0) {
    126 			rogue.hp_current = 0;
    127 		}
    128 		if ((!sustain_strength) && rand_percent(40) &&
    129 			(rogue.str_current >= 3)) {
    130 			rogue.str_current--;
    131 		}
    132 		print_stats(STAT_HP | STAT_STRENGTH);
    133 		if (rogue.hp_current <= 0) {
    134 			killed_by((object *) 0, POISON_DART);
    135 		}
    136 		break;
    137 	case SLEEPING_GAS_TRAP:
    138 		message(trap_strings[(t*2)+1], 1);
    139 		take_a_nap();
    140 		break;
    141 	case RUST_TRAP:
    142 		message(trap_strings[(t*2)+1], 1);
    143 		rust((object *) 0);
    144 		break;
    145 	}
    146 }
    147 
    148 void
    149 add_traps()
    150 {
    151 	short i, n, tries = 0;
    152 	short row, col;
    153 
    154 	if (cur_level <= 2) {
    155 		n = 0;
    156 	} else if (cur_level <= 7) {
    157 		n = get_rand(0, 2);
    158 	} else if (cur_level <= 11) {
    159 		n = get_rand(1, 2);
    160 	} else if (cur_level <= 16) {
    161 		n = get_rand(2, 3);
    162 	} else if (cur_level <= 21) {
    163 		n = get_rand(2, 4);
    164 	} else if (cur_level <= (AMULET_LEVEL + 2)) {
    165 		n = get_rand(3, 5);
    166 	} else {
    167 		n = get_rand(5, MAX_TRAPS);
    168 	}
    169 	for (i = 0; i < n; i++) {
    170 		traps[i].trap_type = get_rand(0, (TRAPS - 1));
    171 
    172 		if ((i == 0) && (party_room != NO_ROOM)) {
    173 			do {
    174 				row = get_rand((rooms[party_room].top_row+1),
    175 						(rooms[party_room].bottom_row-1));
    176 				col = get_rand((rooms[party_room].left_col+1),
    177 						(rooms[party_room].right_col-1));
    178 				tries++;
    179 			} while (((dungeon[row][col] & (OBJECT|STAIRS|TRAP|TUNNEL)) ||
    180 					(dungeon[row][col] == NOTHING)) && (tries < 15));
    181 			if (tries >= 15) {
    182 				gr_row_col(&row, &col, (FLOOR | MONSTER));
    183 			}
    184 		} else {
    185 			gr_row_col(&row, &col, (FLOOR | MONSTER));
    186 		}
    187 		traps[i].trap_row = row;
    188 		traps[i].trap_col = col;
    189 		dungeon[row][col] |= (TRAP | HIDDEN);
    190 	}
    191 }
    192 
    193 void
    194 id_trap()
    195 {
    196 	short dir, row, col, d, t;
    197 
    198 	message("direction? ", 0);
    199 
    200 	while (!is_direction(dir = rgetchar(), &d)) {
    201 		sound_bell();
    202 	}
    203 	check_message();
    204 
    205 	if (dir == CANCEL) {
    206 		return;
    207 	}
    208 	row = rogue.row;
    209 	col = rogue.col;
    210 
    211 	get_dir_rc(d, &row, &col, 0);
    212 
    213 	if ((dungeon[row][col] & TRAP) && (!(dungeon[row][col] & HIDDEN))) {
    214 		t = trap_at(row, col);
    215 		message(trap_strings[t*2], 0);
    216 	} else {
    217 		message("no trap there", 0);
    218 	}
    219 }
    220 
    221 void
    222 show_traps()
    223 {
    224 	short i, j;
    225 
    226 	for (i = 0; i < DROWS; i++) {
    227 		for (j = 0; j < DCOLS; j++) {
    228 			if (dungeon[i][j] & TRAP) {
    229 				mvaddch(i, j, '^');
    230 			}
    231 		}
    232 	}
    233 }
    234 
    235 void
    236 search(n, is_auto)
    237 	short n;
    238 	boolean is_auto;
    239 {
    240 	short s, i, j, row, col, t;
    241 	short shown = 0, found = 0;
    242 	static boolean reg_search;
    243 
    244 	for (i = -1; i <= 1; i++) {
    245 		for (j = -1; j <= 1; j++) {
    246 			row = rogue.row + i;
    247 			col = rogue.col + j;
    248 			if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
    249 					(col < 0) || (col >= DCOLS)) {
    250 				continue;
    251 			}
    252 			if (dungeon[row][col] & HIDDEN) {
    253 				found++;
    254 			}
    255 		}
    256 	}
    257 	for (s = 0; s < n; s++) {
    258 		for (i = -1; i <= 1; i++) {
    259 			for (j = -1; j <= 1; j++) {
    260 				row = rogue.row + i;
    261 				col = rogue.col + j ;
    262 				if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
    263 						(col < 0) || (col >= DCOLS)) {
    264 					continue;
    265 				}
    266 				if (dungeon[row][col] & HIDDEN) {
    267 					if (rand_percent(17 + (rogue.exp + ring_exp))) {
    268 						dungeon[row][col] &= (~HIDDEN);
    269 						if ((!blind) && ((row != rogue.row) ||
    270 								(col != rogue.col))) {
    271 							mvaddch(row, col, get_dungeon_char(row, col));
    272 						}
    273 						shown++;
    274 						if (dungeon[row][col] & TRAP) {
    275 							t = trap_at(row, col);
    276 							message(trap_strings[t*2], 1);
    277 						}
    278 					}
    279 				}
    280 				if (((shown == found) && (found > 0)) || interrupted) {
    281 					return;
    282 				}
    283 			}
    284 		}
    285 		if ((!is_auto) && (reg_search = !reg_search)) {
    286 			(void) reg_move();
    287 		}
    288 	}
    289 }
    290