132689Sbostic /*
2*60842Sbostic * Copyright (c) 1988, 1993
3*60842Sbostic * The Regents of the University of California. All rights reserved.
436704Sbostic *
536704Sbostic * This code is derived from software contributed to Berkeley by
636704Sbostic * Timothy C. Stoehr.
736704Sbostic *
842604Sbostic * %sccs.include.redist.c%
936704Sbostic */
1036704Sbostic
1136704Sbostic #ifndef lint
12*60842Sbostic static char sccsid[] = "@(#)trap.c 8.1 (Berkeley) 05/31/93";
1336704Sbostic #endif /* not lint */
1436704Sbostic
1536704Sbostic /*
1632689Sbostic * trap.c
1732689Sbostic *
1832689Sbostic * This source herein may be modified and/or distributed by anybody who
1932689Sbostic * so desires, with the following restrictions:
2032689Sbostic * 1.) No portion of this notice shall be removed.
2132689Sbostic * 2.) Credit shall not be taken for the creation of this source.
2232689Sbostic * 3.) This code is not to be traded, sold, or used for personal
2332689Sbostic * gain or profit.
2432689Sbostic *
2532689Sbostic */
2632689Sbostic
2732689Sbostic #include "rogue.h"
2832689Sbostic
2932689Sbostic trap traps[MAX_TRAPS];
3032689Sbostic boolean trap_door = 0;
3132689Sbostic short bear_trap = 0;
3232689Sbostic
3332689Sbostic char *trap_strings[TRAPS * 2] = {
3432689Sbostic "trap door",
3532689Sbostic "you fell down a trap",
3632689Sbostic "bear trap",
3732689Sbostic "you are caught in a bear trap",
3832689Sbostic "teleport trap",
3932689Sbostic "teleport",
4032689Sbostic "poison dart trap",
4132689Sbostic "a small dart just hit you in the shoulder",
4232689Sbostic "sleeping gas trap",
4332689Sbostic "a strange white mist envelops you and you fall asleep",
4432689Sbostic "rust trap",
4532689Sbostic "a gush of water hits you on the head"
4632689Sbostic };
4732689Sbostic
4832689Sbostic extern short cur_level, party_room;
4932689Sbostic extern char *new_level_message;
5032689Sbostic extern boolean interrupted;
5132689Sbostic extern short ring_exp;
5232689Sbostic extern boolean sustain_strength;
5332689Sbostic extern short blind;
5432689Sbostic
trap_at(row,col)5532689Sbostic trap_at(row, col)
5632689Sbostic register row, col;
5732689Sbostic {
5832689Sbostic short i;
5932689Sbostic
6032689Sbostic for (i = 0; ((i < MAX_TRAPS) && (traps[i].trap_type != NO_TRAP)); i++) {
6132689Sbostic if ((traps[i].trap_row == row) && (traps[i].trap_col == col)) {
6232689Sbostic return(traps[i].trap_type);
6332689Sbostic }
6432689Sbostic }
6532689Sbostic return(NO_TRAP);
6632689Sbostic }
6732689Sbostic
trap_player(row,col)6832689Sbostic trap_player(row, col)
6932689Sbostic short row, col;
7032689Sbostic {
7132689Sbostic short t;
7232689Sbostic
7332689Sbostic if ((t = trap_at(row, col)) == NO_TRAP) {
7432689Sbostic return;
7532689Sbostic }
7632689Sbostic dungeon[row][col] &= (~HIDDEN);
7732689Sbostic if (rand_percent(rogue.exp + ring_exp)) {
7832689Sbostic message("the trap failed", 1);
7932689Sbostic return;
8032689Sbostic }
8132689Sbostic switch(t) {
8232689Sbostic case TRAP_DOOR:
8332689Sbostic trap_door = 1;
8432689Sbostic new_level_message = trap_strings[(t*2)+1];
8532689Sbostic break;
8632689Sbostic case BEAR_TRAP:
8732689Sbostic message(trap_strings[(t*2)+1], 1);
8832689Sbostic bear_trap = get_rand(4, 7);
8932689Sbostic break;
9032689Sbostic case TELE_TRAP:
9132689Sbostic mvaddch(rogue.row, rogue.col, '^');
9232689Sbostic tele();
9332689Sbostic break;
9432689Sbostic case DART_TRAP:
9532689Sbostic message(trap_strings[(t*2)+1], 1);
9632689Sbostic rogue.hp_current -= get_damage("1d6", 1);
9732689Sbostic if (rogue.hp_current <= 0) {
9832689Sbostic rogue.hp_current = 0;
9932689Sbostic }
10032689Sbostic if ((!sustain_strength) && rand_percent(40) &&
10132689Sbostic (rogue.str_current >= 3)) {
10232689Sbostic rogue.str_current--;
10332689Sbostic }
10432689Sbostic print_stats(STAT_HP | STAT_STRENGTH);
10532689Sbostic if (rogue.hp_current <= 0) {
10632689Sbostic killed_by((object *) 0, POISON_DART);
10732689Sbostic }
10832689Sbostic break;
10932689Sbostic case SLEEPING_GAS_TRAP:
11032689Sbostic message(trap_strings[(t*2)+1], 1);
11132689Sbostic take_a_nap();
11232689Sbostic break;
11332689Sbostic case RUST_TRAP:
11432689Sbostic message(trap_strings[(t*2)+1], 1);
11532689Sbostic rust((object *) 0);
11632689Sbostic break;
11732689Sbostic }
11832689Sbostic }
11932689Sbostic
add_traps()12032689Sbostic add_traps()
12132689Sbostic {
12232689Sbostic short i, n, tries = 0;
12332689Sbostic short row, col;
12432689Sbostic
12532689Sbostic if (cur_level <= 2) {
12632689Sbostic n = 0;
12732689Sbostic } else if (cur_level <= 7) {
12832689Sbostic n = get_rand(0, 2);
12932689Sbostic } else if (cur_level <= 11) {
13032689Sbostic n = get_rand(1, 2);
13132689Sbostic } else if (cur_level <= 16) {
13232689Sbostic n = get_rand(2, 3);
13332689Sbostic } else if (cur_level <= 21) {
13432689Sbostic n = get_rand(2, 4);
13532689Sbostic } else if (cur_level <= (AMULET_LEVEL + 2)) {
13632689Sbostic n = get_rand(3, 5);
13732689Sbostic } else {
13832689Sbostic n = get_rand(5, MAX_TRAPS);
13932689Sbostic }
14032689Sbostic for (i = 0; i < n; i++) {
14132689Sbostic traps[i].trap_type = get_rand(0, (TRAPS - 1));
14232689Sbostic
14332689Sbostic if ((i == 0) && (party_room != NO_ROOM)) {
14432689Sbostic do {
14532689Sbostic row = get_rand((rooms[party_room].top_row+1),
14632689Sbostic (rooms[party_room].bottom_row-1));
14732689Sbostic col = get_rand((rooms[party_room].left_col+1),
14832689Sbostic (rooms[party_room].right_col-1));
14932689Sbostic tries++;
15032689Sbostic } while (((dungeon[row][col] & (OBJECT|STAIRS|TRAP|TUNNEL)) ||
15132689Sbostic (dungeon[row][col] == NOTHING)) && (tries < 15));
15232689Sbostic if (tries >= 15) {
15332689Sbostic gr_row_col(&row, &col, (FLOOR | MONSTER));
15432689Sbostic }
15532689Sbostic } else {
15632689Sbostic gr_row_col(&row, &col, (FLOOR | MONSTER));
15732689Sbostic }
15832689Sbostic traps[i].trap_row = row;
15932689Sbostic traps[i].trap_col = col;
16032689Sbostic dungeon[row][col] |= (TRAP | HIDDEN);
16132689Sbostic }
16232689Sbostic }
16332689Sbostic
id_trap()16432689Sbostic id_trap()
16532689Sbostic {
16632689Sbostic short dir, row, col, d, t;
16732689Sbostic
16832689Sbostic message("direction? ", 0);
16932689Sbostic
17032689Sbostic while (!is_direction(dir = rgetchar(), &d)) {
17132689Sbostic sound_bell();
17232689Sbostic }
17332689Sbostic check_message();
17432689Sbostic
17532689Sbostic if (dir == CANCEL) {
17632689Sbostic return;
17732689Sbostic }
17832689Sbostic row = rogue.row;
17932689Sbostic col = rogue.col;
18032689Sbostic
18132689Sbostic get_dir_rc(d, &row, &col, 0);
18232689Sbostic
18332689Sbostic if ((dungeon[row][col] & TRAP) && (!(dungeon[row][col] & HIDDEN))) {
18432689Sbostic t = trap_at(row, col);
18532689Sbostic message(trap_strings[t*2], 0);
18632689Sbostic } else {
18732689Sbostic message("no trap there", 0);
18832689Sbostic }
18932689Sbostic }
19032689Sbostic
show_traps()19132689Sbostic show_traps()
19232689Sbostic {
19332689Sbostic short i, j;
19432689Sbostic
19532689Sbostic for (i = 0; i < DROWS; i++) {
19632689Sbostic for (j = 0; j < DCOLS; j++) {
19732689Sbostic if (dungeon[i][j] & TRAP) {
19832689Sbostic mvaddch(i, j, '^');
19932689Sbostic }
20032689Sbostic }
20132689Sbostic }
20232689Sbostic }
20332689Sbostic
search(n,is_auto)20432689Sbostic search(n, is_auto)
20532689Sbostic short n;
20632689Sbostic boolean is_auto;
20732689Sbostic {
20832689Sbostic short s, i, j, row, col, t;
20932689Sbostic short shown = 0, found = 0;
21032689Sbostic static boolean reg_search;
21132689Sbostic
21232689Sbostic for (i = -1; i <= 1; i++) {
21332689Sbostic for (j = -1; j <= 1; j++) {
21432689Sbostic row = rogue.row + i;
21532689Sbostic col = rogue.col + j;
21632689Sbostic if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
21732689Sbostic (col < 0) || (col >= DCOLS)) {
21832689Sbostic continue;
21932689Sbostic }
22032689Sbostic if (dungeon[row][col] & HIDDEN) {
22132689Sbostic found++;
22232689Sbostic }
22332689Sbostic }
22432689Sbostic }
22532689Sbostic for (s = 0; s < n; s++) {
22632689Sbostic for (i = -1; i <= 1; i++) {
22732689Sbostic for (j = -1; j <= 1; j++) {
22832689Sbostic row = rogue.row + i;
22932689Sbostic col = rogue.col + j ;
23032689Sbostic if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
23132689Sbostic (col < 0) || (col >= DCOLS)) {
23232689Sbostic continue;
23332689Sbostic }
23432689Sbostic if (dungeon[row][col] & HIDDEN) {
23532689Sbostic if (rand_percent(17 + (rogue.exp + ring_exp))) {
23632689Sbostic dungeon[row][col] &= (~HIDDEN);
23732689Sbostic if ((!blind) && ((row != rogue.row) ||
23832689Sbostic (col != rogue.col))) {
23932689Sbostic mvaddch(row, col, get_dungeon_char(row, col));
24032689Sbostic }
24132689Sbostic shown++;
24232689Sbostic if (dungeon[row][col] & TRAP) {
24332689Sbostic t = trap_at(row, col);
24432689Sbostic message(trap_strings[t*2], 1);
24532689Sbostic }
24632689Sbostic }
24732689Sbostic }
24832689Sbostic if (((shown == found) && (found > 0)) || interrupted) {
24932689Sbostic return;
25032689Sbostic }
25132689Sbostic }
25232689Sbostic }
25332689Sbostic if ((!is_auto) && (reg_search = !reg_search)) {
25432689Sbostic (void) reg_move();
25532689Sbostic }
25632689Sbostic }
25732689Sbostic }
258