Add efidev.4 and efirt.9 manual pages from FreeBSD.
[dragonfly.git] / games / rogue / trap.c
1 /*-
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.
16  * 3. Neither the name of the University nor the names of its contributors
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.
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 $
34  */
35
36 /*
37  * trap.c
38  *
39  * This source herein may be modified and/or distributed by anybody who
40  * so desires, with the following restrictions:
41  *    1.)  No portion of this notice shall be removed.
42  *    2.)  Credit shall not be taken for the creation of this source.
43  *    3.)  This code is not to be traded, sold, or used for personal
44  *         gain or profit.
45  *
46  */
47
48 #include "rogue.h"
49
50 trap traps[MAX_TRAPS];
51 boolean trap_door = 0;
52 short bear_trap = 0;
53
54 static const char *const trap_strings[TRAPS * 2] = {
55         "trap door",
56                         "you fell down a trap",
57         "bear trap",
58                         "you are caught in a bear trap",
59         "teleport trap",
60                         "teleport",
61         "poison dart trap",
62                         "a small dart just hit you in the shoulder",
63         "sleeping gas trap",
64                         "a strange white mist envelops you and you fall asleep",
65         "rust trap",
66                         "a gush of water hits you on the head"
67 };
68
69 static short
70 trap_at(int row, int col)
71 {
72         short i;
73
74         for (i = 0; ((i < MAX_TRAPS) && (traps[i].trap_type != NO_TRAP)); i++) {
75                 if ((traps[i].trap_row == row) && (traps[i].trap_col == col)) {
76                         return(traps[i].trap_type);
77                 }
78         }
79         return(NO_TRAP);
80 }
81
82 void
83 trap_player(short row, short col)
84 {
85         short t;
86
87         if ((t = trap_at(row, col)) == NO_TRAP) {
88                 return;
89         }
90         dungeon[row][col] &= (~HIDDEN);
91         if (rand_percent(rogue.exp + ring_exp)) {
92                 message("the trap failed", 1);
93                 return;
94         }
95         switch(t) {
96         case TRAP_DOOR:
97                 trap_door = 1;
98                 new_level_message = trap_strings[(t*2)+1];
99                 break;
100         case BEAR_TRAP:
101                 message(trap_strings[(t*2)+1], 1);
102                 bear_trap = get_rand(4, 7);
103                 break;
104         case TELE_TRAP:
105                 mvaddch(rogue.row, rogue.col, '^');
106                 tele();
107                 break;
108         case DART_TRAP:
109                 message(trap_strings[(t*2)+1], 1);
110                 rogue.hp_current -= get_damage("1d6", 1);
111                 if (rogue.hp_current <= 0) {
112                         rogue.hp_current = 0;
113                 }
114                 if ((!sustain_strength) && rand_percent(40) &&
115                         (rogue.str_current >= 3)) {
116                         rogue.str_current--;
117                 }
118                 print_stats(STAT_HP | STAT_STRENGTH);
119                 if (rogue.hp_current <= 0) {
120                         killed_by(NULL, POISON_DART);
121                 }
122                 break;
123         case SLEEPING_GAS_TRAP:
124                 message(trap_strings[(t*2)+1], 1);
125                 take_a_nap();
126                 break;
127         case RUST_TRAP:
128                 message(trap_strings[(t*2)+1], 1);
129                 rust(NULL);
130                 break;
131         }
132 }
133
134 void
135 add_traps(void)
136 {
137         short i, n, tries = 0;
138         short row, col;
139
140         if (cur_level <= 2) {
141                 n = 0;
142         } else if (cur_level <= 7) {
143                 n = get_rand(0, 2);
144         } else if (cur_level <= 11) {
145                 n = get_rand(1, 2);
146         } else if (cur_level <= 16) {
147                 n = get_rand(2, 3);
148         } else if (cur_level <= 21) {
149                 n = get_rand(2, 4);
150         } else if (cur_level <= (AMULET_LEVEL + 2)) {
151                 n = get_rand(3, 5);
152         } else {
153                 n = get_rand(5, MAX_TRAPS);
154         }
155         for (i = 0; i < n; i++) {
156                 traps[i].trap_type = get_rand(0, (TRAPS - 1));
157
158                 if ((i == 0) && (party_room != NO_ROOM)) {
159                         do {
160                                 row = get_rand((rooms[party_room].top_row+1),
161                                                 (rooms[party_room].bottom_row-1));
162                                 col = get_rand((rooms[party_room].left_col+1),
163                                                 (rooms[party_room].right_col-1));
164                                 tries++;
165                         } while (((dungeon[row][col] & (OBJECT|STAIRS|TRAP|TUNNEL)) ||
166                                         (dungeon[row][col] == NOTHING)) && (tries < 15));
167                         if (tries >= 15) {
168                                 gr_row_col(&row, &col, (FLOOR | MONSTER));
169                         }
170                 } else {
171                         gr_row_col(&row, &col, (FLOOR | MONSTER));
172                 }
173                 traps[i].trap_row = row;
174                 traps[i].trap_col = col;
175                 dungeon[row][col] |= (TRAP | HIDDEN);
176         }
177 }
178
179 void
180 id_trap(void)
181 {
182         short dir, row, col, d, t;
183
184         message("direction? ", 0);
185
186         while (!is_direction(dir = rgetchar(), &d)) {
187                 sound_bell();
188         }
189         check_message();
190
191         if (dir == CANCEL) {
192                 return;
193         }
194         row = rogue.row;
195         col = rogue.col;
196
197         get_dir_rc(d, &row, &col, 0);
198
199         if ((dungeon[row][col] & TRAP) && (!(dungeon[row][col] & HIDDEN))) {
200                 t = trap_at(row, col);
201                 message(trap_strings[t*2], 0);
202         } else {
203                 message("no trap there", 0);
204         }
205 }
206
207 void
208 show_traps(void)
209 {
210         short i, j;
211
212         for (i = 0; i < DROWS; i++) {
213                 for (j = 0; j < DCOLS; j++) {
214                         if (dungeon[i][j] & TRAP) {
215                                 mvaddch(i, j, '^');
216                         }
217                 }
218         }
219 }
220
221 void
222 search(short n, boolean is_auto)
223 {
224         short s, i, j, row, col, t;
225         short shown = 0, found = 0;
226         static boolean reg_search;
227
228         for (i = -1; i <= 1; i++) {
229                 for (j = -1; j <= 1; j++) {
230                         row = rogue.row + i;
231                         col = rogue.col + j;
232                         if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
233                                         (col < 0) || (col >= DCOLS)) {
234                                 continue;
235                         }
236                         if (dungeon[row][col] & HIDDEN) {
237                                 found++;
238                         }
239                 }
240         }
241         for (s = 0; s < n; s++) {
242                 for (i = -1; i <= 1; i++) {
243                         for (j = -1; j <= 1; j++) {
244                                 row = rogue.row + i;
245                                 col = rogue.col + j ;
246                                 if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
247                                                 (col < 0) || (col >= DCOLS)) {
248                                         continue;
249                                 }
250                                 if (dungeon[row][col] & HIDDEN) {
251                                         if (rand_percent(17 + (rogue.exp + ring_exp))) {
252                                                 dungeon[row][col] &= (~HIDDEN);
253                                                 if ((!blind) && ((row != rogue.row) ||
254                                                                 (col != rogue.col))) {
255                                                         mvaddch(row, col, get_dungeon_char(row, col));
256                                                 }
257                                                 shown++;
258                                                 if (dungeon[row][col] & TRAP) {
259                                                         t = trap_at(row, col);
260                                                         message(trap_strings[t*2], 1);
261                                                 }
262                                         }
263                                 }
264                                 if (((shown == found) && (found > 0)) || interrupted) {
265                                         return;
266                                 }
267                         }
268                 }
269                 if ((!is_auto) && (reg_search = !reg_search)) {
270                         reg_move();
271                 }
272         }
273 }