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 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 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 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 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 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 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