Commit | Line | Data |
---|---|---|
8bb0f55f WJ |
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 | } |