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