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