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