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