Home | History | Annotate | Line # | Download | only in rogue
trap.c revision 1.3
      1 /*	$NetBSD: trap.c,v 1.3 1995/04/22 10:28:35 cgd 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 #ifndef lint
     40 #if 0
     41 static char sccsid[] = "@(#)trap.c	8.1 (Berkeley) 5/31/93";
     42 #else
     43 static char rcsid[] = "$NetBSD: trap.c,v 1.3 1995/04/22 10:28:35 cgd Exp $";
     44 #endif
     45 #endif /* not lint */
     46 
     47 /*
     48  * trap.c
     49  *
     50  * This source herein may be modified and/or distributed by anybody who
     51  * so desires, with the following restrictions:
     52  *    1.)  No portion of this notice shall be removed.
     53  *    2.)  Credit shall not be taken for the creation of this source.
     54  *    3.)  This code is not to be traded, sold, or used for personal
     55  *         gain or profit.
     56  *
     57  */
     58 
     59 #include "rogue.h"
     60 
     61 trap traps[MAX_TRAPS];
     62 boolean trap_door = 0;
     63 short bear_trap = 0;
     64 
     65 char *trap_strings[TRAPS * 2] = {
     66 	"trap door",
     67 			"you fell down a trap",
     68 	"bear trap",
     69 			"you are caught in a bear trap",
     70 	"teleport trap",
     71 			"teleport",
     72 	"poison dart trap",
     73 			"a small dart just hit you in the shoulder",
     74 	"sleeping gas trap",
     75 			"a strange white mist envelops you and you fall asleep",
     76 	"rust trap",
     77 			"a gush of water hits you on the head"
     78 };
     79 
     80 extern short cur_level, party_room;
     81 extern char *new_level_message;
     82 extern boolean interrupted;
     83 extern short ring_exp;
     84 extern boolean sustain_strength;
     85 extern short blind;
     86 
     87 trap_at(row, col)
     88 register row, col;
     89 {
     90 	short i;
     91 
     92 	for (i = 0; ((i < MAX_TRAPS) && (traps[i].trap_type != NO_TRAP)); i++) {
     93 		if ((traps[i].trap_row == row) && (traps[i].trap_col == col)) {
     94 			return(traps[i].trap_type);
     95 		}
     96 	}
     97 	return(NO_TRAP);
     98 }
     99 
    100 trap_player(row, col)
    101 short row, col;
    102 {
    103 	short t;
    104 
    105 	if ((t = trap_at(row, col)) == NO_TRAP) {
    106 		return;
    107 	}
    108 	dungeon[row][col] &= (~HIDDEN);
    109 	if (rand_percent(rogue.exp + ring_exp)) {
    110 		message("the trap failed", 1);
    111 		return;
    112 	}
    113 	switch(t) {
    114 	case TRAP_DOOR:
    115 		trap_door = 1;
    116 		new_level_message = trap_strings[(t*2)+1];
    117 		break;
    118 	case BEAR_TRAP:
    119 		message(trap_strings[(t*2)+1], 1);
    120 		bear_trap = get_rand(4, 7);
    121 		break;
    122 	case TELE_TRAP:
    123 		mvaddch(rogue.row, rogue.col, '^');
    124 		tele();
    125 		break;
    126 	case DART_TRAP:
    127 		message(trap_strings[(t*2)+1], 1);
    128 		rogue.hp_current -= get_damage("1d6", 1);
    129 		if (rogue.hp_current <= 0) {
    130 			rogue.hp_current = 0;
    131 		}
    132 		if ((!sustain_strength) && rand_percent(40) &&
    133 			(rogue.str_current >= 3)) {
    134 			rogue.str_current--;
    135 		}
    136 		print_stats(STAT_HP | STAT_STRENGTH);
    137 		if (rogue.hp_current <= 0) {
    138 			killed_by((object *) 0, POISON_DART);
    139 		}
    140 		break;
    141 	case SLEEPING_GAS_TRAP:
    142 		message(trap_strings[(t*2)+1], 1);
    143 		take_a_nap();
    144 		break;
    145 	case RUST_TRAP:
    146 		message(trap_strings[(t*2)+1], 1);
    147 		rust((object *) 0);
    148 		break;
    149 	}
    150 }
    151 
    152 add_traps()
    153 {
    154 	short i, n, tries = 0;
    155 	short row, col;
    156 
    157 	if (cur_level <= 2) {
    158 		n = 0;
    159 	} else if (cur_level <= 7) {
    160 		n = get_rand(0, 2);
    161 	} else if (cur_level <= 11) {
    162 		n = get_rand(1, 2);
    163 	} else if (cur_level <= 16) {
    164 		n = get_rand(2, 3);
    165 	} else if (cur_level <= 21) {
    166 		n = get_rand(2, 4);
    167 	} else if (cur_level <= (AMULET_LEVEL + 2)) {
    168 		n = get_rand(3, 5);
    169 	} else {
    170 		n = get_rand(5, MAX_TRAPS);
    171 	}
    172 	for (i = 0; i < n; i++) {
    173 		traps[i].trap_type = get_rand(0, (TRAPS - 1));
    174 
    175 		if ((i == 0) && (party_room != NO_ROOM)) {
    176 			do {
    177 				row = get_rand((rooms[party_room].top_row+1),
    178 						(rooms[party_room].bottom_row-1));
    179 				col = get_rand((rooms[party_room].left_col+1),
    180 						(rooms[party_room].right_col-1));
    181 				tries++;
    182 			} while (((dungeon[row][col] & (OBJECT|STAIRS|TRAP|TUNNEL)) ||
    183 					(dungeon[row][col] == NOTHING)) && (tries < 15));
    184 			if (tries >= 15) {
    185 				gr_row_col(&row, &col, (FLOOR | MONSTER));
    186 			}
    187 		} else {
    188 			gr_row_col(&row, &col, (FLOOR | MONSTER));
    189 		}
    190 		traps[i].trap_row = row;
    191 		traps[i].trap_col = col;
    192 		dungeon[row][col] |= (TRAP | HIDDEN);
    193 	}
    194 }
    195 
    196 id_trap()
    197 {
    198 	short dir, row, col, d, t;
    199 
    200 	message("direction? ", 0);
    201 
    202 	while (!is_direction(dir = rgetchar(), &d)) {
    203 		sound_bell();
    204 	}
    205 	check_message();
    206 
    207 	if (dir == CANCEL) {
    208 		return;
    209 	}
    210 	row = rogue.row;
    211 	col = rogue.col;
    212 
    213 	get_dir_rc(d, &row, &col, 0);
    214 
    215 	if ((dungeon[row][col] & TRAP) && (!(dungeon[row][col] & HIDDEN))) {
    216 		t = trap_at(row, col);
    217 		message(trap_strings[t*2], 0);
    218 	} else {
    219 		message("no trap there", 0);
    220 	}
    221 }
    222 
    223 show_traps()
    224 {
    225 	short i, j;
    226 
    227 	for (i = 0; i < DROWS; i++) {
    228 		for (j = 0; j < DCOLS; j++) {
    229 			if (dungeon[i][j] & TRAP) {
    230 				mvaddch(i, j, '^');
    231 			}
    232 		}
    233 	}
    234 }
    235 
    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