xref: /csrg-svn/games/rogue/trap.c (revision 60842)
132689Sbostic /*
2*60842Sbostic  * Copyright (c) 1988, 1993
3*60842Sbostic  *	The Regents of the University of California.  All rights reserved.
436704Sbostic  *
536704Sbostic  * This code is derived from software contributed to Berkeley by
636704Sbostic  * Timothy C. Stoehr.
736704Sbostic  *
842604Sbostic  * %sccs.include.redist.c%
936704Sbostic  */
1036704Sbostic 
1136704Sbostic #ifndef lint
12*60842Sbostic static char sccsid[] = "@(#)trap.c	8.1 (Berkeley) 05/31/93";
1336704Sbostic #endif /* not lint */
1436704Sbostic 
1536704Sbostic /*
1632689Sbostic  * trap.c
1732689Sbostic  *
1832689Sbostic  * This source herein may be modified and/or distributed by anybody who
1932689Sbostic  * so desires, with the following restrictions:
2032689Sbostic  *    1.)  No portion of this notice shall be removed.
2132689Sbostic  *    2.)  Credit shall not be taken for the creation of this source.
2232689Sbostic  *    3.)  This code is not to be traded, sold, or used for personal
2332689Sbostic  *         gain or profit.
2432689Sbostic  *
2532689Sbostic  */
2632689Sbostic 
2732689Sbostic #include "rogue.h"
2832689Sbostic 
2932689Sbostic trap traps[MAX_TRAPS];
3032689Sbostic boolean trap_door = 0;
3132689Sbostic short bear_trap = 0;
3232689Sbostic 
3332689Sbostic char *trap_strings[TRAPS * 2] = {
3432689Sbostic 	"trap door",
3532689Sbostic 			"you fell down a trap",
3632689Sbostic 	"bear trap",
3732689Sbostic 			"you are caught in a bear trap",
3832689Sbostic 	"teleport trap",
3932689Sbostic 			"teleport",
4032689Sbostic 	"poison dart trap",
4132689Sbostic 			"a small dart just hit you in the shoulder",
4232689Sbostic 	"sleeping gas trap",
4332689Sbostic 			"a strange white mist envelops you and you fall asleep",
4432689Sbostic 	"rust trap",
4532689Sbostic 			"a gush of water hits you on the head"
4632689Sbostic };
4732689Sbostic 
4832689Sbostic extern short cur_level, party_room;
4932689Sbostic extern char *new_level_message;
5032689Sbostic extern boolean interrupted;
5132689Sbostic extern short ring_exp;
5232689Sbostic extern boolean sustain_strength;
5332689Sbostic extern short blind;
5432689Sbostic 
trap_at(row,col)5532689Sbostic trap_at(row, col)
5632689Sbostic register row, col;
5732689Sbostic {
5832689Sbostic 	short i;
5932689Sbostic 
6032689Sbostic 	for (i = 0; ((i < MAX_TRAPS) && (traps[i].trap_type != NO_TRAP)); i++) {
6132689Sbostic 		if ((traps[i].trap_row == row) && (traps[i].trap_col == col)) {
6232689Sbostic 			return(traps[i].trap_type);
6332689Sbostic 		}
6432689Sbostic 	}
6532689Sbostic 	return(NO_TRAP);
6632689Sbostic }
6732689Sbostic 
trap_player(row,col)6832689Sbostic trap_player(row, col)
6932689Sbostic short row, col;
7032689Sbostic {
7132689Sbostic 	short t;
7232689Sbostic 
7332689Sbostic 	if ((t = trap_at(row, col)) == NO_TRAP) {
7432689Sbostic 		return;
7532689Sbostic 	}
7632689Sbostic 	dungeon[row][col] &= (~HIDDEN);
7732689Sbostic 	if (rand_percent(rogue.exp + ring_exp)) {
7832689Sbostic 		message("the trap failed", 1);
7932689Sbostic 		return;
8032689Sbostic 	}
8132689Sbostic 	switch(t) {
8232689Sbostic 	case TRAP_DOOR:
8332689Sbostic 		trap_door = 1;
8432689Sbostic 		new_level_message = trap_strings[(t*2)+1];
8532689Sbostic 		break;
8632689Sbostic 	case BEAR_TRAP:
8732689Sbostic 		message(trap_strings[(t*2)+1], 1);
8832689Sbostic 		bear_trap = get_rand(4, 7);
8932689Sbostic 		break;
9032689Sbostic 	case TELE_TRAP:
9132689Sbostic 		mvaddch(rogue.row, rogue.col, '^');
9232689Sbostic 		tele();
9332689Sbostic 		break;
9432689Sbostic 	case DART_TRAP:
9532689Sbostic 		message(trap_strings[(t*2)+1], 1);
9632689Sbostic 		rogue.hp_current -= get_damage("1d6", 1);
9732689Sbostic 		if (rogue.hp_current <= 0) {
9832689Sbostic 			rogue.hp_current = 0;
9932689Sbostic 		}
10032689Sbostic 		if ((!sustain_strength) && rand_percent(40) &&
10132689Sbostic 			(rogue.str_current >= 3)) {
10232689Sbostic 			rogue.str_current--;
10332689Sbostic 		}
10432689Sbostic 		print_stats(STAT_HP | STAT_STRENGTH);
10532689Sbostic 		if (rogue.hp_current <= 0) {
10632689Sbostic 			killed_by((object *) 0, POISON_DART);
10732689Sbostic 		}
10832689Sbostic 		break;
10932689Sbostic 	case SLEEPING_GAS_TRAP:
11032689Sbostic 		message(trap_strings[(t*2)+1], 1);
11132689Sbostic 		take_a_nap();
11232689Sbostic 		break;
11332689Sbostic 	case RUST_TRAP:
11432689Sbostic 		message(trap_strings[(t*2)+1], 1);
11532689Sbostic 		rust((object *) 0);
11632689Sbostic 		break;
11732689Sbostic 	}
11832689Sbostic }
11932689Sbostic 
add_traps()12032689Sbostic add_traps()
12132689Sbostic {
12232689Sbostic 	short i, n, tries = 0;
12332689Sbostic 	short row, col;
12432689Sbostic 
12532689Sbostic 	if (cur_level <= 2) {
12632689Sbostic 		n = 0;
12732689Sbostic 	} else if (cur_level <= 7) {
12832689Sbostic 		n = get_rand(0, 2);
12932689Sbostic 	} else if (cur_level <= 11) {
13032689Sbostic 		n = get_rand(1, 2);
13132689Sbostic 	} else if (cur_level <= 16) {
13232689Sbostic 		n = get_rand(2, 3);
13332689Sbostic 	} else if (cur_level <= 21) {
13432689Sbostic 		n = get_rand(2, 4);
13532689Sbostic 	} else if (cur_level <= (AMULET_LEVEL + 2)) {
13632689Sbostic 		n = get_rand(3, 5);
13732689Sbostic 	} else {
13832689Sbostic 		n = get_rand(5, MAX_TRAPS);
13932689Sbostic 	}
14032689Sbostic 	for (i = 0; i < n; i++) {
14132689Sbostic 		traps[i].trap_type = get_rand(0, (TRAPS - 1));
14232689Sbostic 
14332689Sbostic 		if ((i == 0) && (party_room != NO_ROOM)) {
14432689Sbostic 			do {
14532689Sbostic 				row = get_rand((rooms[party_room].top_row+1),
14632689Sbostic 						(rooms[party_room].bottom_row-1));
14732689Sbostic 				col = get_rand((rooms[party_room].left_col+1),
14832689Sbostic 						(rooms[party_room].right_col-1));
14932689Sbostic 				tries++;
15032689Sbostic 			} while (((dungeon[row][col] & (OBJECT|STAIRS|TRAP|TUNNEL)) ||
15132689Sbostic 					(dungeon[row][col] == NOTHING)) && (tries < 15));
15232689Sbostic 			if (tries >= 15) {
15332689Sbostic 				gr_row_col(&row, &col, (FLOOR | MONSTER));
15432689Sbostic 			}
15532689Sbostic 		} else {
15632689Sbostic 			gr_row_col(&row, &col, (FLOOR | MONSTER));
15732689Sbostic 		}
15832689Sbostic 		traps[i].trap_row = row;
15932689Sbostic 		traps[i].trap_col = col;
16032689Sbostic 		dungeon[row][col] |= (TRAP | HIDDEN);
16132689Sbostic 	}
16232689Sbostic }
16332689Sbostic 
id_trap()16432689Sbostic id_trap()
16532689Sbostic {
16632689Sbostic 	short dir, row, col, d, t;
16732689Sbostic 
16832689Sbostic 	message("direction? ", 0);
16932689Sbostic 
17032689Sbostic 	while (!is_direction(dir = rgetchar(), &d)) {
17132689Sbostic 		sound_bell();
17232689Sbostic 	}
17332689Sbostic 	check_message();
17432689Sbostic 
17532689Sbostic 	if (dir == CANCEL) {
17632689Sbostic 		return;
17732689Sbostic 	}
17832689Sbostic 	row = rogue.row;
17932689Sbostic 	col = rogue.col;
18032689Sbostic 
18132689Sbostic 	get_dir_rc(d, &row, &col, 0);
18232689Sbostic 
18332689Sbostic 	if ((dungeon[row][col] & TRAP) && (!(dungeon[row][col] & HIDDEN))) {
18432689Sbostic 		t = trap_at(row, col);
18532689Sbostic 		message(trap_strings[t*2], 0);
18632689Sbostic 	} else {
18732689Sbostic 		message("no trap there", 0);
18832689Sbostic 	}
18932689Sbostic }
19032689Sbostic 
show_traps()19132689Sbostic show_traps()
19232689Sbostic {
19332689Sbostic 	short i, j;
19432689Sbostic 
19532689Sbostic 	for (i = 0; i < DROWS; i++) {
19632689Sbostic 		for (j = 0; j < DCOLS; j++) {
19732689Sbostic 			if (dungeon[i][j] & TRAP) {
19832689Sbostic 				mvaddch(i, j, '^');
19932689Sbostic 			}
20032689Sbostic 		}
20132689Sbostic 	}
20232689Sbostic }
20332689Sbostic 
search(n,is_auto)20432689Sbostic search(n, is_auto)
20532689Sbostic short n;
20632689Sbostic boolean is_auto;
20732689Sbostic {
20832689Sbostic 	short s, i, j, row, col, t;
20932689Sbostic 	short shown = 0, found = 0;
21032689Sbostic 	static boolean reg_search;
21132689Sbostic 
21232689Sbostic 	for (i = -1; i <= 1; i++) {
21332689Sbostic 		for (j = -1; j <= 1; j++) {
21432689Sbostic 			row = rogue.row + i;
21532689Sbostic 			col = rogue.col + j;
21632689Sbostic 			if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
21732689Sbostic 					(col < 0) || (col >= DCOLS)) {
21832689Sbostic 				continue;
21932689Sbostic 			}
22032689Sbostic 			if (dungeon[row][col] & HIDDEN) {
22132689Sbostic 				found++;
22232689Sbostic 			}
22332689Sbostic 		}
22432689Sbostic 	}
22532689Sbostic 	for (s = 0; s < n; s++) {
22632689Sbostic 		for (i = -1; i <= 1; i++) {
22732689Sbostic 			for (j = -1; j <= 1; j++) {
22832689Sbostic 				row = rogue.row + i;
22932689Sbostic 				col = rogue.col + j ;
23032689Sbostic 				if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
23132689Sbostic 						(col < 0) || (col >= DCOLS)) {
23232689Sbostic 					continue;
23332689Sbostic 				}
23432689Sbostic 				if (dungeon[row][col] & HIDDEN) {
23532689Sbostic 					if (rand_percent(17 + (rogue.exp + ring_exp))) {
23632689Sbostic 						dungeon[row][col] &= (~HIDDEN);
23732689Sbostic 						if ((!blind) && ((row != rogue.row) ||
23832689Sbostic 								(col != rogue.col))) {
23932689Sbostic 							mvaddch(row, col, get_dungeon_char(row, col));
24032689Sbostic 						}
24132689Sbostic 						shown++;
24232689Sbostic 						if (dungeon[row][col] & TRAP) {
24332689Sbostic 							t = trap_at(row, col);
24432689Sbostic 							message(trap_strings[t*2], 1);
24532689Sbostic 						}
24632689Sbostic 					}
24732689Sbostic 				}
24832689Sbostic 				if (((shown == found) && (found > 0)) || interrupted) {
24932689Sbostic 					return;
25032689Sbostic 				}
25132689Sbostic 			}
25232689Sbostic 		}
25332689Sbostic 		if ((!is_auto) && (reg_search = !reg_search)) {
25432689Sbostic 			(void) reg_move();
25532689Sbostic 		}
25632689Sbostic 	}
25732689Sbostic }
258