Commit | Line | Data |
---|---|---|
fc3e88fd KB |
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 | * | |
b2e7427f | 8 | * %sccs.include.redist.c% |
fc3e88fd KB |
9 | */ |
10 | ||
11 | #ifndef lint | |
b2e7427f | 12 | static char sccsid[] = "@(#)trap.c 5.3 (Berkeley) %G%"; |
fc3e88fd KB |
13 | #endif /* not lint */ |
14 | ||
b3afadef KB |
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 | ||
b3afadef KB |
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 | } |