Commit | Line | Data |
---|---|---|
6693db17 | 1 | /*- |
984263bc MD |
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 | * 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. | |
6693db17 | 16 | * 3. Neither the name of the University nor the names of its contributors |
984263bc MD |
17 | * may be used to endorse or promote products derived from this software |
18 | * without specific prior written permission. | |
19 | * | |
20 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
30 | * SUCH DAMAGE. | |
1de703da MD |
31 | * |
32 | * @(#)trap.c 8.1 (Berkeley) 5/31/93 | |
33 | * $FreeBSD: src/games/rogue/trap.c,v 1.6 1999/11/30 03:49:28 billf Exp $ | |
b28e2a8f | 34 | * $DragonFly: src/games/rogue/trap.c,v 1.3 2006/09/02 19:31:07 pavalos Exp $ |
984263bc MD |
35 | */ |
36 | ||
984263bc MD |
37 | /* |
38 | * trap.c | |
39 | * | |
40 | * This source herein may be modified and/or distributed by anybody who | |
41 | * so desires, with the following restrictions: | |
42 | * 1.) No portion of this notice shall be removed. | |
43 | * 2.) Credit shall not be taken for the creation of this source. | |
44 | * 3.) This code is not to be traded, sold, or used for personal | |
45 | * gain or profit. | |
46 | * | |
47 | */ | |
48 | ||
49 | #include "rogue.h" | |
50 | ||
51 | trap traps[MAX_TRAPS]; | |
52 | boolean trap_door = 0; | |
53 | short bear_trap = 0; | |
54 | ||
55 | const char *const trap_strings[TRAPS * 2] = { | |
56 | "trap door", | |
57 | "you fell down a trap", | |
58 | "bear trap", | |
59 | "you are caught in a bear trap", | |
60 | "teleport trap", | |
61 | "teleport", | |
62 | "poison dart trap", | |
63 | "a small dart just hit you in the shoulder", | |
64 | "sleeping gas trap", | |
65 | "a strange white mist envelops you and you fall asleep", | |
66 | "rust trap", | |
67 | "a gush of water hits you on the head" | |
68 | }; | |
69 | ||
70 | extern short cur_level, party_room; | |
71 | extern const char *new_level_message; | |
72 | extern boolean interrupted; | |
73 | extern short ring_exp; | |
74 | extern boolean sustain_strength; | |
75 | extern short blind; | |
76 | ||
6693db17 | 77 | static short trap_at(int, int); |
b28e2a8f PA |
78 | |
79 | static short | |
80 | trap_at(int row, int col) | |
984263bc MD |
81 | { |
82 | short i; | |
83 | ||
84 | for (i = 0; ((i < MAX_TRAPS) && (traps[i].trap_type != NO_TRAP)); i++) { | |
85 | if ((traps[i].trap_row == row) && (traps[i].trap_col == col)) { | |
86 | return(traps[i].trap_type); | |
87 | } | |
88 | } | |
89 | return(NO_TRAP); | |
90 | } | |
91 | ||
b28e2a8f PA |
92 | void |
93 | trap_player(short row, short col) | |
984263bc MD |
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 | message("the trap failed", 1); | |
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 | message(trap_strings[(t*2)+1], 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 | message(trap_strings[(t*2)+1], 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) { | |
902ec341 | 130 | killed_by(NULL, POISON_DART); |
984263bc MD |
131 | } |
132 | break; | |
133 | case SLEEPING_GAS_TRAP: | |
134 | message(trap_strings[(t*2)+1], 1); | |
135 | take_a_nap(); | |
136 | break; | |
137 | case RUST_TRAP: | |
138 | message(trap_strings[(t*2)+1], 1); | |
902ec341 | 139 | rust(NULL); |
984263bc MD |
140 | break; |
141 | } | |
142 | } | |
143 | ||
b28e2a8f PA |
144 | void |
145 | add_traps(void) | |
984263bc MD |
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 | ||
b28e2a8f PA |
189 | void |
190 | id_trap(void) | |
984263bc MD |
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 | ||
b28e2a8f PA |
217 | void |
218 | show_traps(void) | |
984263bc MD |
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 | ||
b28e2a8f PA |
231 | void |
232 | search(short n, boolean is_auto) | |
984263bc MD |
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)) { | |
b28e2a8f | 280 | reg_move(); |
984263bc MD |
281 | } |
282 | } | |
283 | } |