386BSD 0.1 development
[unix-history] / usr / othersrc / games / rogue / trap.c
CommitLineData
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
38static 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
55trap traps[MAX_TRAPS];
56boolean trap_door = 0;
57short bear_trap = 0;
58
59char *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
74extern short cur_level, party_room;
75extern char *new_level_message;
76extern boolean interrupted;
77extern short ring_exp;
78extern boolean sustain_strength;
79extern short blind;
80
81trap_at(row, col)
82register 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
94trap_player(row, col)
95short 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
146add_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
190id_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
217show_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
230search(n, is_auto)
231short n;
232boolean 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}