* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
* This code is derived from software contributed to Berkeley by
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)move.c 8.1 (Berkeley) %G%";
* This source herein may be modified and/or distributed by anybody who
* so desires, with the following restrictions:
* 1.) No portion of this notice shall be removed.
* 2.) Credit shall not be taken for the creation of this source.
* 3.) This code is not to be traded, sold, or used for personal
char *you_can_move_again
= "you can move again";
extern short cur_room
, halluc
, blind
, levitate
;
extern short cur_level
, max_level
;
extern short bear_trap
, haste_self
, confused
;
extern short e_rings
, regeneration
, auto_search
;
extern char hunger_str
[];
extern boolean being_held
, interrupted
, r_teleport
, passgo
;
one_move_rogue(dirch
, pickup
)
(void) is_direction(dirch
, &d
);
get_dir_rc(d
, &row
, &col
, 1);
if (!can_move(rogue
.row
, rogue
.col
, row
, col
)) {
if (being_held
|| bear_trap
) {
if (!(dungeon
[row
][col
] & MONSTER
)) {
message("you are being held", 1);
message("you are still stuck in the bear trap", 0);
if (rand_percent(R_TELE_PERCENT
)) {
return(STOPPED_ON_SOMETHING
);
if (dungeon
[row
][col
] & MONSTER
) {
rogue_hit(object_at(&level_monsters
, row
, col
), 0);
if (dungeon
[row
][col
] & DOOR
) {
if (cur_room
== PASSAGE
) {
cur_room
= get_room_number(row
, col
);
wake_room(cur_room
, 1, row
, col
);
} else if ((dungeon
[rogue
.row
][rogue
.col
] & DOOR
) &&
(dungeon
[row
][col
] & TUNNEL
)) {
wake_room(cur_room
, 0, rogue
.row
, rogue
.col
);
} else if (dungeon
[row
][col
] & TUNNEL
) {
mvaddch(rogue
.row
, rogue
.col
, get_dungeon_char(rogue
.row
, rogue
.col
));
mvaddch(row
, col
, rogue
.fchar
);
if (dungeon
[row
][col
] & OBJECT
) {
if (levitate
&& pickup
) {
return(STOPPED_ON_SOMETHING
);
if (pickup
&& !levitate
) {
if (obj
= pick_up(row
, col
, &status
)) {
if (obj
->what_is
== GOLD
) {
obj
= object_at(&level_objects
, row
, col
);
(void) strcpy(desc
, "moved onto ");
return(STOPPED_ON_SOMETHING
);
if (dungeon
[row
][col
] & (DOOR
| STAIRS
| TRAP
)) {
if ((!levitate
) && (dungeon
[row
][col
] & TRAP
)) {
return(STOPPED_ON_SOMETHING
);
MVED
: if (reg_move()) { /* fainted from hunger */
return(STOPPED_ON_SOMETHING
);
return((confused
? STOPPED_ON_SOMETHING
: MOVED
));
multiple_move_rogue(dirch
)
if (((m
= one_move_rogue((dirch
+ 96), 1)) == MOVE_FAILED
) ||
(m
== STOPPED_ON_SOMETHING
) ||
} while (!next_to_something(row
, col
));
if ( (!interrupted
) && passgo
&& (m
== MOVE_FAILED
) &&
(dungeon
[rogue
.row
][rogue
.col
] & TUNNEL
)) {
turn_passage(dirch
+ 96, 0);
while ((!interrupted
) && (one_move_rogue((dirch
+ 32), 1) == MOVED
)) ;
if ( (!interrupted
) && passgo
&&
(dungeon
[rogue
.row
][rogue
.col
] & TUNNEL
)) {
turn_passage(dirch
+ 32, 1);
if ((row
< MIN_ROW
) || (row
> (DROWS
- 2)) || (col
< 0) ||
if (dungeon
[row
][col
] & HIDDEN
) {
return((dungeon
[row
][col
] & TRAP
) ? 1 : 0);
return(dungeon
[row
][col
] & (FLOOR
| TUNNEL
| DOOR
| STAIRS
| TRAP
));
next_to_something(drow
, dcol
)
short i
, j
, i_end
, j_end
, row
, col
;
i_end
= (rogue
.row
< (DROWS
-2)) ? 1 : 0;
j_end
= (rogue
.col
< (DCOLS
-1)) ? 1 : 0;
for (i
= ((rogue
.row
> MIN_ROW
) ? -1 : 0); i
<= i_end
; i
++) {
for (j
= ((rogue
.col
> 0) ? -1 : 0); j
<= j_end
; j
++) {
if ((i
== 0) && (j
== 0)) {
if (((rogue
.row
+i
) == drow
) && ((rogue
.col
+j
) == dcol
)) {
/* If the rogue used to be right, up, left, down, or right of
* row,col, and now isn't, then don't stop */
if (s
& (MONSTER
| OBJECT
| STAIRS
)) {
if (((row
== drow
) || (col
== dcol
)) &&
(!((row
== rogue
.row
) || (col
== rogue
.col
)))) {
if (((row
== drow
) || (col
== dcol
)) &&
(!((row
== rogue
.row
) || (col
== rogue
.col
)))) {
if ((((i
- j
) == 1) || ((i
- j
) == -1)) && (s
& TUNNEL
)) {
if ((s
& DOOR
) && ((i
== 0) || (j
== 0))) {
can_move(row1
, col1
, row2
, col2
)
if (!is_passable(row2
, col2
)) {
if ((row1
!= row2
) && (col1
!= col2
)) {
if ((dungeon
[row1
][col1
] & DOOR
) || (dungeon
[row2
][col2
] & DOOR
)) {
if ((!dungeon
[row1
][col2
]) || (!dungeon
[row2
][col1
])) {
while (!is_direction(ch
= rgetchar(), &d
)) {
message("direction? ", 0);
(void) one_move_rogue(ch
, 0);
if (rogue
.moves_left
== HUNGRY
) {
(void) strcpy(hunger_str
, "hungry");
print_stats(STAT_HUNGER
);
if (rogue
.moves_left
== WEAK
) {
(void) strcpy(hunger_str
, "weak");
print_stats(STAT_HUNGER
);
if (rogue
.moves_left
<= FAINT
) {
if (rogue
.moves_left
== FAINT
) {
(void) strcpy(hunger_str
, "faint");
print_stats(STAT_HUNGER
);
n
= get_rand(0, (FAINT
- rogue
.moves_left
));
for (i
= 0; i
< n
; i
++) {
message(you_can_move_again
, 1);
if (rogue
.moves_left
<= STARVE
) {
killed_by((object
*) 0, STARVATION
);
Subtract 0, i.e. do nothing.
rogue
.moves_left
-= (rogue
.moves_left
% 2);
rogue
.moves_left
-= (rogue
.moves_left
% 2);
if ((rogue
.moves_left
<= HUNGRY
) || (cur_level
>= max_level
)) {
fainted
= check_hunger(0);
message("you float gently to the ground", 1);
if (dungeon
[rogue
.row
][rogue
.col
] & TRAP
) {
trap_player(rogue
.row
, rogue
.col
);
message("you feel yourself slowing down", 0);
search(auto_search
, auto_search
);
for (i
= 0; i
< count
; i
++) {
static short heal_exp
= -1, n
, c
= 0;
if (rogue
.hp_current
== rogue
.hp_max
) {
if (rogue
.exp
!= heal_exp
) {
if ((rogue
.hp_current
+= regeneration
) > rogue
.hp_max
) {
rogue
.hp_current
= rogue
.hp_max
;
if ((dungeon
[nrow
][ncol
] & TUNNEL
) && is_passable(nrow
, ncol
)) {
short crow
= rogue
.row
, ccol
= rogue
.col
, turns
= 0;
if ((dir
!= 'h') && can_turn(crow
, ccol
+ 1)) {
if ((dir
!= 'l') && can_turn(crow
, ccol
- 1)) {
if ((dir
!= 'k') && can_turn(crow
+ 1, ccol
)) {
if ((dir
!= 'j') && can_turn(crow
- 1, ccol
)) {
multiple_move_rogue(ndir
- (fast
? 32 : 96));