132689Sbostic /* 2*36704Sbostic * Copyright (c) 1988 The Regents of the University of California. 3*36704Sbostic * All rights reserved. 4*36704Sbostic * 5*36704Sbostic * This code is derived from software contributed to Berkeley by 6*36704Sbostic * Timothy C. Stoehr. 7*36704Sbostic * 8*36704Sbostic * Redistribution and use in source and binary forms are permitted 9*36704Sbostic * provided that the above copyright notice and this paragraph are 10*36704Sbostic * duplicated in all such forms and that any documentation, 11*36704Sbostic * advertising materials, and other materials related to such 12*36704Sbostic * distribution and use acknowledge that the software was developed 13*36704Sbostic * by the University of California, Berkeley. The name of the 14*36704Sbostic * University may not be used to endorse or promote products derived 15*36704Sbostic * from this software without specific prior written permission. 16*36704Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17*36704Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18*36704Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19*36704Sbostic */ 20*36704Sbostic 21*36704Sbostic #ifndef lint 22*36704Sbostic static char sccsid[] = "@(#)move.c 5.2 (Berkeley) 02/07/89"; 23*36704Sbostic #endif /* not lint */ 24*36704Sbostic 25*36704Sbostic /* 2632689Sbostic * move.c 2732689Sbostic * 2832689Sbostic * This source herein may be modified and/or distributed by anybody who 2932689Sbostic * so desires, with the following restrictions: 3032689Sbostic * 1.) No portion of this notice shall be removed. 3132689Sbostic * 2.) Credit shall not be taken for the creation of this source. 3232689Sbostic * 3.) This code is not to be traded, sold, or used for personal 3332689Sbostic * gain or profit. 3432689Sbostic * 3532689Sbostic */ 3632689Sbostic 3732689Sbostic #include "rogue.h" 3832689Sbostic 3932689Sbostic short m_moves = 0; 4032689Sbostic boolean jump = 0; 4132689Sbostic char *you_can_move_again = "you can move again"; 4232689Sbostic 4332689Sbostic extern short cur_room, halluc, blind, levitate; 4432689Sbostic extern short cur_level, max_level; 4532689Sbostic extern short bear_trap, haste_self, confused; 4632689Sbostic extern short e_rings, regeneration, auto_search; 4732689Sbostic extern char hunger_str[]; 4832689Sbostic extern boolean being_held, interrupted, r_teleport, passgo; 4932689Sbostic 5032689Sbostic one_move_rogue(dirch, pickup) 5132689Sbostic short dirch, pickup; 5232689Sbostic { 5332689Sbostic short row, col; 5432689Sbostic object *obj; 5532689Sbostic char desc[DCOLS]; 5632689Sbostic short n, status, d; 5732689Sbostic 5832689Sbostic row = rogue.row; 5932689Sbostic col = rogue.col; 6032689Sbostic 6132689Sbostic if (confused) { 6232689Sbostic dirch = gr_dir(); 6332689Sbostic } 6432689Sbostic (void) is_direction(dirch, &d); 6532689Sbostic get_dir_rc(d, &row, &col, 1); 6632689Sbostic 6732689Sbostic if (!can_move(rogue.row, rogue.col, row, col)) { 6832689Sbostic return(MOVE_FAILED); 6932689Sbostic } 7032689Sbostic if (being_held || bear_trap) { 7132689Sbostic if (!(dungeon[row][col] & MONSTER)) { 7232689Sbostic if (being_held) { 7332689Sbostic message("you are being held", 1); 7432689Sbostic } else { 7532689Sbostic message("you are still stuck in the bear trap", 0); 7632689Sbostic (void) reg_move(); 7732689Sbostic } 7832689Sbostic return(MOVE_FAILED); 7932689Sbostic } 8032689Sbostic } 8132689Sbostic if (r_teleport) { 8232689Sbostic if (rand_percent(R_TELE_PERCENT)) { 8332689Sbostic tele(); 8432689Sbostic return(STOPPED_ON_SOMETHING); 8532689Sbostic } 8632689Sbostic } 8732689Sbostic if (dungeon[row][col] & MONSTER) { 8832689Sbostic rogue_hit(object_at(&level_monsters, row, col), 0); 8932689Sbostic (void) reg_move(); 9032689Sbostic return(MOVE_FAILED); 9132689Sbostic } 9232689Sbostic if (dungeon[row][col] & DOOR) { 9332689Sbostic if (cur_room == PASSAGE) { 9432689Sbostic cur_room = get_room_number(row, col); 9532689Sbostic light_up_room(cur_room); 9632689Sbostic wake_room(cur_room, 1, row, col); 9732689Sbostic } else { 9832689Sbostic light_passage(row, col); 9932689Sbostic } 10032689Sbostic } else if ((dungeon[rogue.row][rogue.col] & DOOR) && 10132689Sbostic (dungeon[row][col] & TUNNEL)) { 10232689Sbostic light_passage(row, col); 10332689Sbostic wake_room(cur_room, 0, rogue.row, rogue.col); 10432689Sbostic darken_room(cur_room); 10532689Sbostic cur_room = PASSAGE; 10632689Sbostic } else if (dungeon[row][col] & TUNNEL) { 10732689Sbostic light_passage(row, col); 10832689Sbostic } 10932689Sbostic mvaddch(rogue.row, rogue.col, get_dungeon_char(rogue.row, rogue.col)); 11032689Sbostic mvaddch(row, col, rogue.fchar); 11132689Sbostic 11232689Sbostic if (!jump) { 11332689Sbostic refresh(); 11432689Sbostic } 11532689Sbostic rogue.row = row; 11632689Sbostic rogue.col = col; 11732689Sbostic if (dungeon[row][col] & OBJECT) { 11832689Sbostic if (levitate && pickup) { 11932689Sbostic return(STOPPED_ON_SOMETHING); 12032689Sbostic } 12132689Sbostic if (pickup && !levitate) { 12232689Sbostic if (obj = pick_up(row, col, &status)) { 12332689Sbostic get_desc(obj, desc); 12432689Sbostic if (obj->what_is == GOLD) { 12532689Sbostic free_object(obj); 12632689Sbostic goto NOT_IN_PACK; 12732689Sbostic } 12832689Sbostic } else if (!status) { 12932689Sbostic goto MVED; 13032689Sbostic } else { 13132689Sbostic goto MOVE_ON; 13232689Sbostic } 13332689Sbostic } else { 13432689Sbostic MOVE_ON: 13532689Sbostic obj = object_at(&level_objects, row, col); 13632689Sbostic (void) strcpy(desc, "moved onto "); 13732689Sbostic get_desc(obj, desc+11); 13832689Sbostic goto NOT_IN_PACK; 13932689Sbostic } 14032689Sbostic n = strlen(desc); 14132689Sbostic desc[n] = '('; 14232689Sbostic desc[n+1] = obj->ichar; 14332689Sbostic desc[n+2] = ')'; 14432689Sbostic desc[n+3] = 0; 14532689Sbostic NOT_IN_PACK: 14632689Sbostic message(desc, 1); 14732689Sbostic (void) reg_move(); 14832689Sbostic return(STOPPED_ON_SOMETHING); 14932689Sbostic } 15032689Sbostic if (dungeon[row][col] & (DOOR | STAIRS | TRAP)) { 15132689Sbostic if ((!levitate) && (dungeon[row][col] & TRAP)) { 15232689Sbostic trap_player(row, col); 15332689Sbostic } 15432689Sbostic (void) reg_move(); 15532689Sbostic return(STOPPED_ON_SOMETHING); 15632689Sbostic } 15732689Sbostic MVED: if (reg_move()) { /* fainted from hunger */ 15832689Sbostic return(STOPPED_ON_SOMETHING); 15932689Sbostic } 16032689Sbostic return((confused ? STOPPED_ON_SOMETHING : MOVED)); 16132689Sbostic } 16232689Sbostic 16332689Sbostic multiple_move_rogue(dirch) 16432689Sbostic short dirch; 16532689Sbostic { 16632689Sbostic short row, col; 16732689Sbostic short m; 16832689Sbostic 16932689Sbostic switch(dirch) { 17032689Sbostic case '\010': 17132689Sbostic case '\012': 17232689Sbostic case '\013': 17332689Sbostic case '\014': 17432689Sbostic case '\031': 17532689Sbostic case '\025': 17632689Sbostic case '\016': 17732689Sbostic case '\002': 17832689Sbostic do { 17932689Sbostic row = rogue.row; 18032689Sbostic col = rogue.col; 18132689Sbostic if (((m = one_move_rogue((dirch + 96), 1)) == MOVE_FAILED) || 18232689Sbostic (m == STOPPED_ON_SOMETHING) || 18332689Sbostic interrupted) { 18432689Sbostic break; 18532689Sbostic } 18632689Sbostic } while (!next_to_something(row, col)); 18732689Sbostic if ( (!interrupted) && passgo && (m == MOVE_FAILED) && 18832689Sbostic (dungeon[rogue.row][rogue.col] & TUNNEL)) { 18932689Sbostic turn_passage(dirch + 96, 0); 19032689Sbostic } 19132689Sbostic break; 19232689Sbostic case 'H': 19332689Sbostic case 'J': 19432689Sbostic case 'K': 19532689Sbostic case 'L': 19632689Sbostic case 'B': 19732689Sbostic case 'Y': 19832689Sbostic case 'U': 19932689Sbostic case 'N': 20032689Sbostic while ((!interrupted) && (one_move_rogue((dirch + 32), 1) == MOVED)) ; 20132689Sbostic 20232689Sbostic if ( (!interrupted) && passgo && 20332689Sbostic (dungeon[rogue.row][rogue.col] & TUNNEL)) { 20432689Sbostic turn_passage(dirch + 32, 1); 20532689Sbostic } 20632689Sbostic break; 20732689Sbostic } 20832689Sbostic } 20932689Sbostic 21032689Sbostic is_passable(row, col) 21132689Sbostic register row, col; 21232689Sbostic { 21332689Sbostic if ((row < MIN_ROW) || (row > (DROWS - 2)) || (col < 0) || 21432689Sbostic (col > (DCOLS-1))) { 21532689Sbostic return(0); 21632689Sbostic } 21732689Sbostic if (dungeon[row][col] & HIDDEN) { 21832689Sbostic return((dungeon[row][col] & TRAP) ? 1 : 0); 21932689Sbostic } 22032689Sbostic return(dungeon[row][col] & (FLOOR | TUNNEL | DOOR | STAIRS | TRAP)); 22132689Sbostic } 22232689Sbostic 22332689Sbostic next_to_something(drow, dcol) 22432689Sbostic register drow, dcol; 22532689Sbostic { 22632689Sbostic short i, j, i_end, j_end, row, col; 22732689Sbostic short pass_count = 0; 22832689Sbostic unsigned short s; 22932689Sbostic 23032689Sbostic if (confused) { 23132689Sbostic return(1); 23232689Sbostic } 23332689Sbostic if (blind) { 23432689Sbostic return(0); 23532689Sbostic } 23632689Sbostic i_end = (rogue.row < (DROWS-2)) ? 1 : 0; 23732689Sbostic j_end = (rogue.col < (DCOLS-1)) ? 1 : 0; 23832689Sbostic 23932689Sbostic for (i = ((rogue.row > MIN_ROW) ? -1 : 0); i <= i_end; i++) { 24032689Sbostic for (j = ((rogue.col > 0) ? -1 : 0); j <= j_end; j++) { 24132689Sbostic if ((i == 0) && (j == 0)) { 24232689Sbostic continue; 24332689Sbostic } 24432689Sbostic if (((rogue.row+i) == drow) && ((rogue.col+j) == dcol)) { 24532689Sbostic continue; 24632689Sbostic } 24732689Sbostic row = rogue.row + i; 24832689Sbostic col = rogue.col + j; 24932689Sbostic s = dungeon[row][col]; 25032689Sbostic if (s & HIDDEN) { 25132689Sbostic continue; 25232689Sbostic } 25332689Sbostic /* If the rogue used to be right, up, left, down, or right of 25432689Sbostic * row,col, and now isn't, then don't stop */ 25532689Sbostic if (s & (MONSTER | OBJECT | STAIRS)) { 25632689Sbostic if (((row == drow) || (col == dcol)) && 25732689Sbostic (!((row == rogue.row) || (col == rogue.col)))) { 25832689Sbostic continue; 25932689Sbostic } 26032689Sbostic return(1); 26132689Sbostic } 26232689Sbostic if (s & TRAP) { 26332689Sbostic if (!(s & HIDDEN)) { 26432689Sbostic if (((row == drow) || (col == dcol)) && 26532689Sbostic (!((row == rogue.row) || (col == rogue.col)))) { 26632689Sbostic continue; 26732689Sbostic } 26832689Sbostic return(1); 26932689Sbostic } 27032689Sbostic } 27132689Sbostic if ((((i - j) == 1) || ((i - j) == -1)) && (s & TUNNEL)) { 27232689Sbostic if (++pass_count > 1) { 27332689Sbostic return(1); 27432689Sbostic } 27532689Sbostic } 27632689Sbostic if ((s & DOOR) && ((i == 0) || (j == 0))) { 27732689Sbostic return(1); 27832689Sbostic } 27932689Sbostic } 28032689Sbostic } 28132689Sbostic return(0); 28232689Sbostic } 28332689Sbostic 28432689Sbostic can_move(row1, col1, row2, col2) 28532689Sbostic { 28632689Sbostic if (!is_passable(row2, col2)) { 28732689Sbostic return(0); 28832689Sbostic } 28932689Sbostic if ((row1 != row2) && (col1 != col2)) { 29032689Sbostic if ((dungeon[row1][col1] & DOOR) || (dungeon[row2][col2] & DOOR)) { 29132689Sbostic return(0); 29232689Sbostic } 29332689Sbostic if ((!dungeon[row1][col2]) || (!dungeon[row2][col1])) { 29432689Sbostic return(0); 29532689Sbostic } 29632689Sbostic } 29732689Sbostic return(1); 29832689Sbostic } 29932689Sbostic 30032689Sbostic move_onto() 30132689Sbostic { 30232689Sbostic short ch, d; 30332689Sbostic boolean first_miss = 1; 30432689Sbostic 30532689Sbostic while (!is_direction(ch = rgetchar(), &d)) { 30632689Sbostic sound_bell(); 30732689Sbostic if (first_miss) { 30832689Sbostic message("direction? ", 0); 30932689Sbostic first_miss = 0; 31032689Sbostic } 31132689Sbostic } 31232689Sbostic check_message(); 31332689Sbostic if (ch != CANCEL) { 31432689Sbostic (void) one_move_rogue(ch, 0); 31532689Sbostic } 31632689Sbostic } 31732689Sbostic 31832689Sbostic boolean 31932689Sbostic is_direction(c, d) 32032689Sbostic short c; 32132689Sbostic short *d; 32232689Sbostic { 32332689Sbostic switch(c) { 32432689Sbostic case 'h': 32532689Sbostic *d = LEFT; 32632689Sbostic break; 32732689Sbostic case 'j': 32832689Sbostic *d = DOWN; 32932689Sbostic break; 33032689Sbostic case 'k': 33132689Sbostic *d = UPWARD; 33232689Sbostic break; 33332689Sbostic case 'l': 33432689Sbostic *d = RIGHT; 33532689Sbostic break; 33632689Sbostic case 'b': 33732689Sbostic *d = DOWNLEFT; 33832689Sbostic break; 33932689Sbostic case 'y': 34032689Sbostic *d = UPLEFT; 34132689Sbostic break; 34232689Sbostic case 'u': 34332689Sbostic *d = UPRIGHT; 34432689Sbostic break; 34532689Sbostic case 'n': 34632689Sbostic *d = DOWNRIGHT; 34732689Sbostic break; 34832689Sbostic case CANCEL: 34932689Sbostic break; 35032689Sbostic default: 35132689Sbostic return(0); 35232689Sbostic } 35332689Sbostic return(1); 35432689Sbostic } 35532689Sbostic 35632689Sbostic boolean 35732689Sbostic check_hunger(msg_only) 35832689Sbostic boolean msg_only; 35932689Sbostic { 36032689Sbostic register short i, n; 36132689Sbostic boolean fainted = 0; 36232689Sbostic 36332689Sbostic if (rogue.moves_left == HUNGRY) { 36432689Sbostic (void) strcpy(hunger_str, "hungry"); 36532689Sbostic message(hunger_str, 0); 36632689Sbostic print_stats(STAT_HUNGER); 36732689Sbostic } 36832689Sbostic if (rogue.moves_left == WEAK) { 36932689Sbostic (void) strcpy(hunger_str, "weak"); 37032689Sbostic message(hunger_str, 1); 37132689Sbostic print_stats(STAT_HUNGER); 37232689Sbostic } 37332689Sbostic if (rogue.moves_left <= FAINT) { 37432689Sbostic if (rogue.moves_left == FAINT) { 37532689Sbostic (void) strcpy(hunger_str, "faint"); 37632689Sbostic message(hunger_str, 1); 37732689Sbostic print_stats(STAT_HUNGER); 37832689Sbostic } 37932689Sbostic n = get_rand(0, (FAINT - rogue.moves_left)); 38032689Sbostic if (n > 0) { 38132689Sbostic fainted = 1; 38232689Sbostic if (rand_percent(40)) { 38332689Sbostic rogue.moves_left++; 38432689Sbostic } 38532689Sbostic message("you faint", 1); 38632689Sbostic for (i = 0; i < n; i++) { 38732689Sbostic if (coin_toss()) { 38832689Sbostic mv_mons(); 38932689Sbostic } 39032689Sbostic } 39132689Sbostic message(you_can_move_again, 1); 39232689Sbostic } 39332689Sbostic } 39432689Sbostic if (msg_only) { 39532689Sbostic return(fainted); 39632689Sbostic } 39732689Sbostic if (rogue.moves_left <= STARVE) { 39832689Sbostic killed_by((object *) 0, STARVATION); 39932689Sbostic } 40032689Sbostic 40132689Sbostic switch(e_rings) { 40232689Sbostic /*case -2: 40332689Sbostic Subtract 0, i.e. do nothing. 40432689Sbostic break;*/ 40532689Sbostic case -1: 40632689Sbostic rogue.moves_left -= (rogue.moves_left % 2); 40732689Sbostic break; 40832689Sbostic case 0: 40932689Sbostic rogue.moves_left--; 41032689Sbostic break; 41132689Sbostic case 1: 41232689Sbostic rogue.moves_left--; 41332689Sbostic (void) check_hunger(1); 41432689Sbostic rogue.moves_left -= (rogue.moves_left % 2); 41532689Sbostic break; 41632689Sbostic case 2: 41732689Sbostic rogue.moves_left--; 41832689Sbostic (void) check_hunger(1); 41932689Sbostic rogue.moves_left--; 42032689Sbostic break; 42132689Sbostic } 42232689Sbostic return(fainted); 42332689Sbostic } 42432689Sbostic 42532689Sbostic boolean 42632689Sbostic reg_move() 42732689Sbostic { 42832689Sbostic boolean fainted; 42932689Sbostic 43032689Sbostic if ((rogue.moves_left <= HUNGRY) || (cur_level >= max_level)) { 43132689Sbostic fainted = check_hunger(0); 43232689Sbostic } else { 43332689Sbostic fainted = 0; 43432689Sbostic } 43532689Sbostic 43632689Sbostic mv_mons(); 43732689Sbostic 43832689Sbostic if (++m_moves >= 120) { 43932689Sbostic m_moves = 0; 44032689Sbostic wanderer(); 44132689Sbostic } 44232689Sbostic if (halluc) { 44332689Sbostic if (!(--halluc)) { 44432689Sbostic unhallucinate(); 44532689Sbostic } else { 44632689Sbostic hallucinate(); 44732689Sbostic } 44832689Sbostic } 44932689Sbostic if (blind) { 45032689Sbostic if (!(--blind)) { 45132689Sbostic unblind(); 45232689Sbostic } 45332689Sbostic } 45432689Sbostic if (confused) { 45532689Sbostic if (!(--confused)) { 45632689Sbostic unconfuse(); 45732689Sbostic } 45832689Sbostic } 45932689Sbostic if (bear_trap) { 46032689Sbostic bear_trap--; 46132689Sbostic } 46232689Sbostic if (levitate) { 46332689Sbostic if (!(--levitate)) { 46432689Sbostic message("you float gently to the ground", 1); 46532689Sbostic if (dungeon[rogue.row][rogue.col] & TRAP) { 46632689Sbostic trap_player(rogue.row, rogue.col); 46732689Sbostic } 46832689Sbostic } 46932689Sbostic } 47032689Sbostic if (haste_self) { 47132689Sbostic if (!(--haste_self)) { 47232689Sbostic message("you feel yourself slowing down", 0); 47332689Sbostic } 47432689Sbostic } 47532689Sbostic heal(); 47632689Sbostic if (auto_search > 0) { 47732689Sbostic search(auto_search, auto_search); 47832689Sbostic } 47932689Sbostic return(fainted); 48032689Sbostic } 48132689Sbostic 48232689Sbostic rest(count) 48332689Sbostic { 48432689Sbostic int i; 48532689Sbostic 48632689Sbostic interrupted = 0; 48732689Sbostic 48832689Sbostic for (i = 0; i < count; i++) { 48932689Sbostic if (interrupted) { 49032689Sbostic break; 49132689Sbostic } 49232689Sbostic (void) reg_move(); 49332689Sbostic } 49432689Sbostic } 49532689Sbostic 49632689Sbostic gr_dir() 49732689Sbostic { 49832689Sbostic short d; 49932689Sbostic 50032689Sbostic d = get_rand(1, 8); 50132689Sbostic 50232689Sbostic switch(d) { 50332689Sbostic case 1: 50432689Sbostic d = 'j'; 50532689Sbostic break; 50632689Sbostic case 2: 50732689Sbostic d = 'k'; 50832689Sbostic break; 50932689Sbostic case 3: 51032689Sbostic d = 'l'; 51132689Sbostic break; 51232689Sbostic case 4: 51332689Sbostic d = 'h'; 51432689Sbostic break; 51532689Sbostic case 5: 51632689Sbostic d = 'y'; 51732689Sbostic break; 51832689Sbostic case 6: 51932689Sbostic d = 'u'; 52032689Sbostic break; 52132689Sbostic case 7: 52232689Sbostic d = 'b'; 52332689Sbostic break; 52432689Sbostic case 8: 52532689Sbostic d = 'n'; 52632689Sbostic break; 52732689Sbostic } 52832689Sbostic return(d); 52932689Sbostic } 53032689Sbostic 53132689Sbostic heal() 53232689Sbostic { 53332689Sbostic static short heal_exp = -1, n, c = 0; 53432689Sbostic static boolean alt; 53532689Sbostic 53632689Sbostic if (rogue.hp_current == rogue.hp_max) { 53732689Sbostic c = 0; 53832689Sbostic return; 53932689Sbostic } 54032689Sbostic if (rogue.exp != heal_exp) { 54132689Sbostic heal_exp = rogue.exp; 54232689Sbostic 54332689Sbostic switch(heal_exp) { 54432689Sbostic case 1: 54532689Sbostic n = 20; 54632689Sbostic break; 54732689Sbostic case 2: 54832689Sbostic n = 18; 54932689Sbostic break; 55032689Sbostic case 3: 55132689Sbostic n = 17; 55232689Sbostic break; 55332689Sbostic case 4: 55432689Sbostic n = 14; 55532689Sbostic break; 55632689Sbostic case 5: 55732689Sbostic n = 13; 55832689Sbostic break; 55932689Sbostic case 6: 56032689Sbostic n = 10; 56132689Sbostic break; 56232689Sbostic case 7: 56332689Sbostic n = 9; 56432689Sbostic break; 56532689Sbostic case 8: 56632689Sbostic n = 8; 56732689Sbostic break; 56832689Sbostic case 9: 56932689Sbostic n = 7; 57032689Sbostic break; 57132689Sbostic case 10: 57232689Sbostic n = 4; 57332689Sbostic break; 57432689Sbostic case 11: 57532689Sbostic n = 3; 57632689Sbostic break; 57732689Sbostic case 12: 57832689Sbostic default: 57932689Sbostic n = 2; 58032689Sbostic } 58132689Sbostic } 58232689Sbostic if (++c >= n) { 58332689Sbostic c = 0; 58432689Sbostic rogue.hp_current++; 58532689Sbostic if (alt = !alt) { 58632689Sbostic rogue.hp_current++; 58732689Sbostic } 58832689Sbostic if ((rogue.hp_current += regeneration) > rogue.hp_max) { 58932689Sbostic rogue.hp_current = rogue.hp_max; 59032689Sbostic } 59132689Sbostic print_stats(STAT_HP); 59232689Sbostic } 59332689Sbostic } 59432689Sbostic 59532689Sbostic static boolean 59632689Sbostic can_turn(nrow, ncol) 59732689Sbostic short nrow, ncol; 59832689Sbostic { 59932689Sbostic if ((dungeon[nrow][ncol] & TUNNEL) && is_passable(nrow, ncol)) { 60032689Sbostic return(1); 60132689Sbostic } 60232689Sbostic return(0); 60332689Sbostic } 60432689Sbostic 60532689Sbostic turn_passage(dir, fast) 60632689Sbostic short dir; 60732689Sbostic boolean fast; 60832689Sbostic { 60932689Sbostic short crow = rogue.row, ccol = rogue.col, turns = 0; 61032689Sbostic short ndir; 61132689Sbostic 61232689Sbostic if ((dir != 'h') && can_turn(crow, ccol + 1)) { 61332689Sbostic turns++; 61432689Sbostic ndir = 'l'; 61532689Sbostic } 61632689Sbostic if ((dir != 'l') && can_turn(crow, ccol - 1)) { 61732689Sbostic turns++; 61832689Sbostic ndir = 'h'; 61932689Sbostic } 62032689Sbostic if ((dir != 'k') && can_turn(crow + 1, ccol)) { 62132689Sbostic turns++; 62232689Sbostic ndir = 'j'; 62332689Sbostic } 62432689Sbostic if ((dir != 'j') && can_turn(crow - 1, ccol)) { 62532689Sbostic turns++; 62632689Sbostic ndir = 'k'; 62732689Sbostic } 62832689Sbostic if (turns == 1) { 62932689Sbostic multiple_move_rogue(ndir - (fast ? 32 : 96)); 63032689Sbostic } 63132689Sbostic } 632