Home | History | Annotate | Line # | Download | only in rogue
      1  1.18    hgutch /*	$NetBSD: monster.c,v 1.18 2025/04/07 14:36:28 hgutch 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.8       agc  * 3. Neither the name of the University nor the names of its contributors
     19   1.1       cgd  *    may be used to endorse or promote products derived from this software
     20   1.1       cgd  *    without specific prior written permission.
     21   1.1       cgd  *
     22   1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23   1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24   1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25   1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26   1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27   1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28   1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29   1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30   1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31   1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32   1.1       cgd  * SUCH DAMAGE.
     33   1.1       cgd  */
     34   1.1       cgd 
     35   1.4     lukem #include <sys/cdefs.h>
     36   1.1       cgd #ifndef lint
     37   1.3       cgd #if 0
     38   1.3       cgd static char sccsid[] = "@(#)monster.c	8.1 (Berkeley) 5/31/93";
     39   1.3       cgd #else
     40  1.18    hgutch __RCSID("$NetBSD: monster.c,v 1.18 2025/04/07 14:36:28 hgutch Exp $");
     41   1.3       cgd #endif
     42   1.1       cgd #endif /* not lint */
     43   1.1       cgd 
     44   1.1       cgd /*
     45   1.1       cgd  * monster.c
     46   1.1       cgd  *
     47   1.1       cgd  * This source herein may be modified and/or distributed by anybody who
     48   1.1       cgd  * so desires, with the following restrictions:
     49   1.1       cgd  *    1.)  No portion of this notice shall be removed.
     50   1.1       cgd  *    2.)  Credit shall not be taken for the creation of this source.
     51   1.1       cgd  *    3.)  This code is not to be traded, sold, or used for personal
     52   1.1       cgd  *         gain or profit.
     53   1.1       cgd  *
     54   1.1       cgd  */
     55   1.1       cgd 
     56   1.1       cgd #include "rogue.h"
     57   1.1       cgd 
     58   1.1       cgd object level_monsters;
     59   1.1       cgd boolean mon_disappeared;
     60   1.1       cgd 
     61   1.7   hubertf const char *const m_names[] = {
     62   1.1       cgd 	"aquator",
     63   1.1       cgd 	"bat",
     64   1.1       cgd 	"centaur",
     65   1.1       cgd 	"dragon",
     66   1.1       cgd 	"emu",
     67   1.1       cgd 	"venus fly-trap",
     68   1.1       cgd 	"griffin",
     69   1.1       cgd 	"hobgoblin",
     70   1.1       cgd 	"ice monster",
     71   1.1       cgd 	"jabberwock",
     72   1.1       cgd 	"kestrel",
     73   1.1       cgd 	"leprechaun",
     74   1.1       cgd 	"medusa",
     75   1.1       cgd 	"nymph",
     76   1.1       cgd 	"orc",
     77   1.1       cgd 	"phantom",
     78   1.1       cgd 	"quagga",
     79   1.1       cgd 	"rattlesnake",
     80   1.1       cgd 	"snake",
     81   1.1       cgd 	"troll",
     82   1.1       cgd 	"black unicorn",
     83   1.1       cgd 	"vampire",
     84   1.1       cgd 	"wraith",
     85   1.1       cgd 	"xeroc",
     86   1.1       cgd 	"yeti",
     87   1.1       cgd 	"zombie"
     88   1.1       cgd };
     89   1.1       cgd 
     90  1.17  dholland #define FILL 0,0,0,0,0,0,0,0,0,0,0,0,0,NULL
     91  1.17  dholland 
     92  1.14  dholland static object mon_tab[MONSTERS] = {
     93  1.17  dholland 	{(ASLEEP|WAKENS|WANDERS|RUSTS),"0d0",25,'A',20,9,18,100,0,0, FILL},
     94  1.17  dholland 	{(ASLEEP|WANDERS|FLITS|FLIES),"1d3",10,'B',2,1,8,60,0,0, FILL},
     95  1.17  dholland 	{(ASLEEP|WANDERS),"3d3/2d5",32,'C',15,7,16,85,0,10, FILL},
     96  1.17  dholland 	{(ASLEEP|WAKENS|FLAMES),"4d6/4d9",145,'D',5000,21,126,100,0,90, FILL},
     97  1.17  dholland 	{(ASLEEP|WAKENS),"1d3",11,'E',2,1,7,65,0,0, FILL},
     98  1.17  dholland 	{(HOLDS|STATIONARY),"5d5",73,'F',91,12,126,80,0,0, FILL},
     99   1.1       cgd 	{(ASLEEP|WAKENS|WANDERS|FLIES),"5d5/5d5",115,'G',
    100  1.17  dholland 			2000,20,126,85,0,10, FILL},
    101  1.17  dholland 	{(ASLEEP|WAKENS|WANDERS),"1d3/1d2",15,'H',3,1,10,67,0,0, FILL},
    102  1.17  dholland 	{(ASLEEP|FREEZES),"0d0",15,'I',5,2,11,68,0,0, FILL},
    103  1.17  dholland 	{(ASLEEP|WANDERS),"3d10/4d5",132,'J',3000,21,126,100,0,0, FILL},
    104  1.17  dholland 	{(ASLEEP|WAKENS|WANDERS|FLIES),"1d4",10,'K',2,1,6,60,0,0, FILL},
    105  1.17  dholland 	{(ASLEEP|STEALS_GOLD),"0d0",25,'L',21,6,16,75,0,0, FILL},
    106   1.1       cgd 	{(ASLEEP|WAKENS|WANDERS|CONFUSES),"4d4/3d7",97,'M',
    107  1.17  dholland 			250,18,126,85,0,25, FILL},
    108  1.17  dholland 	{(ASLEEP|STEALS_ITEM),"0d0",25,'N',39,10,19,75,0,100, FILL},
    109  1.17  dholland 	{(ASLEEP|WANDERS|WAKENS|SEEKS_GOLD),"1d6",25,'O',5,4,13,70,0,10, FILL},
    110  1.17  dholland 	{(ASLEEP|INVISIBLE|WANDERS|FLITS),"5d4",76,'P',120,15,24,80,0,50, FILL},
    111  1.17  dholland 	{(ASLEEP|WAKENS|WANDERS),"3d5",30,'Q',20,8,17,78,0,20, FILL},
    112  1.17  dholland 	{(ASLEEP|WAKENS|WANDERS|STINGS),"2d5",19,'R',10,3,12,70,0,0, FILL},
    113  1.17  dholland 	{(ASLEEP|WAKENS|WANDERS),"1d3",8,'S',2,1,9,50,0,0, FILL},
    114  1.17  dholland 	{(ASLEEP|WAKENS|WANDERS),"4d6/1d4",75,'T',125,13,22,75,0,33, FILL},
    115   1.1       cgd 	{(ASLEEP|WAKENS|WANDERS),"4d10",90,'U',
    116  1.17  dholland 			200,17,26,85,0,33, FILL},
    117   1.1       cgd 	{(ASLEEP|WAKENS|WANDERS|DRAINS_LIFE),"1d14/1d4",55,'V',
    118  1.17  dholland 			350,19,126,85,0,18, FILL},
    119  1.17  dholland 	{(ASLEEP|WANDERS|DROPS_LEVEL),"2d8",45,'W',55,14,23,75,0,0, FILL},
    120  1.17  dholland 	{(ASLEEP|IMITATES),"4d6",42,'X',110,16,25,75,0,0, FILL},
    121  1.17  dholland 	{(ASLEEP|WANDERS),"3d6",35,'Y',50,11,20,80,0,20, FILL},
    122  1.17  dholland 	{(ASLEEP|WAKENS|WANDERS),"1d7",21,'Z',8,5,14,69,0,0, FILL}
    123   1.1       cgd };
    124   1.1       cgd 
    125  1.15  dholland static void aim_monster(object *);
    126  1.15  dholland static int flit(object *);
    127  1.15  dholland static int move_confused(object *);
    128  1.15  dholland static int mtry(object *, short, short);
    129  1.15  dholland static int no_room_for_monster(int);
    130  1.15  dholland static void put_m_at(short, short, object *);
    131  1.15  dholland static int rogue_is_around(int, int);
    132  1.15  dholland 
    133   1.4     lukem void
    134  1.18    hgutch set_monster_damage(object *obj)
    135  1.18    hgutch {
    136  1.18    hgutch 	for (short i = 0; i < MONSTERS; i++) {
    137  1.18    hgutch 		if (obj->ichar == mon_tab[i].ichar) {
    138  1.18    hgutch 			obj->damage = mon_tab[i].damage;
    139  1.18    hgutch 			break;
    140  1.18    hgutch 		}
    141  1.18    hgutch 	}
    142  1.18    hgutch }
    143  1.18    hgutch 
    144  1.18    hgutch void
    145  1.14  dholland put_mons(void)
    146   1.1       cgd {
    147   1.1       cgd 	short i;
    148   1.1       cgd 	short n;
    149   1.1       cgd 	object *monster;
    150   1.1       cgd 	short row, col;
    151   1.1       cgd 
    152   1.1       cgd 	n = get_rand(4, 6);
    153   1.1       cgd 
    154   1.1       cgd 	for (i = 0; i < n; i++) {
    155  1.14  dholland 		monster = gr_monster(NULL, 0);
    156   1.1       cgd 		if ((monster->m_flags & WANDERS) && coin_toss()) {
    157   1.1       cgd 			wake_up(monster);
    158   1.1       cgd 		}
    159   1.1       cgd 		gr_row_col(&row, &col, (FLOOR | TUNNEL | STAIRS | OBJECT));
    160   1.1       cgd 		put_m_at(row, col, monster);
    161   1.1       cgd 	}
    162   1.1       cgd }
    163   1.1       cgd 
    164   1.1       cgd object *
    165  1.14  dholland gr_monster(object *monster, int mn)
    166   1.1       cgd {
    167   1.1       cgd 	if (!monster) {
    168   1.1       cgd 		monster = alloc_object();
    169   1.1       cgd 
    170   1.1       cgd 		for (;;) {
    171   1.1       cgd 			mn = get_rand(0, MONSTERS-1);
    172   1.1       cgd 			if ((cur_level >= mon_tab[mn].first_level) &&
    173   1.1       cgd 			(cur_level <= mon_tab[mn].last_level)) {
    174   1.1       cgd 				break;
    175   1.1       cgd 			}
    176   1.1       cgd 		}
    177   1.1       cgd 	}
    178   1.1       cgd 	*monster = mon_tab[mn];
    179   1.1       cgd 	if (monster->m_flags & IMITATES) {
    180   1.1       cgd 		monster->disguise = gr_obj_char();
    181   1.1       cgd 	}
    182   1.1       cgd 	if (cur_level > (AMULET_LEVEL + 2)) {
    183   1.1       cgd 		monster->m_flags |= HASTED;
    184   1.1       cgd 	}
    185   1.1       cgd 	monster->trow = NO_ROOM;
    186   1.1       cgd 	return(monster);
    187   1.1       cgd }
    188   1.1       cgd 
    189   1.4     lukem void
    190  1.14  dholland mv_mons(void)
    191   1.1       cgd {
    192   1.5   hubertf 	object *monster, *next_monster, *test_mons;
    193   1.1       cgd 	boolean flew;
    194   1.1       cgd 
    195   1.1       cgd 	if (haste_self % 2) {
    196   1.1       cgd 		return;
    197   1.1       cgd 	}
    198   1.1       cgd 
    199   1.1       cgd 	monster = level_monsters.next_monster;
    200   1.1       cgd 
    201   1.1       cgd 	while (monster) {
    202   1.1       cgd 		next_monster = monster->next_monster;
    203   1.1       cgd 		mon_disappeared = 0;
    204   1.1       cgd 		if (monster->m_flags & HASTED) {
    205   1.1       cgd 			mv_1_monster(monster, rogue.row, rogue.col);
    206   1.1       cgd 			if (mon_disappeared) {
    207   1.1       cgd 				goto NM;
    208   1.1       cgd 			}
    209   1.1       cgd 		} else if (monster->m_flags & SLOWED) {
    210   1.1       cgd 			monster->slowed_toggle = !monster->slowed_toggle;
    211   1.1       cgd 			if (monster->slowed_toggle) {
    212   1.1       cgd 				goto NM;
    213   1.1       cgd 			}
    214   1.1       cgd 		}
    215   1.1       cgd 		if ((monster->m_flags & CONFUSED) && move_confused(monster)) {
    216   1.1       cgd 			goto NM;
    217   1.1       cgd 		}
    218   1.1       cgd 		flew = 0;
    219   1.1       cgd 		if (	(monster->m_flags & FLIES) &&
    220   1.1       cgd 				!(monster->m_flags & NAPPING) &&
    221   1.1       cgd 				!mon_can_go(monster, rogue.row, rogue.col)) {
    222   1.1       cgd 			flew = 1;
    223   1.1       cgd 			mv_1_monster(monster, rogue.row, rogue.col);
    224   1.1       cgd 			if (mon_disappeared) {
    225   1.1       cgd 				goto NM;
    226   1.1       cgd 			}
    227   1.1       cgd 		}
    228   1.1       cgd 		if (!(flew && mon_can_go(monster, rogue.row, rogue.col))) {
    229   1.1       cgd 			mv_1_monster(monster, rogue.row, rogue.col);
    230   1.1       cgd 		}
    231   1.5   hubertf NM:		test_mons = level_monsters.next_monster;
    232   1.5   hubertf 		monster = NULL;
    233   1.5   hubertf 		while (test_mons)
    234   1.5   hubertf 		{
    235   1.5   hubertf 			if (next_monster == test_mons)
    236   1.5   hubertf 			{
    237   1.5   hubertf 				monster = next_monster;
    238   1.5   hubertf 				break;
    239   1.5   hubertf 			}
    240   1.5   hubertf 			test_mons = test_mons -> next_monster;
    241   1.5   hubertf 		}
    242   1.1       cgd 	}
    243   1.1       cgd }
    244   1.1       cgd 
    245   1.4     lukem void
    246  1.14  dholland party_monsters(int rn, int n)
    247   1.1       cgd {
    248   1.1       cgd 	short i, j;
    249   1.1       cgd 	short row, col;
    250   1.1       cgd 	object *monster;
    251   1.1       cgd 	boolean found;
    252   1.1       cgd 
    253   1.4     lukem 	row = col = 0;
    254   1.1       cgd 	n += n;
    255   1.1       cgd 
    256   1.1       cgd 	for (i = 0; i < MONSTERS; i++) {
    257   1.1       cgd 		mon_tab[i].first_level -= (cur_level % 3);
    258   1.1       cgd 	}
    259   1.1       cgd 	for (i = 0; i < n; i++) {
    260   1.1       cgd 		if (no_room_for_monster(rn)) {
    261   1.1       cgd 			break;
    262   1.1       cgd 		}
    263   1.1       cgd 		for (j = found = 0; ((!found) && (j < 250)); j++) {
    264   1.1       cgd 			row = get_rand(rooms[rn].top_row+1,
    265   1.1       cgd 				rooms[rn].bottom_row-1);
    266   1.1       cgd 			col = get_rand(rooms[rn].left_col+1,
    267   1.1       cgd 				rooms[rn].right_col-1);
    268   1.1       cgd 			if ((!(dungeon[row][col] & MONSTER)) &&
    269   1.1       cgd 				(dungeon[row][col] & (FLOOR | TUNNEL))) {
    270   1.1       cgd 				found = 1;
    271   1.1       cgd 			}
    272   1.1       cgd 		}
    273   1.1       cgd 		if (found) {
    274  1.13  dholland 			monster = gr_monster((object *)0, 0);
    275   1.1       cgd 			if (!(monster->m_flags & IMITATES)) {
    276   1.1       cgd 				monster->m_flags |= WAKENS;
    277   1.1       cgd 			}
    278   1.1       cgd 			put_m_at(row, col, monster);
    279   1.1       cgd 		}
    280   1.1       cgd 	}
    281   1.1       cgd 	for (i = 0; i < MONSTERS; i++) {
    282   1.1       cgd 		mon_tab[i].first_level += (cur_level % 3);
    283   1.1       cgd 	}
    284   1.1       cgd }
    285   1.1       cgd 
    286   1.4     lukem char
    287  1.14  dholland gmc_row_col(int row, int col)
    288   1.1       cgd {
    289   1.4     lukem 	object *monster;
    290   1.1       cgd 
    291   1.4     lukem 	if ((monster = object_at(&level_monsters, row, col)) != NULL) {
    292   1.1       cgd 		if ((!(detect_monster || see_invisible || r_see_invisible) &&
    293   1.1       cgd 			(monster->m_flags & INVISIBLE)) || blind) {
    294   1.1       cgd 			return(monster->trail_char);
    295   1.1       cgd 		}
    296   1.1       cgd 		if (monster->m_flags & IMITATES) {
    297   1.1       cgd 			return(monster->disguise);
    298   1.1       cgd 		}
    299   1.1       cgd 		return(monster->m_char);
    300   1.1       cgd 	} else {
    301   1.1       cgd 		return('&');	/* BUG if this ever happens */
    302   1.1       cgd 	}
    303   1.1       cgd }
    304   1.1       cgd 
    305   1.4     lukem char
    306  1.14  dholland gmc(object *monster)
    307   1.1       cgd {
    308   1.1       cgd 	if ((!(detect_monster || see_invisible || r_see_invisible) &&
    309   1.1       cgd 		(monster->m_flags & INVISIBLE))
    310   1.1       cgd 		|| blind) {
    311   1.1       cgd 		return(monster->trail_char);
    312   1.1       cgd 	}
    313   1.1       cgd 	if (monster->m_flags & IMITATES) {
    314   1.1       cgd 		return(monster->disguise);
    315   1.1       cgd 	}
    316   1.1       cgd 	return(monster->m_char);
    317   1.1       cgd }
    318   1.1       cgd 
    319   1.4     lukem void
    320  1.14  dholland mv_1_monster(object *monster, short row, short col)
    321   1.1       cgd {
    322   1.1       cgd 	short i, n;
    323   1.1       cgd 	boolean tried[6];
    324   1.1       cgd 
    325   1.1       cgd 	if (monster->m_flags & ASLEEP) {
    326   1.1       cgd 		if (monster->m_flags & NAPPING) {
    327   1.1       cgd 			if (--monster->nap_length <= 0) {
    328   1.1       cgd 				monster->m_flags &= (~(NAPPING | ASLEEP));
    329   1.1       cgd 			}
    330   1.1       cgd 			return;
    331   1.1       cgd 		}
    332   1.1       cgd 		if ((monster->m_flags & WAKENS) &&
    333   1.1       cgd 			 rogue_is_around(monster->row, monster->col) &&
    334   1.1       cgd 			 rand_percent(((stealthy > 0) ?
    335   1.1       cgd 			 	(WAKE_PERCENT / (STEALTH_FACTOR + stealthy)) :
    336   1.1       cgd 				WAKE_PERCENT))) {
    337   1.1       cgd 			wake_up(monster);
    338   1.1       cgd 		}
    339   1.1       cgd 		return;
    340   1.1       cgd 	} else if (monster->m_flags & ALREADY_MOVED) {
    341   1.1       cgd 		monster->m_flags &= (~ALREADY_MOVED);
    342   1.1       cgd 		return;
    343   1.1       cgd 	}
    344   1.1       cgd 	if ((monster->m_flags & FLITS) && flit(monster)) {
    345   1.1       cgd 		return;
    346   1.1       cgd 	}
    347   1.1       cgd 	if ((monster->m_flags & STATIONARY) &&
    348   1.1       cgd 		(!mon_can_go(monster, rogue.row, rogue.col))) {
    349   1.1       cgd 		return;
    350   1.1       cgd 	}
    351   1.1       cgd 	if (monster->m_flags & FREEZING_ROGUE) {
    352   1.1       cgd 		return;
    353   1.1       cgd 	}
    354   1.1       cgd 	if ((monster->m_flags & CONFUSES) && m_confuse(monster)) {
    355   1.1       cgd 		return;
    356   1.1       cgd 	}
    357   1.1       cgd 	if (mon_can_go(monster, rogue.row, rogue.col)) {
    358   1.1       cgd 		mon_hit(monster);
    359   1.1       cgd 		return;
    360   1.1       cgd 	}
    361   1.1       cgd 	if ((monster->m_flags & FLAMES) && flame_broil(monster)) {
    362   1.1       cgd 		return;
    363   1.1       cgd 	}
    364   1.1       cgd 	if ((monster->m_flags & SEEKS_GOLD) && seek_gold(monster)) {
    365   1.1       cgd 		return;
    366   1.1       cgd 	}
    367   1.1       cgd 	if ((monster->trow == monster->row) &&
    368   1.1       cgd 		   (monster->tcol == monster->col)) {
    369   1.1       cgd 		monster->trow = NO_ROOM;
    370   1.1       cgd 	} else if (monster->trow != NO_ROOM) {
    371   1.1       cgd 		row = monster->trow;
    372   1.1       cgd 		col = monster->tcol;
    373   1.1       cgd 	}
    374   1.1       cgd 	if (monster->row > row) {
    375   1.1       cgd 		row = monster->row - 1;
    376   1.1       cgd 	} else if (monster->row < row) {
    377   1.1       cgd 		row = monster->row + 1;
    378   1.1       cgd 	}
    379   1.1       cgd 	if ((dungeon[row][monster->col] & DOOR) &&
    380   1.1       cgd 		 mtry(monster, row, monster->col)) {
    381   1.1       cgd 		return;
    382   1.1       cgd 	}
    383   1.1       cgd 	if (monster->col > col) {
    384   1.1       cgd 		col = monster->col - 1;
    385   1.1       cgd 	} else if (monster->col < col) {
    386   1.1       cgd 		col = monster->col + 1;
    387   1.1       cgd 	}
    388   1.1       cgd 	if ((dungeon[monster->row][col] & DOOR) &&
    389   1.1       cgd 		 mtry(monster, monster->row, col)) {
    390   1.1       cgd 		return;
    391   1.1       cgd 	}
    392   1.1       cgd 	if (mtry(monster, row, col)) {
    393   1.1       cgd 		return;
    394   1.1       cgd 	}
    395   1.1       cgd 
    396   1.1       cgd 	for (i = 0; i <= 5; i++) tried[i] = 0;
    397   1.1       cgd 
    398   1.1       cgd 	for (i = 0; i < 6; i++) {
    399   1.1       cgd NEXT_TRY:	n = get_rand(0, 5);
    400   1.1       cgd 		switch(n) {
    401   1.1       cgd 		case 0:
    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 1:
    407   1.1       cgd 			if (!tried[n] && mtry(monster, row, monster->col)) {
    408   1.1       cgd 				goto O;
    409   1.1       cgd 			}
    410   1.1       cgd 			break;
    411   1.1       cgd 		case 2:
    412   1.1       cgd 			if (!tried[n] && mtry(monster, row, monster->col+1)) {
    413   1.1       cgd 				goto O;
    414   1.1       cgd 			}
    415   1.1       cgd 			break;
    416   1.1       cgd 		case 3:
    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 		case 4:
    422   1.1       cgd 			if (!tried[n] && mtry(monster, monster->row, col)) {
    423   1.1       cgd 				goto O;
    424   1.1       cgd 			}
    425   1.1       cgd 			break;
    426   1.1       cgd 		case 5:
    427   1.1       cgd 			if (!tried[n] && mtry(monster, monster->row+1, col)) {
    428   1.1       cgd 				goto O;
    429   1.1       cgd 			}
    430   1.1       cgd 			break;
    431   1.1       cgd 		}
    432   1.1       cgd 		if (!tried[n]) {
    433   1.1       cgd 			tried[n] = 1;
    434   1.1       cgd 		} else {
    435   1.1       cgd 			goto NEXT_TRY;
    436   1.1       cgd 		}
    437   1.1       cgd 	}
    438   1.1       cgd O:
    439   1.1       cgd 	if ((monster->row == monster->o_row) && (monster->col == monster->o_col)) {
    440   1.1       cgd 		if (++(monster->o) > 4) {
    441   1.1       cgd 			if ((monster->trow == NO_ROOM) &&
    442   1.1       cgd 					(!mon_sees(monster, rogue.row, rogue.col))) {
    443   1.1       cgd 				monster->trow = get_rand(1, (DROWS - 2));
    444   1.1       cgd 				monster->tcol = get_rand(0, (DCOLS - 1));
    445   1.1       cgd 			} else {
    446   1.1       cgd 				monster->trow = NO_ROOM;
    447   1.1       cgd 				monster->o = 0;
    448   1.1       cgd 			}
    449   1.1       cgd 		}
    450   1.1       cgd 	} else {
    451   1.1       cgd 		monster->o_row = monster->row;
    452   1.1       cgd 		monster->o_col = monster->col;
    453   1.1       cgd 		monster->o = 0;
    454   1.1       cgd 	}
    455   1.1       cgd }
    456   1.1       cgd 
    457  1.15  dholland static int
    458  1.14  dholland mtry(object *monster, short row, short col)
    459   1.1       cgd {
    460   1.1       cgd 	if (mon_can_go(monster, row, col)) {
    461   1.1       cgd 		move_mon_to(monster, row, col);
    462   1.1       cgd 		return(1);
    463   1.1       cgd 	}
    464   1.1       cgd 	return(0);
    465   1.1       cgd }
    466   1.1       cgd 
    467   1.4     lukem void
    468  1.14  dholland move_mon_to(object *monster, short row, short col)
    469   1.1       cgd {
    470   1.1       cgd 	short c;
    471   1.4     lukem 	int mrow, mcol;
    472   1.1       cgd 
    473   1.1       cgd 	mrow = monster->row;
    474   1.1       cgd 	mcol = monster->col;
    475   1.1       cgd 
    476   1.1       cgd 	dungeon[mrow][mcol] &= ~MONSTER;
    477   1.1       cgd 	dungeon[row][col] |= MONSTER;
    478   1.1       cgd 
    479   1.1       cgd 	c = mvinch(mrow, mcol);
    480   1.1       cgd 
    481   1.1       cgd 	if ((c >= 'A') && (c <= 'Z')) {
    482   1.1       cgd 		if (!detect_monster) {
    483   1.1       cgd 			mvaddch(mrow, mcol, monster->trail_char);
    484   1.1       cgd 		} else {
    485   1.1       cgd 			if (rogue_can_see(mrow, mcol)) {
    486   1.1       cgd 				mvaddch(mrow, mcol, monster->trail_char);
    487   1.1       cgd 			} else {
    488   1.1       cgd 				if (monster->trail_char == '.') {
    489   1.1       cgd 					monster->trail_char = ' ';
    490   1.1       cgd 				}
    491   1.1       cgd 				mvaddch(mrow, mcol, monster->trail_char);
    492   1.1       cgd 			}
    493   1.1       cgd 		}
    494   1.1       cgd 	}
    495   1.1       cgd 	monster->trail_char = mvinch(row, col);
    496   1.1       cgd 	if (!blind && (detect_monster || rogue_can_see(row, col))) {
    497   1.1       cgd 		if ((!(monster->m_flags & INVISIBLE) ||
    498   1.1       cgd 			(detect_monster || see_invisible || r_see_invisible))) {
    499   1.1       cgd 			mvaddch(row, col, gmc(monster));
    500   1.1       cgd 		}
    501   1.1       cgd 	}
    502   1.1       cgd 	if ((dungeon[row][col] & DOOR) &&
    503   1.1       cgd 		(get_room_number(row, col) != cur_room) &&
    504   1.1       cgd 		(dungeon[mrow][mcol] == FLOOR) && !blind) {
    505   1.1       cgd 			mvaddch(mrow, mcol, ' ');
    506   1.1       cgd 	}
    507   1.1       cgd 	if (dungeon[row][col] & DOOR) {
    508   1.1       cgd 			dr_course(monster, ((dungeon[mrow][mcol] & TUNNEL) ? 1 : 0),
    509   1.1       cgd 				row, col);
    510   1.1       cgd 	} else {
    511   1.1       cgd 		monster->row = row;
    512   1.1       cgd 		monster->col = col;
    513   1.1       cgd 	}
    514   1.1       cgd }
    515   1.1       cgd 
    516   1.4     lukem int
    517  1.14  dholland mon_can_go(const object *monster, short row, short col)
    518   1.1       cgd {
    519   1.1       cgd 	object *obj;
    520   1.1       cgd 	short dr, dc;
    521   1.1       cgd 
    522   1.1       cgd 	dr = monster->row - row;	/* check if move distance > 1 */
    523   1.1       cgd 	if ((dr >= 2) || (dr <= -2)) {
    524   1.1       cgd 		return(0);
    525   1.1       cgd 	}
    526   1.1       cgd 	dc = monster->col - col;
    527   1.1       cgd 	if ((dc >= 2) || (dc <= -2)) {
    528   1.1       cgd 		return(0);
    529   1.1       cgd 	}
    530   1.1       cgd 	if ((!dungeon[monster->row][col]) || (!dungeon[row][monster->col])) {
    531   1.1       cgd 		return(0);
    532   1.1       cgd 	}
    533   1.1       cgd 	if ((!is_passable(row, col)) || (dungeon[row][col] & MONSTER)) {
    534   1.1       cgd 		return(0);
    535   1.1       cgd 	}
    536   1.1       cgd 	if ((monster->row!=row)&&(monster->col!=col)&&((dungeon[row][col]&DOOR) ||
    537   1.1       cgd 		(dungeon[monster->row][monster->col]&DOOR))) {
    538   1.1       cgd 		return(0);
    539   1.1       cgd 	}
    540   1.1       cgd 	if (!(monster->m_flags & (FLITS | CONFUSED | CAN_FLIT)) &&
    541   1.1       cgd 		(monster->trow == NO_ROOM)) {
    542   1.1       cgd 		if ((monster->row < rogue.row) && (row < monster->row)) return(0);
    543   1.1       cgd 		if ((monster->row > rogue.row) && (row > monster->row)) return(0);
    544   1.1       cgd 		if ((monster->col < rogue.col) && (col < monster->col)) return(0);
    545   1.1       cgd 		if ((monster->col > rogue.col) && (col > monster->col)) return(0);
    546   1.1       cgd 	}
    547   1.1       cgd 	if (dungeon[row][col] & OBJECT) {
    548   1.1       cgd 		obj = object_at(&level_objects, row, col);
    549   1.1       cgd 		if ((obj->what_is == SCROL) && (obj->which_kind == SCARE_MONSTER)) {
    550   1.1       cgd 			return(0);
    551   1.1       cgd 		}
    552   1.1       cgd 	}
    553   1.1       cgd 	return(1);
    554   1.1       cgd }
    555   1.1       cgd 
    556   1.4     lukem void
    557  1.14  dholland wake_up(object *monster)
    558   1.1       cgd {
    559   1.1       cgd 	if (!(monster->m_flags & NAPPING)) {
    560   1.1       cgd 		monster->m_flags &= (~(ASLEEP | IMITATES | WAKENS));
    561   1.1       cgd 	}
    562   1.1       cgd }
    563   1.1       cgd 
    564   1.4     lukem void
    565  1.14  dholland wake_room(short rn, boolean entering, short row, short 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.7   hubertf const char *
    599  1.14  dholland mon_name(const object *monster)
    600   1.1       cgd {
    601   1.1       cgd 	short ch;
    602   1.1       cgd 
    603   1.1       cgd 	if (blind || ((monster->m_flags & INVISIBLE) &&
    604   1.1       cgd 		!(detect_monster || see_invisible || r_see_invisible))) {
    605   1.1       cgd 		return("something");
    606   1.1       cgd 	}
    607   1.1       cgd 	if (halluc) {
    608   1.1       cgd 		ch = get_rand('A', 'Z') - 'A';
    609   1.1       cgd 		return(m_names[ch]);
    610   1.1       cgd 	}
    611   1.1       cgd 	ch = monster->m_char - 'A';
    612   1.1       cgd 	return(m_names[ch]);
    613   1.1       cgd }
    614   1.1       cgd 
    615  1.15  dholland static int
    616  1.14  dholland rogue_is_around(int row, int col)
    617   1.1       cgd {
    618   1.1       cgd 	short rdif, cdif, retval;
    619   1.1       cgd 
    620   1.1       cgd 	rdif = row - rogue.row;
    621   1.1       cgd 	cdif = col - rogue.col;
    622   1.1       cgd 
    623   1.1       cgd 	retval = (rdif >= -1) && (rdif <= 1) && (cdif >= -1) && (cdif <= 1);
    624   1.1       cgd 	return(retval);
    625   1.1       cgd }
    626   1.1       cgd 
    627   1.4     lukem void
    628  1.14  dholland wanderer(void)
    629   1.1       cgd {
    630   1.1       cgd 	object *monster;
    631   1.1       cgd 	short row, col, i;
    632   1.1       cgd 	boolean found = 0;
    633   1.1       cgd 
    634  1.10      tron 	monster = NULL;		/* XXXGCC -Wuninitialized [powerpc] */
    635   1.9        he 
    636   1.1       cgd 	for (i = 0; ((i < 15) && (!found)); i++) {
    637  1.14  dholland 		monster = gr_monster(NULL, 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.14  dholland show_monsters(void)
    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.14  dholland create_monster(void)
    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.16  dholland 		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.13  dholland 		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.12  dholland 		messagef(0, "you hear a faint cry of anguish in the distance");
    715   1.1       cgd 	}
    716   1.1       cgd }
    717   1.1       cgd 
    718  1.15  dholland static void
    719  1.14  dholland put_m_at(short row, short col, object *monster)
    720   1.1       cgd {
    721   1.1       cgd 	monster->row = row;
    722   1.1       cgd 	monster->col = col;
    723   1.1       cgd 	dungeon[row][col] |= MONSTER;
    724   1.1       cgd 	monster->trail_char = mvinch(row, col);
    725  1.13  dholland 	(void)add_to_pack(monster, &level_monsters, 0);
    726   1.1       cgd 	aim_monster(monster);
    727   1.1       cgd }
    728   1.1       cgd 
    729  1.15  dholland static void
    730  1.14  dholland aim_monster(object *monster)
    731   1.1       cgd {
    732   1.1       cgd 	short i, rn, d, r;
    733   1.1       cgd 
    734   1.1       cgd 	rn = get_room_number(monster->row, monster->col);
    735  1.11   jnemeth 	if (rn == NO_ROOM)
    736  1.11   jnemeth 		clean_up("aim_monster: monster not in room");
    737   1.1       cgd 	r = get_rand(0, 12);
    738   1.1       cgd 
    739   1.1       cgd 	for (i = 0; i < 4; i++) {
    740   1.1       cgd 		d = (r + i) % 4;
    741   1.1       cgd 		if (rooms[rn].doors[d].oth_room != NO_ROOM) {
    742   1.1       cgd 			monster->trow = rooms[rn].doors[d].door_row;
    743   1.1       cgd 			monster->tcol = rooms[rn].doors[d].door_col;
    744   1.1       cgd 			break;
    745   1.1       cgd 		}
    746   1.1       cgd 	}
    747   1.1       cgd }
    748   1.1       cgd 
    749   1.4     lukem int
    750  1.14  dholland rogue_can_see(int row, int col)
    751   1.1       cgd {
    752   1.4     lukem 	int retval;
    753   1.1       cgd 
    754   1.1       cgd 	retval = !blind &&
    755   1.1       cgd 			(((get_room_number(row, col) == cur_room) &&
    756   1.1       cgd 					!(rooms[cur_room].is_room & R_MAZE)) ||
    757   1.1       cgd 			rogue_is_around(row, col));
    758   1.1       cgd 
    759   1.1       cgd 	return(retval);
    760   1.1       cgd }
    761   1.1       cgd 
    762  1.15  dholland static int
    763  1.14  dholland move_confused(object *monster)
    764   1.1       cgd {
    765   1.1       cgd 	short i, row, col;
    766   1.1       cgd 
    767   1.1       cgd 	if (!(monster->m_flags & ASLEEP)) {
    768   1.1       cgd 		if (--monster->moves_confused <= 0) {
    769   1.1       cgd 			monster->m_flags &= (~CONFUSED);
    770   1.1       cgd 		}
    771   1.1       cgd 		if (monster->m_flags & STATIONARY) {
    772   1.1       cgd 			return(coin_toss() ? 1 : 0);
    773   1.1       cgd 		} else if (rand_percent(15)) {
    774   1.1       cgd 			return(1);
    775   1.1       cgd 		}
    776   1.1       cgd 		row = monster->row;
    777   1.1       cgd 		col = monster->col;
    778   1.1       cgd 
    779   1.1       cgd 		for (i = 0; i < 9; i++) {
    780   1.1       cgd 			rand_around(i, &row, &col);
    781   1.1       cgd 			if ((row == rogue.row) && (col == rogue.col)) {
    782   1.1       cgd 				return(0);
    783   1.1       cgd 			}
    784   1.1       cgd 			if (mtry(monster, row, col)) {
    785   1.1       cgd 				return(1);
    786   1.1       cgd 			}
    787   1.1       cgd 		}
    788   1.1       cgd 	}
    789   1.1       cgd 	return(0);
    790   1.1       cgd }
    791   1.1       cgd 
    792  1.15  dholland static int
    793  1.14  dholland flit(object *monster)
    794   1.1       cgd {
    795   1.1       cgd 	short i, row, col;
    796   1.1       cgd 
    797   1.1       cgd 	if (!rand_percent(FLIT_PERCENT + ((monster->m_flags & FLIES) ? 20 : 0))) {
    798   1.1       cgd 		return(0);
    799   1.1       cgd 	}
    800   1.1       cgd 	if (rand_percent(10)) {
    801   1.1       cgd 		return(1);
    802   1.1       cgd 	}
    803   1.1       cgd 	row = monster->row;
    804   1.1       cgd 	col = monster->col;
    805   1.1       cgd 
    806   1.1       cgd 	for (i = 0; i < 9; i++) {
    807   1.1       cgd 		rand_around(i, &row, &col);
    808   1.1       cgd 		if ((row == rogue.row) && (col == rogue.col)) {
    809   1.1       cgd 			continue;
    810   1.1       cgd 		}
    811   1.1       cgd 		if (mtry(monster, row, col)) {
    812   1.1       cgd 			return(1);
    813   1.1       cgd 		}
    814   1.1       cgd 	}
    815   1.1       cgd 	return(1);
    816   1.1       cgd }
    817   1.1       cgd 
    818   1.4     lukem char
    819  1.14  dholland gr_obj_char(void)
    820   1.1       cgd {
    821   1.1       cgd 	short r;
    822   1.7   hubertf 	const char *rs = "%!?]=/):*";
    823   1.1       cgd 
    824   1.1       cgd 	r = get_rand(0, 8);
    825   1.1       cgd 
    826   1.1       cgd 	return(rs[r]);
    827   1.1       cgd }
    828   1.1       cgd 
    829  1.15  dholland static int
    830  1.14  dholland no_room_for_monster(int rn)
    831   1.1       cgd {
    832   1.1       cgd 	short i, j;
    833   1.1       cgd 
    834   1.1       cgd 	for (i = rooms[rn].top_row+1; i < rooms[rn].bottom_row; i++) {
    835   1.1       cgd 		for (j = rooms[rn].left_col+1; j < rooms[rn].right_col; j++) {
    836   1.1       cgd 			if (!(dungeon[i][j] & MONSTER)) {
    837   1.1       cgd 				return(0);
    838   1.1       cgd 			}
    839   1.1       cgd 		}
    840   1.1       cgd 	}
    841   1.1       cgd 	return(1);
    842   1.1       cgd }
    843   1.1       cgd 
    844   1.4     lukem void
    845  1.14  dholland aggravate(void)
    846   1.1       cgd {
    847   1.1       cgd 	object *monster;
    848   1.1       cgd 
    849  1.12  dholland 	messagef(0, "you hear a high pitched humming noise");
    850   1.1       cgd 
    851   1.1       cgd 	monster = level_monsters.next_monster;
    852   1.1       cgd 
    853   1.1       cgd 	while (monster) {
    854   1.1       cgd 		wake_up(monster);
    855   1.1       cgd 		monster->m_flags &= (~IMITATES);
    856   1.1       cgd 		if (rogue_can_see(monster->row, monster->col)) {
    857   1.1       cgd 			mvaddch(monster->row, monster->col, monster->m_char);
    858   1.1       cgd 		}
    859   1.1       cgd 		monster = monster->next_monster;
    860   1.1       cgd 	}
    861   1.1       cgd }
    862   1.1       cgd 
    863   1.1       cgd boolean
    864  1.14  dholland mon_sees(const object *monster, int row, int col)
    865   1.1       cgd {
    866   1.1       cgd 	short rn, rdif, cdif, retval;
    867   1.1       cgd 
    868   1.1       cgd 	rn = get_room_number(row, col);
    869   1.1       cgd 
    870   1.1       cgd 	if (	(rn != NO_ROOM) &&
    871   1.1       cgd 			(rn == get_room_number(monster->row, monster->col)) &&
    872   1.1       cgd 			!(rooms[rn].is_room & R_MAZE)) {
    873   1.1       cgd 		return(1);
    874   1.1       cgd 	}
    875   1.1       cgd 	rdif = row - monster->row;
    876   1.1       cgd 	cdif = col - monster->col;
    877   1.1       cgd 
    878   1.1       cgd 	retval = (rdif >= -1) && (rdif <= 1) && (cdif >= -1) && (cdif <= 1);
    879   1.1       cgd 	return(retval);
    880   1.1       cgd }
    881   1.1       cgd 
    882   1.4     lukem void
    883  1.14  dholland mv_aquatars(void)
    884   1.1       cgd {
    885   1.1       cgd 	object *monster;
    886   1.1       cgd 
    887   1.1       cgd 	monster = level_monsters.next_monster;
    888   1.1       cgd 
    889   1.1       cgd 	while (monster) {
    890   1.1       cgd 		if ((monster->m_char == 'A') &&
    891   1.1       cgd 			mon_can_go(monster, rogue.row, rogue.col)) {
    892   1.1       cgd 			mv_1_monster(monster, rogue.row, rogue.col);
    893   1.1       cgd 			monster->m_flags |= ALREADY_MOVED;
    894   1.1       cgd 		}
    895   1.1       cgd 		monster = monster->next_monster;
    896   1.1       cgd 	}
    897   1.1       cgd }
    898