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