1 /* $NetBSD: trap.c,v 1.10 2009/08/12 08:44:45 dholland Exp $ */
2
3 /*
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Timothy C. Stoehr.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #include <sys/cdefs.h>
36 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)trap.c 8.1 (Berkeley) 5/31/93";
39 #else
40 __RCSID("$NetBSD: trap.c,v 1.10 2009/08/12 08:44:45 dholland Exp $");
41 #endif
42 #endif /* not lint */
43
44 /*
45 * trap.c
46 *
47 * This source herein may be modified and/or distributed by anybody who
48 * so desires, with the following restrictions:
49 * 1.) No portion of this notice shall be removed.
50 * 2.) Credit shall not be taken for the creation of this source.
51 * 3.) This code is not to be traded, sold, or used for personal
52 * gain or profit.
53 *
54 */
55
56 #include "rogue.h"
57
58 trap traps[MAX_TRAPS];
59 boolean trap_door = 0;
60 short bear_trap = 0;
61
62 static const char *const trap_strings[TRAPS * 2] = {
63 "trap door",
64 "you fell down a trap",
65 "bear trap",
66 "you are caught in a bear trap",
67 "teleport trap",
68 "teleport",
69 "poison dart trap",
70 "a small dart just hit you in the shoulder",
71 "sleeping gas trap",
72 "a strange white mist envelops you and you fall asleep",
73 "rust trap",
74 "a gush of water hits you on the head"
75 };
76
77 static short
trap_at(int row,int col)78 trap_at(int row, int col)
79 {
80 short i;
81
82 for (i = 0; ((i < MAX_TRAPS) && (traps[i].trap_type != NO_TRAP)); i++) {
83 if ((traps[i].trap_row == row) && (traps[i].trap_col == col)) {
84 return(traps[i].trap_type);
85 }
86 }
87 return(NO_TRAP);
88 }
89
90 void
trap_player(short row,short col)91 trap_player(short row, short col)
92 {
93 short t;
94
95 if ((t = trap_at(row, col)) == NO_TRAP) {
96 return;
97 }
98 dungeon[row][col] &= (~HIDDEN);
99 if (rand_percent(rogue.exp + ring_exp)) {
100 messagef(1, "the trap failed");
101 return;
102 }
103 switch(t) {
104 case TRAP_DOOR:
105 trap_door = 1;
106 new_level_message = trap_strings[(t*2)+1];
107 break;
108 case BEAR_TRAP:
109 messagef(1, "%s", trap_strings[(t*2)+1]);
110 bear_trap = get_rand(4, 7);
111 break;
112 case TELE_TRAP:
113 mvaddch(rogue.row, rogue.col, '^');
114 tele();
115 break;
116 case DART_TRAP:
117 messagef(1, "%s", trap_strings[(t*2)+1]);
118 rogue.hp_current -= get_damage("1d6", 1);
119 if (rogue.hp_current <= 0) {
120 rogue.hp_current = 0;
121 }
122 if ((!sustain_strength) && rand_percent(40) &&
123 (rogue.str_current >= 3)) {
124 rogue.str_current--;
125 }
126 print_stats(STAT_HP | STAT_STRENGTH);
127 if (rogue.hp_current <= 0) {
128 killed_by((object *)0, POISON_DART);
129 }
130 break;
131 case SLEEPING_GAS_TRAP:
132 messagef(1, "%s", trap_strings[(t*2)+1]);
133 take_a_nap();
134 break;
135 case RUST_TRAP:
136 messagef(1, "%s", trap_strings[(t*2)+1]);
137 rust(NULL);
138 break;
139 }
140 }
141
142 void
add_traps(void)143 add_traps(void)
144 {
145 short i, n, tries = 0;
146 short row, col;
147
148 if (cur_level <= 2) {
149 n = 0;
150 } else if (cur_level <= 7) {
151 n = get_rand(0, 2);
152 } else if (cur_level <= 11) {
153 n = get_rand(1, 2);
154 } else if (cur_level <= 16) {
155 n = get_rand(2, 3);
156 } else if (cur_level <= 21) {
157 n = get_rand(2, 4);
158 } else if (cur_level <= (AMULET_LEVEL + 2)) {
159 n = get_rand(3, 5);
160 } else {
161 n = get_rand(5, MAX_TRAPS);
162 }
163 for (i = 0; i < n; i++) {
164 traps[i].trap_type = get_rand(0, (TRAPS - 1));
165
166 if ((i == 0) && (party_room != NO_ROOM)) {
167 do {
168 row = get_rand((rooms[party_room].top_row+1),
169 (rooms[party_room].bottom_row-1));
170 col = get_rand((rooms[party_room].left_col+1),
171 (rooms[party_room].right_col-1));
172 tries++;
173 } while (((dungeon[row][col] & (OBJECT|STAIRS|TRAP|TUNNEL)) ||
174 (dungeon[row][col] == NOTHING)) && (tries < 15));
175 if (tries >= 15) {
176 gr_row_col(&row, &col, (FLOOR | MONSTER));
177 }
178 } else {
179 gr_row_col(&row, &col, (FLOOR | MONSTER));
180 }
181 traps[i].trap_row = row;
182 traps[i].trap_col = col;
183 dungeon[row][col] |= (TRAP | HIDDEN);
184 }
185 }
186
187 void
id_trap(void)188 id_trap(void)
189 {
190 short dir, row, col, d, t;
191
192 messagef(0, "direction? ");
193
194 while (!is_direction(dir = rgetchar(), &d)) {
195 sound_bell();
196 }
197 check_message();
198
199 if (dir == CANCEL) {
200 return;
201 }
202 row = rogue.row;
203 col = rogue.col;
204
205 get_dir_rc(d, &row, &col, 0);
206
207 if ((dungeon[row][col] & TRAP) && (!(dungeon[row][col] & HIDDEN))) {
208 t = trap_at(row, col);
209 messagef(0, "%s", trap_strings[t*2]);
210 } else {
211 messagef(0, "no trap there");
212 }
213 }
214
215 void
show_traps(void)216 show_traps(void)
217 {
218 short i, j;
219
220 for (i = 0; i < DROWS; i++) {
221 for (j = 0; j < DCOLS; j++) {
222 if (dungeon[i][j] & TRAP) {
223 mvaddch(i, j, '^');
224 }
225 }
226 }
227 }
228
229 void
search(short n,boolean is_auto)230 search(short n, boolean is_auto)
231 {
232 short s, i, j, row, col, t;
233 short shown = 0, found = 0;
234 static boolean reg_search;
235
236 for (i = -1; i <= 1; i++) {
237 for (j = -1; j <= 1; j++) {
238 row = rogue.row + i;
239 col = rogue.col + j;
240 if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
241 (col < 0) || (col >= DCOLS)) {
242 continue;
243 }
244 if (dungeon[row][col] & HIDDEN) {
245 found++;
246 }
247 }
248 }
249 for (s = 0; s < n; s++) {
250 for (i = -1; i <= 1; i++) {
251 for (j = -1; j <= 1; j++) {
252 row = rogue.row + i;
253 col = rogue.col + j ;
254 if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
255 (col < 0) || (col >= DCOLS)) {
256 continue;
257 }
258 if (dungeon[row][col] & HIDDEN) {
259 if (rand_percent(17 + (rogue.exp + ring_exp))) {
260 dungeon[row][col] &= (~HIDDEN);
261 if ((!blind) && ((row != rogue.row) ||
262 (col != rogue.col))) {
263 mvaddch(row, col, get_dungeon_char(row, col));
264 }
265 shown++;
266 if (dungeon[row][col] & TRAP) {
267 t = trap_at(row, col);
268 messagef(1, "%s",
269 trap_strings[t*2]);
270 }
271 }
272 }
273 if (((shown == found) && (found > 0)) || interrupted) {
274 return;
275 }
276 }
277 }
278 if ((!is_auto) && (reg_search = !reg_search)) {
279 (void)reg_move();
280 }
281 }
282 }
283