Home | History | Annotate | Line # | Download | only in rogue
monster.c revision 1.6
      1  1.6  hubertf /*	$NetBSD: monster.c,v 1.6 1998/09/11 14:07:51 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[] = "@(#)monster.c	8.1 (Berkeley) 5/31/93";
     43  1.3      cgd #else
     44  1.6  hubertf __RCSID("$NetBSD: monster.c,v 1.6 1998/09/11 14:07:51 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  * monster.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 object level_monsters;
     63  1.1      cgd boolean mon_disappeared;
     64  1.1      cgd 
     65  1.1      cgd char *m_names[] = {
     66  1.1      cgd 	"aquator",
     67  1.1      cgd 	"bat",
     68  1.1      cgd 	"centaur",
     69  1.1      cgd 	"dragon",
     70  1.1      cgd 	"emu",
     71  1.1      cgd 	"venus fly-trap",
     72  1.1      cgd 	"griffin",
     73  1.1      cgd 	"hobgoblin",
     74  1.1      cgd 	"ice monster",
     75  1.1      cgd 	"jabberwock",
     76  1.1      cgd 	"kestrel",
     77  1.1      cgd 	"leprechaun",
     78  1.1      cgd 	"medusa",
     79  1.1      cgd 	"nymph",
     80  1.1      cgd 	"orc",
     81  1.1      cgd 	"phantom",
     82  1.1      cgd 	"quagga",
     83  1.1      cgd 	"rattlesnake",
     84  1.1      cgd 	"snake",
     85  1.1      cgd 	"troll",
     86  1.1      cgd 	"black unicorn",
     87  1.1      cgd 	"vampire",
     88  1.1      cgd 	"wraith",
     89  1.1      cgd 	"xeroc",
     90  1.1      cgd 	"yeti",
     91  1.1      cgd 	"zombie"
     92  1.1      cgd };
     93  1.1      cgd 
     94  1.1      cgd object mon_tab[MONSTERS] = {
     95  1.1      cgd 	{(ASLEEP|WAKENS|WANDERS|RUSTS),"0d0",25,'A',20,9,18,100,0,0,0,0,0},
     96  1.1      cgd 	{(ASLEEP|WANDERS|FLITS|FLIES),"1d3",10,'B',2,1,8,60,0,0,0,0,0},
     97  1.1      cgd 	{(ASLEEP|WANDERS),"3d3/2d5",32,'C',15,7,16,85,0,10,0,0,0},
     98  1.1      cgd 	{(ASLEEP|WAKENS|FLAMES),"4d6/4d9",145,'D',5000,21,126,100,0,90,0,0,0},
     99  1.1      cgd 	{(ASLEEP|WAKENS),"1d3",11,'E',2,1,7,65,0,0,0,0,0},
    100  1.1      cgd 	{(HOLDS|STATIONARY),"5d5",73,'F',91,12,126,80,0,0,0,0,0},
    101  1.1      cgd 	{(ASLEEP|WAKENS|WANDERS|FLIES),"5d5/5d5",115,'G',
    102  1.1      cgd 			2000,20,126,85,0,10,0,0,0},
    103  1.1      cgd 	{(ASLEEP|WAKENS|WANDERS),"1d3/1d2",15,'H',3,1,10,67,0,0,0,0,0},
    104  1.1      cgd 	{(ASLEEP|FREEZES),"0d0",15,'I',5,2,11,68,0,0,0,0,0},
    105  1.1      cgd 	{(ASLEEP|WANDERS),"3d10/4d5",132,'J',3000,21,126,100,0,0,0,0,0},
    106  1.1      cgd 	{(ASLEEP|WAKENS|WANDERS|FLIES),"1d4",10,'K',2,1,6,60,0,0,0,0,0},
    107  1.1      cgd 	{(ASLEEP|STEALS_GOLD),"0d0",25,'L',21,6,16,75,0,0,0,0,0},
    108  1.1      cgd 	{(ASLEEP|WAKENS|WANDERS|CONFUSES),"4d4/3d7",97,'M',
    109  1.1      cgd 			250,18,126,85,0,25,0,0,0},
    110  1.1      cgd 	{(ASLEEP|STEALS_ITEM),"0d0",25,'N',39,10,19,75,0,100,0,0,0},
    111  1.1      cgd 	{(ASLEEP|WANDERS|WAKENS|SEEKS_GOLD),"1d6",25,'O',5,4,13,70,0,10,0,0,0},
    112  1.1      cgd 	{(ASLEEP|INVISIBLE|WANDERS|FLITS),"5d4",76,'P',120,15,24,80,0,50,0,0,0},
    113  1.1      cgd 	{(ASLEEP|WAKENS|WANDERS),"3d5",30,'Q',20,8,17,78,0,20,0,0,0},
    114  1.1      cgd 	{(ASLEEP|WAKENS|WANDERS|STINGS),"2d5",19,'R',10,3,12,70,0,0,0,0,0},
    115  1.1      cgd 	{(ASLEEP|WAKENS|WANDERS),"1d3",8,'S',2,1,9,50,0,0,0,0,0},
    116  1.1      cgd 	{(ASLEEP|WAKENS|WANDERS),"4d6/1d4",75,'T',125,13,22,75,0,33,0,0,0},
    117  1.1      cgd 	{(ASLEEP|WAKENS|WANDERS),"4d10",90,'U',
    118  1.1      cgd 			200,17,26,85,0,33,0,0,0},
    119  1.1      cgd 	{(ASLEEP|WAKENS|WANDERS|DRAINS_LIFE),"1d14/1d4",55,'V',
    120  1.1      cgd 			350,19,126,85,0,18,0,0,0},
    121  1.1      cgd 	{(ASLEEP|WANDERS|DROPS_LEVEL),"2d8",45,'W',55,14,23,75,0,0,0,0,0},
    122  1.1      cgd 	{(ASLEEP|IMITATES),"4d6",42,'X',110,16,25,75,0,0,0,0,0},
    123  1.1      cgd 	{(ASLEEP|WANDERS),"3d6",35,'Y',50,11,20,80,0,20,0,0,0},
    124  1.1      cgd 	{(ASLEEP|WAKENS|WANDERS),"1d7",21,'Z',8,5,14,69,0,0,0,0,0}
    125  1.1      cgd };
    126  1.1      cgd 
    127  1.4    lukem void
    128  1.1      cgd put_mons()
    129  1.1      cgd {
    130  1.1      cgd 	short i;
    131  1.1      cgd 	short n;
    132  1.1      cgd 	object *monster;
    133  1.1      cgd 	short row, col;
    134  1.1      cgd 
    135  1.1      cgd 	n = get_rand(4, 6);
    136  1.1      cgd 
    137  1.1      cgd 	for (i = 0; i < n; i++) {
    138  1.1      cgd 		monster = gr_monster((object *) 0, 0);
    139  1.1      cgd 		if ((monster->m_flags & WANDERS) && coin_toss()) {
    140  1.1      cgd 			wake_up(monster);
    141  1.1      cgd 		}
    142  1.1      cgd 		gr_row_col(&row, &col, (FLOOR | TUNNEL | STAIRS | OBJECT));
    143  1.1      cgd 		put_m_at(row, col, monster);
    144  1.1      cgd 	}
    145  1.1      cgd }
    146  1.1      cgd 
    147  1.1      cgd object *
    148  1.1      cgd gr_monster(monster, mn)
    149  1.4    lukem 	object *monster;
    150  1.4    lukem 	int mn;
    151  1.1      cgd {
    152  1.1      cgd 	if (!monster) {
    153  1.1      cgd 		monster = alloc_object();
    154  1.1      cgd 
    155  1.1      cgd 		for (;;) {
    156  1.1      cgd 			mn = get_rand(0, MONSTERS-1);
    157  1.1      cgd 			if ((cur_level >= mon_tab[mn].first_level) &&
    158  1.1      cgd 			(cur_level <= mon_tab[mn].last_level)) {
    159  1.1      cgd 				break;
    160  1.1      cgd 			}
    161  1.1      cgd 		}
    162  1.1      cgd 	}
    163  1.1      cgd 	*monster = mon_tab[mn];
    164  1.1      cgd 	if (monster->m_flags & IMITATES) {
    165  1.1      cgd 		monster->disguise = gr_obj_char();
    166  1.1      cgd 	}
    167  1.1      cgd 	if (cur_level > (AMULET_LEVEL + 2)) {
    168  1.1      cgd 		monster->m_flags |= HASTED;
    169  1.1      cgd 	}
    170  1.1      cgd 	monster->trow = NO_ROOM;
    171  1.1      cgd 	return(monster);
    172  1.1      cgd }
    173  1.1      cgd 
    174  1.4    lukem void
    175  1.1      cgd mv_mons()
    176  1.1      cgd {
    177  1.5  hubertf 	object *monster, *next_monster, *test_mons;
    178  1.1      cgd 	boolean flew;
    179  1.1      cgd 
    180  1.1      cgd 	if (haste_self % 2) {
    181  1.1      cgd 		return;
    182  1.1      cgd 	}
    183  1.1      cgd 
    184  1.1      cgd 	monster = level_monsters.next_monster;
    185  1.1      cgd 
    186  1.1      cgd 	while (monster) {
    187  1.1      cgd 		next_monster = monster->next_monster;
    188  1.1      cgd 		mon_disappeared = 0;
    189  1.1      cgd 		if (monster->m_flags & HASTED) {
    190  1.1      cgd 			mv_1_monster(monster, rogue.row, rogue.col);
    191  1.1      cgd 			if (mon_disappeared) {
    192  1.1      cgd 				goto NM;
    193  1.1      cgd 			}
    194  1.1      cgd 		} else if (monster->m_flags & SLOWED) {
    195  1.1      cgd 			monster->slowed_toggle = !monster->slowed_toggle;
    196  1.1      cgd 			if (monster->slowed_toggle) {
    197  1.1      cgd 				goto NM;
    198  1.1      cgd 			}
    199  1.1      cgd 		}
    200  1.1      cgd 		if ((monster->m_flags & CONFUSED) && move_confused(monster)) {
    201  1.1      cgd 			goto NM;
    202  1.1      cgd 		}
    203  1.1      cgd 		flew = 0;
    204  1.1      cgd 		if (	(monster->m_flags & FLIES) &&
    205  1.1      cgd 				!(monster->m_flags & NAPPING) &&
    206  1.1      cgd 				!mon_can_go(monster, rogue.row, rogue.col)) {
    207  1.1      cgd 			flew = 1;
    208  1.1      cgd 			mv_1_monster(monster, rogue.row, rogue.col);
    209  1.1      cgd 			if (mon_disappeared) {
    210  1.1      cgd 				goto NM;
    211  1.1      cgd 			}
    212  1.1      cgd 		}
    213  1.1      cgd 		if (!(flew && mon_can_go(monster, rogue.row, rogue.col))) {
    214  1.1      cgd 			mv_1_monster(monster, rogue.row, rogue.col);
    215  1.1      cgd 		}
    216  1.5  hubertf NM:		test_mons = level_monsters.next_monster;
    217  1.5  hubertf 		monster = NULL;
    218  1.5  hubertf 		while (test_mons)
    219  1.5  hubertf 		{
    220  1.5  hubertf 			if (next_monster == test_mons)
    221  1.5  hubertf 			{
    222  1.5  hubertf 				monster = next_monster;
    223  1.5  hubertf 				break;
    224  1.5  hubertf 			}
    225  1.5  hubertf 			test_mons = test_mons -> next_monster;
    226  1.5  hubertf 		}
    227  1.1      cgd 	}
    228  1.1      cgd }
    229  1.1      cgd 
    230  1.4    lukem void
    231  1.1      cgd party_monsters(rn, n)
    232  1.4    lukem 	int rn, n;
    233  1.1      cgd {
    234  1.1      cgd 	short i, j;
    235  1.1      cgd 	short row, col;
    236  1.1      cgd 	object *monster;
    237  1.1      cgd 	boolean found;
    238  1.1      cgd 
    239  1.4    lukem 	row = col = 0;
    240  1.1      cgd 	n += n;
    241  1.1      cgd 
    242  1.1      cgd 	for (i = 0; i < MONSTERS; i++) {
    243  1.1      cgd 		mon_tab[i].first_level -= (cur_level % 3);
    244  1.1      cgd 	}
    245  1.1      cgd 	for (i = 0; i < n; i++) {
    246  1.1      cgd 		if (no_room_for_monster(rn)) {
    247  1.1      cgd 			break;
    248  1.1      cgd 		}
    249  1.1      cgd 		for (j = found = 0; ((!found) && (j < 250)); j++) {
    250  1.1      cgd 			row = get_rand(rooms[rn].top_row+1,
    251  1.1      cgd 				rooms[rn].bottom_row-1);
    252  1.1      cgd 			col = get_rand(rooms[rn].left_col+1,
    253  1.1      cgd 				rooms[rn].right_col-1);
    254  1.1      cgd 			if ((!(dungeon[row][col] & MONSTER)) &&
    255  1.1      cgd 				(dungeon[row][col] & (FLOOR | TUNNEL))) {
    256  1.1      cgd 				found = 1;
    257  1.1      cgd 			}
    258  1.1      cgd 		}
    259  1.1      cgd 		if (found) {
    260  1.1      cgd 			monster = gr_monster((object *) 0, 0);
    261  1.1      cgd 			if (!(monster->m_flags & IMITATES)) {
    262  1.1      cgd 				monster->m_flags |= WAKENS;
    263  1.1      cgd 			}
    264  1.1      cgd 			put_m_at(row, col, monster);
    265  1.1      cgd 		}
    266  1.1      cgd 	}
    267  1.1      cgd 	for (i = 0; i < MONSTERS; i++) {
    268  1.1      cgd 		mon_tab[i].first_level += (cur_level % 3);
    269  1.1      cgd 	}
    270  1.1      cgd }
    271  1.1      cgd 
    272  1.4    lukem char
    273  1.1      cgd gmc_row_col(row, col)
    274  1.4    lukem 	int row, col;
    275  1.1      cgd {
    276  1.4    lukem 	object *monster;
    277  1.1      cgd 
    278  1.4    lukem 	if ((monster = object_at(&level_monsters, row, col)) != NULL) {
    279  1.1      cgd 		if ((!(detect_monster || see_invisible || r_see_invisible) &&
    280  1.1      cgd 			(monster->m_flags & INVISIBLE)) || blind) {
    281  1.1      cgd 			return(monster->trail_char);
    282  1.1      cgd 		}
    283  1.1      cgd 		if (monster->m_flags & IMITATES) {
    284  1.1      cgd 			return(monster->disguise);
    285  1.1      cgd 		}
    286  1.1      cgd 		return(monster->m_char);
    287  1.1      cgd 	} else {
    288  1.1      cgd 		return('&');	/* BUG if this ever happens */
    289  1.1      cgd 	}
    290  1.1      cgd }
    291  1.1      cgd 
    292  1.4    lukem char
    293  1.1      cgd gmc(monster)
    294  1.4    lukem 	object *monster;
    295  1.1      cgd {
    296  1.1      cgd 	if ((!(detect_monster || see_invisible || r_see_invisible) &&
    297  1.1      cgd 		(monster->m_flags & INVISIBLE))
    298  1.1      cgd 		|| blind) {
    299  1.1      cgd 		return(monster->trail_char);
    300  1.1      cgd 	}
    301  1.1      cgd 	if (monster->m_flags & IMITATES) {
    302  1.1      cgd 		return(monster->disguise);
    303  1.1      cgd 	}
    304  1.1      cgd 	return(monster->m_char);
    305  1.1      cgd }
    306  1.1      cgd 
    307  1.4    lukem void
    308  1.1      cgd mv_1_monster(monster, row, col)
    309  1.4    lukem 	object *monster;
    310  1.4    lukem 	short row, col;
    311  1.1      cgd {
    312  1.1      cgd 	short i, n;
    313  1.1      cgd 	boolean tried[6];
    314  1.1      cgd 
    315  1.1      cgd 	if (monster->m_flags & ASLEEP) {
    316  1.1      cgd 		if (monster->m_flags & NAPPING) {
    317  1.1      cgd 			if (--monster->nap_length <= 0) {
    318  1.1      cgd 				monster->m_flags &= (~(NAPPING | ASLEEP));
    319  1.1      cgd 			}
    320  1.1      cgd 			return;
    321  1.1      cgd 		}
    322  1.1      cgd 		if ((monster->m_flags & WAKENS) &&
    323  1.1      cgd 			 rogue_is_around(monster->row, monster->col) &&
    324  1.1      cgd 			 rand_percent(((stealthy > 0) ?
    325  1.1      cgd 			 	(WAKE_PERCENT / (STEALTH_FACTOR + stealthy)) :
    326  1.1      cgd 				WAKE_PERCENT))) {
    327  1.1      cgd 			wake_up(monster);
    328  1.1      cgd 		}
    329  1.1      cgd 		return;
    330  1.1      cgd 	} else if (monster->m_flags & ALREADY_MOVED) {
    331  1.1      cgd 		monster->m_flags &= (~ALREADY_MOVED);
    332  1.1      cgd 		return;
    333  1.1      cgd 	}
    334  1.1      cgd 	if ((monster->m_flags & FLITS) && flit(monster)) {
    335  1.1      cgd 		return;
    336  1.1      cgd 	}
    337  1.1      cgd 	if ((monster->m_flags & STATIONARY) &&
    338  1.1      cgd 		(!mon_can_go(monster, rogue.row, rogue.col))) {
    339  1.1      cgd 		return;
    340  1.1      cgd 	}
    341  1.1      cgd 	if (monster->m_flags & FREEZING_ROGUE) {
    342  1.1      cgd 		return;
    343  1.1      cgd 	}
    344  1.1      cgd 	if ((monster->m_flags & CONFUSES) && m_confuse(monster)) {
    345  1.1      cgd 		return;
    346  1.1      cgd 	}
    347  1.1      cgd 	if (mon_can_go(monster, rogue.row, rogue.col)) {
    348  1.1      cgd 		mon_hit(monster);
    349  1.1      cgd 		return;
    350  1.1      cgd 	}
    351  1.1      cgd 	if ((monster->m_flags & FLAMES) && flame_broil(monster)) {
    352  1.1      cgd 		return;
    353  1.1      cgd 	}
    354  1.1      cgd 	if ((monster->m_flags & SEEKS_GOLD) && seek_gold(monster)) {
    355  1.1      cgd 		return;
    356  1.1      cgd 	}
    357  1.1      cgd 	if ((monster->trow == monster->row) &&
    358  1.1      cgd 		   (monster->tcol == monster->col)) {
    359  1.1      cgd 		monster->trow = NO_ROOM;
    360  1.1      cgd 	} else if (monster->trow != NO_ROOM) {
    361  1.1      cgd 		row = monster->trow;
    362  1.1      cgd 		col = monster->tcol;
    363  1.1      cgd 	}
    364  1.1      cgd 	if (monster->row > row) {
    365  1.1      cgd 		row = monster->row - 1;
    366  1.1      cgd 	} else if (monster->row < row) {
    367  1.1      cgd 		row = monster->row + 1;
    368  1.1      cgd 	}
    369  1.1      cgd 	if ((dungeon[row][monster->col] & DOOR) &&
    370  1.1      cgd 		 mtry(monster, row, monster->col)) {
    371  1.1      cgd 		return;
    372  1.1      cgd 	}
    373  1.1      cgd 	if (monster->col > col) {
    374  1.1      cgd 		col = monster->col - 1;
    375  1.1      cgd 	} else if (monster->col < col) {
    376  1.1      cgd 		col = monster->col + 1;
    377  1.1      cgd 	}
    378  1.1      cgd 	if ((dungeon[monster->row][col] & DOOR) &&
    379  1.1      cgd 		 mtry(monster, monster->row, col)) {
    380  1.1      cgd 		return;
    381  1.1      cgd 	}
    382  1.1      cgd 	if (mtry(monster, row, col)) {
    383  1.1      cgd 		return;
    384  1.1      cgd 	}
    385  1.1      cgd 
    386  1.1      cgd 	for (i = 0; i <= 5; i++) tried[i] = 0;
    387  1.1      cgd 
    388  1.1      cgd 	for (i = 0; i < 6; i++) {
    389  1.1      cgd NEXT_TRY:	n = get_rand(0, 5);
    390  1.1      cgd 		switch(n) {
    391  1.1      cgd 		case 0:
    392  1.1      cgd 			if (!tried[n] && mtry(monster, row, monster->col-1)) {
    393  1.1      cgd 				goto O;
    394  1.1      cgd 			}
    395  1.1      cgd 			break;
    396  1.1      cgd 		case 1:
    397  1.1      cgd 			if (!tried[n] && mtry(monster, row, monster->col)) {
    398  1.1      cgd 				goto O;
    399  1.1      cgd 			}
    400  1.1      cgd 			break;
    401  1.1      cgd 		case 2:
    402  1.1      cgd 			if (!tried[n] && mtry(monster, row, monster->col+1)) {
    403  1.1      cgd 				goto O;
    404  1.1      cgd 			}
    405  1.1      cgd 			break;
    406  1.1      cgd 		case 3:
    407  1.1      cgd 			if (!tried[n] && mtry(monster, monster->row-1, col)) {
    408  1.1      cgd 				goto O;
    409  1.1      cgd 			}
    410  1.1      cgd 			break;
    411  1.1      cgd 		case 4:
    412  1.1      cgd 			if (!tried[n] && mtry(monster, monster->row, col)) {
    413  1.1      cgd 				goto O;
    414  1.1      cgd 			}
    415  1.1      cgd 			break;
    416  1.1      cgd 		case 5:
    417  1.1      cgd 			if (!tried[n] && mtry(monster, monster->row+1, col)) {
    418  1.1      cgd 				goto O;
    419  1.1      cgd 			}
    420  1.1      cgd 			break;
    421  1.1      cgd 		}
    422  1.1      cgd 		if (!tried[n]) {
    423  1.1      cgd 			tried[n] = 1;
    424  1.1      cgd 		} else {
    425  1.1      cgd 			goto NEXT_TRY;
    426  1.1      cgd 		}
    427  1.1      cgd 	}
    428  1.1      cgd O:
    429  1.1      cgd 	if ((monster->row == monster->o_row) && (monster->col == monster->o_col)) {
    430  1.1      cgd 		if (++(monster->o) > 4) {
    431  1.1      cgd 			if ((monster->trow == NO_ROOM) &&
    432  1.1      cgd 					(!mon_sees(monster, rogue.row, rogue.col))) {
    433  1.1      cgd 				monster->trow = get_rand(1, (DROWS - 2));
    434  1.1      cgd 				monster->tcol = get_rand(0, (DCOLS - 1));
    435  1.1      cgd 			} else {
    436  1.1      cgd 				monster->trow = NO_ROOM;
    437  1.1      cgd 				monster->o = 0;
    438  1.1      cgd 			}
    439  1.1      cgd 		}
    440  1.1      cgd 	} else {
    441  1.1      cgd 		monster->o_row = monster->row;
    442  1.1      cgd 		monster->o_col = monster->col;
    443  1.1      cgd 		monster->o = 0;
    444  1.1      cgd 	}
    445  1.1      cgd }
    446  1.1      cgd 
    447  1.4    lukem int
    448  1.1      cgd mtry(monster, row, col)
    449  1.4    lukem 	object *monster;
    450  1.4    lukem 	short row, col;
    451  1.1      cgd {
    452  1.1      cgd 	if (mon_can_go(monster, row, col)) {
    453  1.1      cgd 		move_mon_to(monster, row, col);
    454  1.1      cgd 		return(1);
    455  1.1      cgd 	}
    456  1.1      cgd 	return(0);
    457  1.1      cgd }
    458  1.1      cgd 
    459  1.4    lukem void
    460  1.1      cgd move_mon_to(monster, row, col)
    461  1.4    lukem 	object *monster;
    462  1.4    lukem 	short row, col;
    463  1.1      cgd {
    464  1.1      cgd 	short c;
    465  1.4    lukem 	int mrow, mcol;
    466  1.1      cgd 
    467  1.1      cgd 	mrow = monster->row;
    468  1.1      cgd 	mcol = monster->col;
    469  1.1      cgd 
    470  1.1      cgd 	dungeon[mrow][mcol] &= ~MONSTER;
    471  1.1      cgd 	dungeon[row][col] |= MONSTER;
    472  1.1      cgd 
    473  1.1      cgd 	c = mvinch(mrow, mcol);
    474  1.1      cgd 
    475  1.1      cgd 	if ((c >= 'A') && (c <= 'Z')) {
    476  1.1      cgd 		if (!detect_monster) {
    477  1.1      cgd 			mvaddch(mrow, mcol, monster->trail_char);
    478  1.1      cgd 		} else {
    479  1.1      cgd 			if (rogue_can_see(mrow, mcol)) {
    480  1.1      cgd 				mvaddch(mrow, mcol, monster->trail_char);
    481  1.1      cgd 			} else {
    482  1.1      cgd 				if (monster->trail_char == '.') {
    483  1.1      cgd 					monster->trail_char = ' ';
    484  1.1      cgd 				}
    485  1.1      cgd 				mvaddch(mrow, mcol, monster->trail_char);
    486  1.1      cgd 			}
    487  1.1      cgd 		}
    488  1.1      cgd 	}
    489  1.1      cgd 	monster->trail_char = mvinch(row, col);
    490  1.1      cgd 	if (!blind && (detect_monster || rogue_can_see(row, col))) {
    491  1.1      cgd 		if ((!(monster->m_flags & INVISIBLE) ||
    492  1.1      cgd 			(detect_monster || see_invisible || r_see_invisible))) {
    493  1.1      cgd 			mvaddch(row, col, gmc(monster));
    494  1.1      cgd 		}
    495  1.1      cgd 	}
    496  1.1      cgd 	if ((dungeon[row][col] & DOOR) &&
    497  1.1      cgd 		(get_room_number(row, col) != cur_room) &&
    498  1.1      cgd 		(dungeon[mrow][mcol] == FLOOR) && !blind) {
    499  1.1      cgd 			mvaddch(mrow, mcol, ' ');
    500  1.1      cgd 	}
    501  1.1      cgd 	if (dungeon[row][col] & DOOR) {
    502  1.1      cgd 			dr_course(monster, ((dungeon[mrow][mcol] & TUNNEL) ? 1 : 0),
    503  1.1      cgd 				row, col);
    504  1.1      cgd 	} else {
    505  1.1      cgd 		monster->row = row;
    506  1.1      cgd 		monster->col = col;
    507  1.1      cgd 	}
    508  1.1      cgd }
    509  1.1      cgd 
    510  1.4    lukem int
    511  1.1      cgd mon_can_go(monster, row, col)
    512  1.4    lukem 	object *monster;
    513  1.4    lukem 	short row, col;
    514  1.1      cgd {
    515  1.1      cgd 	object *obj;
    516  1.1      cgd 	short dr, dc;
    517  1.1      cgd 
    518  1.1      cgd 	dr = monster->row - row;	/* check if move distance > 1 */
    519  1.1      cgd 	if ((dr >= 2) || (dr <= -2)) {
    520  1.1      cgd 		return(0);
    521  1.1      cgd 	}
    522  1.1      cgd 	dc = monster->col - col;
    523  1.1      cgd 	if ((dc >= 2) || (dc <= -2)) {
    524  1.1      cgd 		return(0);
    525  1.1      cgd 	}
    526  1.1      cgd 	if ((!dungeon[monster->row][col]) || (!dungeon[row][monster->col])) {
    527  1.1      cgd 		return(0);
    528  1.1      cgd 	}
    529  1.1      cgd 	if ((!is_passable(row, col)) || (dungeon[row][col] & MONSTER)) {
    530  1.1      cgd 		return(0);
    531  1.1      cgd 	}
    532  1.1      cgd 	if ((monster->row!=row)&&(monster->col!=col)&&((dungeon[row][col]&DOOR) ||
    533  1.1      cgd 		(dungeon[monster->row][monster->col]&DOOR))) {
    534  1.1      cgd 		return(0);
    535  1.1      cgd 	}
    536  1.1      cgd 	if (!(monster->m_flags & (FLITS | CONFUSED | CAN_FLIT)) &&
    537  1.1      cgd 		(monster->trow == NO_ROOM)) {
    538  1.1      cgd 		if ((monster->row < rogue.row) && (row < monster->row)) return(0);
    539  1.1      cgd 		if ((monster->row > rogue.row) && (row > monster->row)) return(0);
    540  1.1      cgd 		if ((monster->col < rogue.col) && (col < monster->col)) return(0);
    541  1.1      cgd 		if ((monster->col > rogue.col) && (col > monster->col)) return(0);
    542  1.1      cgd 	}
    543  1.1      cgd 	if (dungeon[row][col] & OBJECT) {
    544  1.1      cgd 		obj = object_at(&level_objects, row, col);
    545  1.1      cgd 		if ((obj->what_is == SCROL) && (obj->which_kind == SCARE_MONSTER)) {
    546  1.1      cgd 			return(0);
    547  1.1      cgd 		}
    548  1.1      cgd 	}
    549  1.1      cgd 	return(1);
    550  1.1      cgd }
    551  1.1      cgd 
    552  1.4    lukem void
    553  1.1      cgd wake_up(monster)
    554  1.4    lukem 	object *monster;
    555  1.1      cgd {
    556  1.1      cgd 	if (!(monster->m_flags & NAPPING)) {
    557  1.1      cgd 		monster->m_flags &= (~(ASLEEP | IMITATES | WAKENS));
    558  1.1      cgd 	}
    559  1.1      cgd }
    560  1.1      cgd 
    561  1.4    lukem void
    562  1.1      cgd wake_room(rn, entering, row, col)
    563  1.4    lukem 	short rn;
    564  1.4    lukem 	boolean entering;
    565  1.4    lukem 	short row, col;
    566  1.1      cgd {
    567  1.1      cgd 	object *monster;
    568  1.1      cgd 	short wake_percent;
    569  1.1      cgd 	boolean in_room;
    570  1.1      cgd 
    571  1.1      cgd 	wake_percent = (rn == party_room) ? PARTY_WAKE_PERCENT : WAKE_PERCENT;
    572  1.1      cgd 	if (stealthy > 0) {
    573  1.1      cgd 		wake_percent /= (STEALTH_FACTOR + stealthy);
    574  1.1      cgd 	}
    575  1.1      cgd 
    576  1.1      cgd 	monster = level_monsters.next_monster;
    577  1.1      cgd 
    578  1.1      cgd 	while (monster) {
    579  1.1      cgd 		in_room = (rn == get_room_number(monster->row, monster->col));
    580  1.1      cgd 		if (in_room) {
    581  1.1      cgd 			if (entering) {
    582  1.1      cgd 				monster->trow = NO_ROOM;
    583  1.1      cgd 			} else {
    584  1.1      cgd 				monster->trow = row;
    585  1.1      cgd 				monster->tcol = col;
    586  1.1      cgd 			}
    587  1.1      cgd 		}
    588  1.1      cgd 		if ((monster->m_flags & WAKENS) &&
    589  1.1      cgd 			(rn == get_room_number(monster->row, monster->col))) {
    590  1.1      cgd 			if (rand_percent(wake_percent)) {
    591  1.1      cgd 				wake_up(monster);
    592  1.1      cgd 			}
    593  1.1      cgd 		}
    594  1.1      cgd 		monster = monster->next_monster;
    595  1.1      cgd 	}
    596  1.1      cgd }
    597  1.1      cgd 
    598  1.1      cgd char *
    599  1.1      cgd mon_name(monster)
    600  1.4    lukem 	object *monster;
    601  1.1      cgd {
    602  1.1      cgd 	short ch;
    603  1.1      cgd 
    604  1.1      cgd 	if (blind || ((monster->m_flags & INVISIBLE) &&
    605  1.1      cgd 		!(detect_monster || see_invisible || r_see_invisible))) {
    606  1.1      cgd 		return("something");
    607  1.1      cgd 	}
    608  1.1      cgd 	if (halluc) {
    609  1.1      cgd 		ch = get_rand('A', 'Z') - 'A';
    610  1.1      cgd 		return(m_names[ch]);
    611  1.1      cgd 	}
    612  1.1      cgd 	ch = monster->m_char - 'A';
    613  1.1      cgd 	return(m_names[ch]);
    614  1.1      cgd }
    615  1.1      cgd 
    616  1.4    lukem int
    617  1.1      cgd rogue_is_around(row, col)
    618  1.4    lukem 	int row, col;
    619  1.1      cgd {
    620  1.1      cgd 	short rdif, cdif, retval;
    621  1.1      cgd 
    622  1.1      cgd 	rdif = row - rogue.row;
    623  1.1      cgd 	cdif = col - rogue.col;
    624  1.1      cgd 
    625  1.1      cgd 	retval = (rdif >= -1) && (rdif <= 1) && (cdif >= -1) && (cdif <= 1);
    626  1.1      cgd 	return(retval);
    627  1.1      cgd }
    628  1.1      cgd 
    629  1.4    lukem void
    630  1.1      cgd wanderer()
    631  1.1      cgd {
    632  1.1      cgd 	object *monster;
    633  1.1      cgd 	short row, col, i;
    634  1.1      cgd 	boolean found = 0;
    635  1.1      cgd 
    636  1.1      cgd 	for (i = 0; ((i < 15) && (!found)); i++) {
    637  1.1      cgd 		monster = gr_monster((object *) 0, 0);
    638  1.1      cgd 		if (!(monster->m_flags & (WAKENS | WANDERS))) {
    639  1.1      cgd 			free_object(monster);
    640  1.1      cgd 		} else {
    641  1.1      cgd 			found = 1;
    642  1.1      cgd 		}
    643  1.1      cgd 	}
    644  1.1      cgd 	if (found) {
    645  1.1      cgd 		found = 0;
    646  1.1      cgd 		wake_up(monster);
    647  1.1      cgd 		for (i = 0; ((i < 25) && (!found)); i++) {
    648  1.1      cgd 			gr_row_col(&row, &col, (FLOOR | TUNNEL | STAIRS | OBJECT));
    649  1.1      cgd 			if (!rogue_can_see(row, col)) {
    650  1.1      cgd 				put_m_at(row, col, monster);
    651  1.1      cgd 				found = 1;
    652  1.1      cgd 			}
    653  1.1      cgd 		}
    654  1.1      cgd 		if (!found) {
    655  1.1      cgd 			free_object(monster);
    656  1.1      cgd 		}
    657  1.1      cgd 	}
    658  1.1      cgd }
    659  1.1      cgd 
    660  1.4    lukem void
    661  1.1      cgd show_monsters()
    662  1.1      cgd {
    663  1.1      cgd 	object *monster;
    664  1.1      cgd 
    665  1.1      cgd 	detect_monster = 1;
    666  1.1      cgd 
    667  1.1      cgd 	if (blind) {
    668  1.1      cgd 		return;
    669  1.1      cgd 	}
    670  1.1      cgd 	monster = level_monsters.next_monster;
    671  1.1      cgd 
    672  1.1      cgd 	while (monster) {
    673  1.1      cgd 		mvaddch(monster->row, monster->col, monster->m_char);
    674  1.1      cgd 		if (monster->m_flags & IMITATES) {
    675  1.1      cgd 			monster->m_flags &= (~IMITATES);
    676  1.1      cgd 			monster->m_flags |= WAKENS;
    677  1.1      cgd 		}
    678  1.1      cgd 		monster = monster->next_monster;
    679  1.1      cgd 	}
    680  1.1      cgd }
    681  1.1      cgd 
    682  1.4    lukem void
    683  1.1      cgd create_monster()
    684  1.1      cgd {
    685  1.1      cgd 	short row, col;
    686  1.1      cgd 	short i;
    687  1.1      cgd 	boolean found = 0;
    688  1.1      cgd 	object *monster;
    689  1.1      cgd 
    690  1.1      cgd 	row = rogue.row;
    691  1.1      cgd 	col = rogue.col;
    692  1.1      cgd 
    693  1.1      cgd 	for (i = 0; i < 9; i++) {
    694  1.1      cgd 		rand_around(i, &row, &col);
    695  1.1      cgd 		if (((row == rogue.row) && (col = rogue.col)) ||
    696  1.1      cgd 				(row < MIN_ROW) || (row > (DROWS-2)) ||
    697  1.1      cgd 				(col < 0) || (col > (DCOLS-1))) {
    698  1.1      cgd 			continue;
    699  1.1      cgd 		}
    700  1.1      cgd 		if ((!(dungeon[row][col] & MONSTER)) &&
    701  1.1      cgd 			  (dungeon[row][col] & (FLOOR|TUNNEL|STAIRS|DOOR))) {
    702  1.1      cgd 			found = 1;
    703  1.1      cgd 			break;
    704  1.1      cgd 		}
    705  1.1      cgd 	}
    706  1.1      cgd 	if (found) {
    707  1.1      cgd 		monster = gr_monster((object *) 0, 0);
    708  1.1      cgd 		put_m_at(row, col, monster);
    709  1.1      cgd 		mvaddch(row, col, gmc(monster));
    710  1.1      cgd 		if (monster->m_flags & (WANDERS | WAKENS)) {
    711  1.1      cgd 			wake_up(monster);
    712  1.1      cgd 		}
    713  1.1      cgd 	} else {
    714  1.1      cgd 		message("you hear a faint cry of anguish in the distance", 0);
    715  1.1      cgd 	}
    716  1.1      cgd }
    717  1.1      cgd 
    718  1.4    lukem void
    719  1.1      cgd put_m_at(row, col, monster)
    720  1.4    lukem 	short row, col;
    721  1.4    lukem 	object *monster;
    722  1.1      cgd {
    723  1.1      cgd 	monster->row = row;
    724  1.1      cgd 	monster->col = col;
    725  1.1      cgd 	dungeon[row][col] |= MONSTER;
    726  1.1      cgd 	monster->trail_char = mvinch(row, col);
    727  1.1      cgd 	(void) add_to_pack(monster, &level_monsters, 0);
    728  1.1      cgd 	aim_monster(monster);
    729  1.1      cgd }
    730  1.1      cgd 
    731  1.4    lukem void
    732  1.1      cgd aim_monster(monster)
    733  1.4    lukem 	object *monster;
    734  1.1      cgd {
    735  1.1      cgd 	short i, rn, d, r;
    736  1.1      cgd 
    737  1.1      cgd 	rn = get_room_number(monster->row, monster->col);
    738  1.1      cgd 	r = get_rand(0, 12);
    739  1.1      cgd 
    740  1.1      cgd 	for (i = 0; i < 4; i++) {
    741  1.1      cgd 		d = (r + i) % 4;
    742  1.1      cgd 		if (rooms[rn].doors[d].oth_room != NO_ROOM) {
    743  1.1      cgd 			monster->trow = rooms[rn].doors[d].door_row;
    744  1.1      cgd 			monster->tcol = rooms[rn].doors[d].door_col;
    745  1.1      cgd 			break;
    746  1.1      cgd 		}
    747  1.1      cgd 	}
    748  1.1      cgd }
    749  1.1      cgd 
    750  1.4    lukem int
    751  1.1      cgd rogue_can_see(row, col)
    752  1.4    lukem 	int row, col;
    753  1.1      cgd {
    754  1.4    lukem 	int retval;
    755  1.1      cgd 
    756  1.1      cgd 	retval = !blind &&
    757  1.1      cgd 			(((get_room_number(row, col) == cur_room) &&
    758  1.1      cgd 					!(rooms[cur_room].is_room & R_MAZE)) ||
    759  1.1      cgd 			rogue_is_around(row, col));
    760  1.1      cgd 
    761  1.1      cgd 	return(retval);
    762  1.1      cgd }
    763  1.1      cgd 
    764  1.4    lukem int
    765  1.1      cgd move_confused(monster)
    766  1.4    lukem 	object *monster;
    767  1.1      cgd {
    768  1.1      cgd 	short i, row, col;
    769  1.1      cgd 
    770  1.1      cgd 	if (!(monster->m_flags & ASLEEP)) {
    771  1.1      cgd 		if (--monster->moves_confused <= 0) {
    772  1.1      cgd 			monster->m_flags &= (~CONFUSED);
    773  1.1      cgd 		}
    774  1.1      cgd 		if (monster->m_flags & STATIONARY) {
    775  1.1      cgd 			return(coin_toss() ? 1 : 0);
    776  1.1      cgd 		} else if (rand_percent(15)) {
    777  1.1      cgd 			return(1);
    778  1.1      cgd 		}
    779  1.1      cgd 		row = monster->row;
    780  1.1      cgd 		col = monster->col;
    781  1.1      cgd 
    782  1.1      cgd 		for (i = 0; i < 9; i++) {
    783  1.1      cgd 			rand_around(i, &row, &col);
    784  1.1      cgd 			if ((row == rogue.row) && (col == rogue.col)) {
    785  1.1      cgd 				return(0);
    786  1.1      cgd 			}
    787  1.1      cgd 			if (mtry(monster, row, col)) {
    788  1.1      cgd 				return(1);
    789  1.1      cgd 			}
    790  1.1      cgd 		}
    791  1.1      cgd 	}
    792  1.1      cgd 	return(0);
    793  1.1      cgd }
    794  1.1      cgd 
    795  1.4    lukem int
    796  1.1      cgd flit(monster)
    797  1.4    lukem 	object *monster;
    798  1.1      cgd {
    799  1.1      cgd 	short i, row, col;
    800  1.1      cgd 
    801  1.1      cgd 	if (!rand_percent(FLIT_PERCENT + ((monster->m_flags & FLIES) ? 20 : 0))) {
    802  1.1      cgd 		return(0);
    803  1.1      cgd 	}
    804  1.1      cgd 	if (rand_percent(10)) {
    805  1.1      cgd 		return(1);
    806  1.1      cgd 	}
    807  1.1      cgd 	row = monster->row;
    808  1.1      cgd 	col = monster->col;
    809  1.1      cgd 
    810  1.1      cgd 	for (i = 0; i < 9; i++) {
    811  1.1      cgd 		rand_around(i, &row, &col);
    812  1.1      cgd 		if ((row == rogue.row) && (col == rogue.col)) {
    813  1.1      cgd 			continue;
    814  1.1      cgd 		}
    815  1.1      cgd 		if (mtry(monster, row, col)) {
    816  1.1      cgd 			return(1);
    817  1.1      cgd 		}
    818  1.1      cgd 	}
    819  1.1      cgd 	return(1);
    820  1.1      cgd }
    821  1.1      cgd 
    822  1.4    lukem char
    823  1.1      cgd gr_obj_char()
    824  1.1      cgd {
    825  1.1      cgd 	short r;
    826  1.1      cgd 	char *rs = "%!?]=/):*";
    827  1.1      cgd 
    828  1.1      cgd 	r = get_rand(0, 8);
    829  1.1      cgd 
    830  1.1      cgd 	return(rs[r]);
    831  1.1      cgd }
    832  1.1      cgd 
    833  1.4    lukem int
    834  1.1      cgd no_room_for_monster(rn)
    835  1.4    lukem 	int rn;
    836  1.1      cgd {
    837  1.1      cgd 	short i, j;
    838  1.1      cgd 
    839  1.1      cgd 	for (i = rooms[rn].top_row+1; i < rooms[rn].bottom_row; i++) {
    840  1.1      cgd 		for (j = rooms[rn].left_col+1; j < rooms[rn].right_col; j++) {
    841  1.1      cgd 			if (!(dungeon[i][j] & MONSTER)) {
    842  1.1      cgd 				return(0);
    843  1.1      cgd 			}
    844  1.1      cgd 		}
    845  1.1      cgd 	}
    846  1.1      cgd 	return(1);
    847  1.1      cgd }
    848  1.1      cgd 
    849  1.4    lukem void
    850  1.1      cgd aggravate()
    851  1.1      cgd {
    852  1.1      cgd 	object *monster;
    853  1.1      cgd 
    854  1.1      cgd 	message("you hear a high pitched humming noise", 0);
    855  1.1      cgd 
    856  1.1      cgd 	monster = level_monsters.next_monster;
    857  1.1      cgd 
    858  1.1      cgd 	while (monster) {
    859  1.1      cgd 		wake_up(monster);
    860  1.1      cgd 		monster->m_flags &= (~IMITATES);
    861  1.1      cgd 		if (rogue_can_see(monster->row, monster->col)) {
    862  1.1      cgd 			mvaddch(monster->row, monster->col, monster->m_char);
    863  1.1      cgd 		}
    864  1.1      cgd 		monster = monster->next_monster;
    865  1.1      cgd 	}
    866  1.1      cgd }
    867  1.1      cgd 
    868  1.1      cgd boolean
    869  1.1      cgd mon_sees(monster, row, col)
    870  1.4    lukem 	object *monster;
    871  1.6  hubertf 	int row, col;
    872  1.1      cgd {
    873  1.1      cgd 	short rn, rdif, cdif, retval;
    874  1.1      cgd 
    875  1.1      cgd 	rn = get_room_number(row, col);
    876  1.1      cgd 
    877  1.1      cgd 	if (	(rn != NO_ROOM) &&
    878  1.1      cgd 			(rn == get_room_number(monster->row, monster->col)) &&
    879  1.1      cgd 			!(rooms[rn].is_room & R_MAZE)) {
    880  1.1      cgd 		return(1);
    881  1.1      cgd 	}
    882  1.1      cgd 	rdif = row - monster->row;
    883  1.1      cgd 	cdif = col - monster->col;
    884  1.1      cgd 
    885  1.1      cgd 	retval = (rdif >= -1) && (rdif <= 1) && (cdif >= -1) && (cdif <= 1);
    886  1.1      cgd 	return(retval);
    887  1.1      cgd }
    888  1.1      cgd 
    889  1.4    lukem void
    890  1.1      cgd mv_aquatars()
    891  1.1      cgd {
    892  1.1      cgd 	object *monster;
    893  1.1      cgd 
    894  1.1      cgd 	monster = level_monsters.next_monster;
    895  1.1      cgd 
    896  1.1      cgd 	while (monster) {
    897  1.1      cgd 		if ((monster->m_char == 'A') &&
    898  1.1      cgd 			mon_can_go(monster, rogue.row, rogue.col)) {
    899  1.1      cgd 			mv_1_monster(monster, rogue.row, rogue.col);
    900  1.1      cgd 			monster->m_flags |= ALREADY_MOVED;
    901  1.1      cgd 		}
    902  1.1      cgd 		monster = monster->next_monster;
    903  1.1      cgd 	}
    904  1.1      cgd }
    905