Source:NetHack 3.2.0/monmove.c

Below is the full text to monmove.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/monmove.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)monmove.c	3.2	96/02/10	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6.    #include "mfndpos.h"  7.    #include "artifact.h"  8. 9.   #ifdef OVL0 10.   11.   static int FDECL(disturb,(struct monst *)); 12.  static void FDECL(distfleeck,(struct monst *,int *,int *,int *)); 13.  static int FDECL(m_arrival, (struct monst *)); 14.  static void FDECL(watch_on_duty,(struct monst *)); 15.   16.   #endif /* OVL0 */ 17.  #ifdef OVLB 18.   19.   boolean /* TRUE : mtmp died */ 20.  mb_trapped(mtmp) 21.  register struct monst *mtmp; 22.  {  23.   	if (flags.verbose) { 24.  	    if (cansee(mtmp->mx, mtmp->my)) 25.  		pline("KABOOM!!  You see a door explode."); 26.  	    else if (flags.soundok) 27.  		You_hear("a distant explosion."); 28.  	}  29.   	wake_nearto(mtmp->mx, mtmp->my, 7*7); 30.  	mtmp->mstun = 1; 31.  	mtmp->mhp -= rnd(15); 32.  	if(mtmp->mhp <= 0) { 33.  		mondied(mtmp); 34.  		if (mtmp->mhp > 0) /* lifesaved */ 35.  			return(FALSE); 36.  		else 37.  			return(TRUE); 38.  	}  39.   	return(FALSE); 40.  }  41.    42.   #endif /* OVLB */ 43.  #ifdef OVL0 44.   45.   static void 46.  watch_on_duty(mtmp) 47.  register struct monst *mtmp; 48.  {  49.   	register s_level *slev = Is_special(&u.uz); 50.  	int	x, y;  51. 52.  	if(slev && slev->flags.town && mtmp->mpeaceful &&  53.   	   mtmp->mcansee && m_canseeu(mtmp) && !rn2(3)) { 54.   55.   	    if(picking_lock(&x, &y) && IS_DOOR(levl[x][y].typ) &&  56.   	       (levl[x][y].doormask & D_LOCKED)) { 57.   58.   		if(couldsee(mtmp->mx, mtmp->my)) { 59.   60.   		  pline("%s yells:", Amonnam(mtmp)); 61.  		  if(levl[x][y].looted & D_WARNED) { 62.  			verbalize("Halt, thief!  You're under arrest!"); 63.  			(void) angry_guards(!(flags.soundok)); 64.  		  } else { 65.  			verbalize("Hey, stop picking that lock!"); 66.  			levl[x][y].looted |=  D_WARNED; 67.  		  }  68.   		  stop_occupation; 69.  		}  70.   	    }  71.   	}  72.   }  73.    74.   #endif /* OVL0 */ 75.  #ifdef OVL1 76.   77.   int 78.  dochugw(mtmp) 79.  	register struct monst *mtmp; 80.  {  81.   	register int x = mtmp->mx, y = mtmp->my; 82.  	boolean already_saw_mon = !occupation ? 0 : canspotmon(mtmp); 83.  	int rd = dochug(mtmp); 84.  	int dd; 85.   86.   	if(Warning && !rd && !mtmp->mpeaceful &&  87.   			(dd = distu(mtmp->mx,mtmp->my)) < distu(x,y) &&  88.   			dd < 100 && !canseemon(mtmp)) { 89.  	    /* Note: this assumes we only want to warn against the monster to  90. * which the weapon does extra damage, as there is no "monster 91.   	     * which the weapon warns against" field. 92.  	     */  93.   	    if (spec_ability(uwep, SPFX_WARN) && spec_dbon(uwep, mtmp, 1)) 94.  		warnlevel = 100; 95.  	    else if ((int) (mtmp->m_lev / 4) > warnlevel) 96.  		warnlevel = (mtmp->m_lev / 4); 97.  	}  98.   	  99.   	/* a similar check is in monster_nearby in hack.c */ 100. 	/* check whether hero notices monster and stops current activity */ 101. 	if (occupation && !rd && !Confusion &&  102.  	    (!mtmp->mpeaceful || Hallucination) &&  103.  	    /* it's close enough to be a threat */  104.  	    distu(mtmp->mx,mtmp->my) <= (BOLT_LIM+1)*(BOLT_LIM+1) &&  105.  	    /* and either couldn't see it before, or it was too far away */  106.  	    (!already_saw_mon || !couldsee(x,y) || 107. 		distu(x,y) > (BOLT_LIM+1)*(BOLT_LIM+1)) &&  108.  	    /* can see it now, or sense it and would normally see it */  109.  	    (canseemon(mtmp) || 110. 		(sensemon(mtmp) && couldsee(mtmp->mx,mtmp->my))) &&  111.  	    !noattacks(mtmp->data) && !onscary(u.ux, u.uy, mtmp)) 112. 		stop_occupation; 113.  114.  	return(rd); 115. }  116.   117.  #endif /* OVL1 */ 118. #ifdef OVL2 119.  120.  boolean 121. onscary(x, y, mtmp) 122. int x, y;  123. struct monst *mtmp; 124. {  125.  	if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee ||  126.  			mtmp->mpeaceful || mtmp->data->mlet == S_HUMAN ||  127.  			is_lminion(mtmp->data) || is_rider(mtmp->data) ||  128.  			mtmp->data == &mons[PM_MINOTAUR]) 129. 		return(FALSE); 130.  131.  	return (boolean)(sobj_at(SCR_SCARE_MONSTER, x, y)  132.  #ifdef ELBERETH  133.  			 || sengr_at("Elbereth", x, y)  134.  #endif  135.  			 || (mtmp->data->mlet == S_VAMPIRE 136. 			     && IS_ALTAR(levl[x][y].typ))); 137. }  138.   139.  #endif /* OVL2 */ 140. #ifdef OVL0 141.  142.  /* regenerate lost hit points */ 143. void 144. mon_regen(mon, digest_meal) 145. struct monst *mon; 146. boolean digest_meal; 147. {  148.  	if (mon->mhp < mon->mhpmax &&  149.  	    (moves % 20 == 0 || regenerates(mon->data))) mon->mhp++; 150. 	if (mon->mspec_used) mon->mspec_used--; 151. 	if (digest_meal) { 152. 	    if (mon->meating) mon->meating--; 153. 	}  154.  }  155.   156.  /*  157.   * Possibly awaken the given monster. Return a 1 if the monster has been 158.  * jolted awake. 159.  */  160.  static int 161. disturb(mtmp) 162. 	register struct monst *mtmp; 163. {  164.  	/*  165.  	 * + Ettins are hard to surprise. 166. 	 * + Nymphs, jabberwocks, and leprechauns do not easily wake up. 167. 	 *  168.  	 * Wake up if: 169. 	 *	in direct LOS						AND 170. 	 *	within 10 squares					AND 171. 	 *	not stealthy or (mon is an ettin and 9/10)		AND 172. 	 *	(mon is not a nymph, jabberwock, or leprechaun) or 1/50	AND 173. 	 *	Aggravate or mon is (dog or human) or  174. *	   (1/7 and mon is not mimicing furniture or object) 175. 	 */  176.  	if(couldsee(mtmp->mx,mtmp->my) &&  177.  		distu(mtmp->mx,mtmp->my) <= 100 &&  178.  		(!Stealth || (mtmp->data == &mons[PM_ETTIN] && rn2(10))) &&  179.  		(!(mtmp->data->mlet == S_NYMPH  180.  			|| mtmp->data == &mons[PM_JABBERWOCK]  181.  			|| mtmp->data->mlet == S_LEPRECHAUN) || !rn2(50)) &&  182.  		(Aggravate_monster 183. 			|| (mtmp->data->mlet == S_DOG ||  184.  				mtmp->data->mlet == S_HUMAN) 185. 			|| (!rn2(7) && mtmp->m_ap_type != M_AP_FURNITURE &&  186.  				mtmp->m_ap_type != M_AP_OBJECT) )) { 187.  188.  		mtmp->msleep = 0; 189. 		return(1); 190. 	}  191.  	return(0); 192. }  193.   194.  static void 195. distfleeck(mtmp,inrange,nearby,scared) 196. register struct monst *mtmp; 197. int *inrange, *nearby, *scared; 198. {  199.  	int seescaryx, seescaryy; 200.  201.  	*inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <=  202.  							(BOLT_LIM * BOLT_LIM)); 203. 	*nearby = *inrange && monnear(mtmp, mtmp->mux, mtmp->muy); 204.  205.  	/* Note: if your image is displaced, the monster sees the Elbereth 206. 	 * at your displaced position, thus never attacking your displaced 207. 	 * position, but possibly attacking you by accident. If you are 208. 	 * invisible, it sees the Elbereth at your real position, thus never 209. 	 * running into you by accident but possibly attacking the spot 210. 	 * where it guesses you are. 211. 	 */  212.  	if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) { 213. 		seescaryx = mtmp->mux; 214. 		seescaryy = mtmp->muy; 215. 	} else { 216. 		seescaryx = u.ux; 217. 		seescaryy = u.uy; 218. 	}  219.  	*scared = (*nearby && (onscary(seescaryx, seescaryy, mtmp) || 220. 			       (!mtmp->mpeaceful &&  221.  				    in_your_sanctuary(mtmp->mx, mtmp->my)))); 222.  223.  	if(*scared && !mtmp->mflee) { 224. 		if (!sticks(uasmon)) 225. 			unstuck(mtmp);	/* monster lets go when fleeing */ 226. 		mtmp->mflee = 1; 227. #ifdef STUPID 228. 		if (rn2(7)) 229. 		    mtmp->mfleetim = rnd(10); 230. 		else 231. 		    mtmp->mfleetim = rnd(100); 232. #else 233. 		mtmp->mfleetim = rnd(rn2(7) ? 10 : 100); 234. #endif 235. 	}  236.   237.  }  238.   239.  /* perform a special one-time action for a monster; returns -1 if nothing 240.    special happened, 0 if monster uses up its turn, 1 if monster is killed */ 241. static int 242. m_arrival(mon) 243. struct monst *mon; 244. {  245.  	mon->mstrategy &= ~STRAT_ARRIVE;	/* always reset */ 246.  247.  	return -1; 248. }  249.   250.  /* returns 1 if monster died moving, 0 otherwise */ 251. /* The whole dochugw/m_move/distfleeck/mfndpos section is serious spaghetti 252.  * code. --KAA 253.  */  254.  int 255. dochug(mtmp) 256. register struct monst *mtmp; 257. {  258.  	register struct permonst *mdat; 259. 	register int tmp=0; 260. 	int inrange, nearby, scared; 261.  262.  /*	Pre-movement adjustments	*/ 263.  264.  	if(mtmp->cham && !rn2(6))	/* polymorph chameleons */ 265. 	    (void) newcham(mtmp, (struct permonst *)0); 266.  267.  	/* regenerate monsters */ 268. 	mon_regen(mtmp, FALSE); 269.  270.  	/* polymorph lycanthropes */ 271. 	were_change(mtmp); 272.  273.  	mdat = mtmp->data; /* after newcham and were_change */ 274.  275.  	if (mtmp->mstrategy & STRAT_ARRIVE) { 276. 	    int res = m_arrival(mtmp); 277. 	    if (res >= 0) return res; 278. 	}  279.   280.  	/* check for waitmask status change */ 281. 	if ((mtmp->mstrategy & STRAT_WAITFORU) &&  282.  		(m_canseeu(mtmp) || mtmp->mhp < mtmp->mhpmax)) 283. 	    mtmp->mstrategy &= ~STRAT_WAITFORU; 284.  285.  	/* update quest status flags */ 286. 	quest_stat_check(mtmp); 287.  288.  	if (!mtmp->mcanmove || (mtmp->mstrategy & STRAT_WAITMASK)) { 289. 	    if (Hallucination) newsym(mtmp->mx,mtmp->my); 290. 	    if (mtmp->mcanmove && (mtmp->mstrategy & STRAT_CLOSE) &&  291.  	       !mtmp->msleep && monnear(mtmp, u.ux, u.uy)) 292. 		quest_talk(mtmp);	/* give the leaders a chance to speak */ 293. 	    return(0);	/* other frozen monsters can't do anything */ 294. 	}  295.   296.  	/* there is a chance we will wake it */ 297. 	if(mtmp->msleep && !disturb(mtmp)) { 298. 		if (Hallucination) newsym(mtmp->mx,mtmp->my); 299. 		return(0); 300. 	}  301.   302.  	/* not frozen or sleeping: wipe out texts written in the dust */ 303. 	wipe_engr_at(mtmp->mx, mtmp->my, 1); 304.  305.  	/* confused monsters get unconfused with small probability */ 306. 	if (mtmp->mconf && !rn2(50)) mtmp->mconf = 0; 307.  308.  	/* stunned monsters get un-stunned with larger probability */ 309. 	if (mtmp->mstun && !rn2(10)) mtmp->mstun = 0; 310.  311.  	/* some monsters teleport */ 312. 	if (mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz) { 313. 		rloc(mtmp); 314. 		return(0); 315. 	}  316.  	if (mdat->msound == MS_SHRIEK && !um_dist(mtmp->mx, mtmp->my, 1)) 317. 	    m_respond(mtmp); 318. 	if (mdat == &mons[PM_MEDUSA] && cansee(mtmp->mx, mtmp->my)) 319. 	    m_respond(mtmp); 320. 	if (mdat->mmove < rnd(6)) return(0); 321.  322.  	/* fleeing monsters might regain courage */ 323. 	if (mtmp->mflee && !mtmp->mfleetim  324.  	   && mtmp->mhp == mtmp->mhpmax && !rn2(25)) mtmp->mflee = 0; 325.  326.  	set_apparxy(mtmp); 327. 	/* Must be done after you move and before the monster does. The 328. 	 * set_apparxy call in m_move doesn't suffice since the variables 329. 	 * inrange, etc. all depend on stuff set by set_apparxy. 330. 	 */  331.   332.  	/* Monsters that want to acquire things */ 333. 	/* may teleport, so do it before inrange is set */ 334. 	if(is_covetous(mdat)) (void) tactics(mtmp); 335.  336.  	/* check distance and scariness of attacks */ 337. 	distfleeck(mtmp,&inrange,&nearby,&scared); 338.  339.  	if(find_defensive(mtmp)) { 340. 		if (use_defensive(mtmp) != 0) 341. 			return 1; 342. 	} else if(find_misc(mtmp)) { 343. 		if (use_misc(mtmp) != 0) 344. 			return 1; 345. 	}  346.   347.  	/* Demonic Blackmail! */ 348.  	if(nearby && mdat->msound == MS_BRIBE &&  349.  	   mtmp->mpeaceful && !mtmp->mtame && !u.uswallow) { 350. 		if (mtmp->mux != u.ux || mtmp->muy != u.uy) { 351. 			pline("%s whispers at thin air.",  352.  			    cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It"); 353.  354.  			if (is_demon(uasmon)) rloc(mtmp); 355. 			  /* "Good hunting, brother" */ 356. 			else { 357. 			    mtmp->minvis = mtmp->perminvis = 0; 358. 			    /* Why? For the same reason in real demon talk */ 359. 			    pline("%s gets angry!", Amonnam(mtmp)); 360. 			    mtmp->mpeaceful = 0; 361. 			    /* since no way is an image going to pay it off */ 362. 			}  363.  		} else if(demon_talk(mtmp)) return(1);	/* you paid it off */ 364. 	}  365.   366.  	/* the watch will look around and see if you are up to no good :-) */  367.  	if (mdat == &mons[PM_WATCHMAN] || mdat == &mons[PM_WATCH_CAPTAIN])  368.  		watch_on_duty(mtmp);  369.   370.  	else if (mdat == &mons[PM_MIND_FLAYER] && !rn2(20)) {  371.  		struct monst *m2, *nmon = (struct monst *)0;  372.   373.  		if (canseemon(mtmp))  374.  			pline("%s concentrates.", Monnam(mtmp));  375.  		if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM) {  376.  			You("sense a faint wave of psychic energy.");  377.  			goto toofar;  378.  		}  379.  		pline("A wave of psychic energy pours over you!");  380.  		if (mtmp->mpeaceful && 381. 		    (!Conflict || resist(mtmp, RING_CLASS, 0, 0)))  382.  			pline("It feels quite soothing.");  383.  		else {  384.  			register boolean m_sen = sensemon(mtmp);  385.   386.  			if (m_sen || (Telepat && rn2(2)) || !rn2(10)) {  387.  				int dmg;  388.  				pline("It locks on to your %s!", 389. 					m_sen ? "telepathy" : 390. 					Telepat ? "latent telepathy" : "mind"); 391.  				dmg = rnd(15);  392.  				if (Half_spell_damage) dmg = (dmg+1) / 2;  393.  				losehp(dmg, "psychic blast", KILLED_BY_AN);  394.  			}  395.  		}  396.  		for(m2=fmon; m2; m2 = nmon) {  397.  			nmon = m2->nmon;  398.  			if (m2->mpeaceful != mtmp->mpeaceful) continue;  399.  			if (mindless(m2->data)) continue;  400.  			if (m2 == mtmp) continue;  401.  			if ((telepathic(m2->data) &&  402.  			    (rn2(2) || m2->mblinded)) || !rn2(10)) {  403.  				if (cansee(m2->mx, m2->my))  404.  				    pline("It locks on to %s.", mon_nam(m2));  405.  				m2->mhp -= rnd(15);  406.  				if (m2->mhp <= 0)  407.  				    monkilled(m2, "", AD_DRIN);  408.  			}  409.  		}  410.  	}  411.  toofar:  412.  	/* If monster is nearby you, and has to wield a weapon, do so.   This  413.  	 * costs the monster a move, of course.  414.  	 */  415.  	if((!mtmp->mpeaceful || Conflict) && inrange && 416. 	   dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8 417. 	   && attacktype(mdat, AT_WEAP)) {  418.  	    if (mtmp->weapon_check == NEED_WEAPON || !MON_WEP(mtmp)) {  419.  		mtmp->weapon_check = NEED_HTH_WEAPON;  420.  		if (mon_wield_item(mtmp) != 0) return(0);  421.  	    }  422.  	}  423.   424.  /*	Now the actual movement phase	*/  425.   426.  	if(!nearby || mtmp->mflee || scared || 427. 	   mtmp->mconf || mtmp->mstun || (mtmp->minvis && !rn2(3)) || 428. 	   (mdat->mlet == S_LEPRECHAUN && !u.ugold && (mtmp->mgold || rn2(2))) || 429. 	   (is_wanderer(mdat) && !rn2(4)) || (Conflict && !mtmp->iswiz) || 430. 	   (!mtmp->mcansee && !rn2(4)) || mtmp->mpeaceful) {  431.   432.  		tmp = m_move(mtmp, 0);  433.  		distfleeck(mtmp,&inrange,&nearby,&scared);	/* recalc */  434.   435.  		switch (tmp) {  436.  		    case 0:	/* no movement, but it can still attack you */  437.  		    case 3:	/* absolutely no movement */  438.  				/* for pets, case 0 and 3 are equivalent */  439.  			/* During hallucination, monster appearance should  440.  			 * still change - even if it doesn't move.  441.  			 */  442.  			if(Hallucination) newsym(mtmp->mx,mtmp->my);  443.  			break;  444.  		    case 1:	/* monster moved */  445.  			/* Maybe it stepped on a trap and fell asleep... */  446.  			if(mtmp->msleep || !mtmp->mcanmove) return(0);  447.  			if(!nearby && 448. 			  (ranged_attk(mdat) || find_offensive(mtmp)))  449.  			    break;  450.  			else if(mdat->mmove <= 12) {  451.  			    /* a monster that's digesting you can move at the  452.  			     * same time -dlc  453.  			     */  454.  			    if(u.uswallow && mtmp == u.ustuck)  455.  				return(mattacku(mtmp));  456.  			    return(0);  457.  			}  458.  			break;  459.  		    case 2:	/* monster died */  460.  			return(1);  461.  		}  462.  	}  463.   464.  /*	Now, attack the player if possible - one attack set per monst	*/  465.   466.  	if (!mtmp->mpeaceful || 467. 	    (Conflict && !resist(mtmp, RING_CLASS, 0, 0))) {  468.  	    if(inrange && !noattacks(mdat) && u.uhp > 0 && !scared && tmp != 3)  469.  		if(mattacku(mtmp)) return(1); /* monster died (e.g. exploded) */  470.   471.  	    if(mtmp->wormno) wormhitu(mtmp);  472.  	}  473.  	/* special speeches for quest monsters */  474.  	if(!mtmp->msleep && mtmp->mcanmove && nearby)  475.  		quest_talk(mtmp);  476.  	else  477.  	    /* extra emotional attack for vile monsters */  478.  	    if(inrange && mtmp->data->msound == MS_CUSS && !mtmp->mpeaceful && 479. 	       couldsee(mtmp->mx, mtmp->my) && !mtmp->minvis && !rn2(5))  480.  		cuss(mtmp);  481.   482.  	/* extra movement for fast monsters */  483.  	if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp, 1);  484.  	return(tmp == 2);  485.  }  486.   487.  static NEARDATA const char practical[] = { WEAPON_CLASS, ARMOR_CLASS, GEM_CLASS, FOOD_CLASS, 0 };  488.  static NEARDATA const char magical[] = {  489.  	AMULET_CLASS, POTION_CLASS, SCROLL_CLASS, WAND_CLASS, RING_CLASS,  490.  	SPBOOK_CLASS, 0 };  491.  static NEARDATA const char indigestion[] = { BALL_CLASS, ROCK_CLASS, 0 };  492.  static NEARDATA const char boulder_class[] = { ROCK_CLASS, 0 };  493.  static NEARDATA const char gem_class[] = { GEM_CLASS, 0 };  494.   495.  boolean  496.  itsstuck(mtmp)  497.  register struct monst *mtmp;  498.  {  499.  	if (sticks(uasmon) && mtmp==u.ustuck && !u.uswallow) {  500.  		pline("%s cannot escape from you!", Monnam(mtmp)); 501. 		return(TRUE); 502. 	}  503.  	return(FALSE); 504. }  505.   506.  /* Return values: 507.  * 0: did not move, but can still attack and do other stuff. 508.  * 1: moved, possibly can attack. 509.  * 2: monster died. 510.  * 3: did not move, and can't do anything else either. 511.  */  512.  int 513. m_move(mtmp, after) 514. register struct monst *mtmp; 515. register int after; 516. {  517.  	register int appr; 518. 	xchar gx,gy,nix,niy,chcnt; 519. 	int chi;	/* could be schar except for stupid Sun-2 compiler */ 520. 	boolean likegold=0, likegems=0, likeobjs=0, likemagic=0, conceals=0; 521. 	boolean likerock=0, can_tunnel=0; 522. 	boolean can_open=0, can_unlock=0, doorbuster=0; 523. 	boolean uses_items=0; 524. 	struct permonst *ptr; 525. 	struct monst *mtoo; 526. 	schar mmoved = 0;	/* not strictly nec.: chi >= 0 will do */ 527. 	long info[9]; 528. 	long flag; 529. 	int  omx = mtmp->mx, omy = mtmp->my; 530. 	struct obj *mw_tmp; 531.  532.  	if(mtmp->mtrapped) { 533. 	    int i = mintrap(mtmp); 534. 	    if(i >= 2) { newsym(mtmp->mx,mtmp->my); return(2); }/* it died */ 535. 	    if(i == 1) return(0);	/* still in trap, so didn't move */ 536. 	}  537.  	ptr = mtmp->data; /* mintrap can change mtmp->data -dlc */ 538.  539.  	if (mtmp->meating) { 540. 	    mtmp->meating--; 541. 	    return 3;			/* still eating */ 542. 	}  543.  	if (hides_under(ptr) && OBJ_AT(mtmp->mx, mtmp->my) && rn2(10)) 544. 	    return 0;		/* do not leave hiding place */ 545.  546.  	set_apparxy(mtmp); 547. 	/* where does mtmp think you are? */ 548.  	/* Not necessary if m_move called from this file, but necessary in  549. * other calls of m_move (ex. leprechauns dodging) 550. 	 */  551.  	can_tunnel = tunnels(ptr) && 552. #ifdef REINCARNATION 553. 		!Is_rogue_level(&u.uz) && 554. #endif 555. 		(!needspick(ptr) || m_carrying(mtmp, PICK_AXE)); 556. 	can_open = !(nohands(ptr) || verysmall(ptr)); 557. 	can_unlock = ((can_open && m_carrying(mtmp, SKELETON_KEY)) || mtmp->iswiz); 558. 	doorbuster = is_giant(ptr); 559. 	if(mtmp->wormno) goto not_special; 560. 	/* my dog gets special treatment */ 561. 	if(mtmp->mtame) { 562. 	    mmoved = dog_move(mtmp, after); 563. 	    goto postmov; 564. 	}  565.   566.  	/* likewise for shopkeeper */ 567. 	if(mtmp->isshk) { 568. 	    mmoved = shk_move(mtmp); 569. 	    if(mmoved == -2) return(2); 570. 	    if(mmoved >= 0) goto postmov; 571. 	    mmoved = 0;		/* follow player outside shop */ 572. 	}  573.   574.  	/* and for the guard */ 575. 	if(mtmp->isgd) { 576. 	    mmoved = gd_move(mtmp); 577. 	    if(mmoved == -2) return(2); 578. 	    if(mmoved >= 0) goto postmov; 579. 	    mmoved = 0; 580. 	}  581.   582.  	/* and the acquisitive monsters get special treatment */ 583. 	if(is_covetous(ptr)) { 584. 	    xchar tx = STRAT_GOALX(mtmp->mstrategy), 585. 		  ty = STRAT_GOALY(mtmp->mstrategy); 586. 	    struct monst *intruder = m_at(tx, ty); 587. 	    /*  588.  	     * if there's a monster on the object or in possesion of it, 589. 	     * attack it. 590. 	     */  591.  	    if((dist2(mtmp->mx, mtmp->my, tx, ty) < 2) &&  592.  	       intruder && (intruder != mtmp)) { 593.  594.  		if(mattackm(mtmp, intruder) == 2) return(2); 595. 		mmoved = 1; 596. 	    } else mmoved = 0; 597. 	    goto postmov; 598. 	}  599.   600.  	/* and for the priest */ 601. 	if(mtmp->ispriest) { 602. 	    mmoved = pri_move(mtmp); 603. 	    if(mmoved == -2) return(2); 604. 	    if(mmoved >= 0) goto postmov; 605. 	    mmoved = 0; 606. 	}  607.   608.  #ifdef MAIL 609. 	if(ptr == &mons[PM_MAIL_DAEMON]) { 610. 	    if(flags.soundok && canseemon(mtmp)) 611. 		verbalize("I'm late!"); 612. 	    mongone(mtmp); 613. 	    return(2); 614. 	}  615.  #endif 616.  617.  	/* teleport if that lies in our nature */ 618. 	if(ptr == &mons[PM_TENGU] && !rn2(5) && !mtmp->mcan) { 619. 	    if(mtmp->mhp < 7 || mtmp->mpeaceful || rn2(2)) 620. 		rloc(mtmp); 621. 	    else 622. 		mnexto(mtmp); 623. 	    mmoved = 1; 624. 	    goto postmov; 625. 	}  626.  not_special: 627. 	if(u.uswallow && !mtmp->mflee && u.ustuck != mtmp) return(1); 628. 	omx = mtmp->mx; 629. 	omy = mtmp->my; 630. 	gx = mtmp->mux; 631. 	gy = mtmp->muy; 632. 	appr = mtmp->mflee ? -1 : 1; 633.  	if (mtmp->mconf || (u.uswallow && mtmp == u.ustuck)) 634. 		appr = 0; 635. 	else { 636. 		boolean should_see = (couldsee(omx, omy) &&  637.  				      (levl[gx][gy].lit || 638. 				       !levl[omx][omy].lit) &&  639.  				      (dist2(omx, omy, gx, gy) <= 36)); 640.  641.  		if (!mtmp->mcansee ||  642.  		    (should_see && Invis && !perceives(ptr) && rn2(11)) ||  643.  		    (u.usym == S_MIMIC_DEF) || u.uundetected ||  644.  		    (u.usym == 0 && !likes_gold(ptr)) ||  /* 0 => gold */  645.  		    (mtmp->mpeaceful && !mtmp->isshk) ||  /* allow shks to follow */  646.  		    ((ptr->mlet == S_STALKER || ptr->mlet == S_BAT ||  647.  		      ptr->mlet == S_LIGHT) && !rn2(3))) 648. 			appr = 0; 649. 	  650.  		if(monsndx(ptr) == PM_LEPRECHAUN && (appr == 1) &&  651.  		   (mtmp->mgold > u.ugold)) 652. 			appr = -1; 653.  654.  		if (!should_see && can_track(ptr)) { 655. 			register coord *cp; 656.  657.  			cp = gettrack(omx,omy); 658. 			if (cp) { 659. 				gx = cp->x; 660. 				gy = cp->y; 661. 			}  662.  		}  663.  	}  664.   665.  	if ((!mtmp->mpeaceful || !rn2(10))  666.  #ifdef REINCARNATION  667.  				    && (!Is_rogue_level(&u.uz))  668.  #endif  669.  							    ) { 670. 	    boolean in_line = lined_up(mtmp) && 671. 		(distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <=  672.  		    (throws_rocks(uasmon) ? 20 : ACURRSTR/2+1) 673.  		); 674.  675.  	    if (appr != 1 || !in_line) { 676. 		/* Monsters in combat won't pick stuff up, avoiding the 677. 		 * situation where you toss arrows at it and it has nothing 678. 		 * better to do than pick the arrows up. 679. 		 */  680.  		register int pctload = (curr_mon_load(mtmp) * 100) / 681. 			max_mon_load(mtmp); 682.  683.  		/* look for gold or jewels nearby */ 684. 		likegold = (likes_gold(ptr) && pctload < 95); 685. 		likegems = (likes_gems(ptr) && pctload < 85); 686. 		uses_items = (!mindless(ptr) && !is_animal(ptr)  687.  			&& pctload < 75); 688. 		likeobjs = (likes_objs(ptr) && pctload < 75); 689. 		likemagic = (likes_magic(ptr) && pctload < 85); 690. 		likerock = (throws_rocks(ptr) && pctload < 50); 691. 		conceals = hides_under(ptr); 692. 	    }  693.  	}  694.   695.  #define SQSRCHRADIUS	5 696.  697.        { register int minr = SQSRCHRADIUS;	/* not too far away */ 698. 	register struct obj *otmp; 699. 	register int xx, yy; 700. 	int oomx, oomy, lmx, lmy; 701.  702.  	/* cut down the search radius if it thinks character is closer. */ 703.  	if(distmin(mtmp->mux, mtmp->muy, omx, omy) < SQSRCHRADIUS &&  704.  	    !mtmp->mpeaceful) minr--; 705. 	/* guards shouldn't get too distracted */ 706. 	if(!mtmp->mpeaceful && is_mercenary(ptr)) minr = 1; 707.  708.  	if((likegold || likegems || likeobjs || likemagic || likerock || conceals)  709.  	      && (!*in_rooms(omx, omy, SHOPBASE) || (!rn2(25) && !mtmp->isshk))) { 710. 	look_for_obj: 711. 	    oomx = min(COLNO-1, omx+minr); 712. 	    oomy = min(ROWNO-1, omy+minr); 713. 	    lmx = max(1, omx-minr); 714. 	    lmy = max(0, omy-minr); 715. 	    for(otmp = fobj; otmp; otmp = otmp->nobj) { 716. 		/* monsters may pick rocks up, but won't go out of their way 717. 		   to grab them; this might hamper sling wielders, but it cuts 718. 		   down on move overhead by filtering out most common item */ 719. 		if (otmp->otyp == ROCK) continue; 720. 		xx = otmp->ox; 721. 		yy = otmp->oy; 722. 		/* Nymphs take everything. Most other creatures should not 723. 		 * pick up corpses except as a special case like in  724. * searches_for_item. We need to do this check in 725. * mpickstuff as well. 726. 		 */  727.  		if(xx >= lmx && xx <= oomx && yy >= lmy && yy <= oomy) { 728. 		    /* don't get stuck circling around an object that's underneath 729. 		       an immobile or hidden monster; paralysis victims excluded */ 730. 		    if ((mtoo = m_at(xx,yy)) != 0 &&  731.  			(mtoo->msleep || mtoo->mundetected || 732. 			 (mtoo->mappearance && !mtoo->iswiz) || 733. 			 !mtoo->data->mmove)) continue; 734.  735.  		    if(((likegold && otmp->oclass == GOLD_CLASS) || 736. 		       (likeobjs && index(practical, otmp->oclass) &&  737.  			(otmp->otyp != CORPSE || (ptr->mlet == S_NYMPH  738.  			   && !is_rider(&mons[otmp->corpsenm])))) || 739. 		       (likemagic && index(magical, otmp->oclass)) || 740. 		       (uses_items && searches_for_item(mtmp, otmp)) || 741. 		       (likerock && otmp->otyp == BOULDER) || 742. 		       (likegems && otmp->oclass == GEM_CLASS &&  743.  			objects[otmp->otyp].oc_material != MINERAL) || 744. 		       (conceals && !cansee(otmp->ox,otmp->oy)) || 745. 		       (ptr == &mons[PM_GELATINOUS_CUBE] &&  746.  			!index(indigestion, otmp->oclass) &&  747.  			!(otmp->otyp == CORPSE && 748. 			  otmp->corpsenm == PM_COCKATRICE)) 749. 		      ) && touch_artifact(otmp,mtmp)) { 750. 			if(can_carry(mtmp,otmp) &&  751.  			   (throws_rocks(ptr) || 752. 				!sobj_at(BOULDER,xx,yy)) &&  753.  			   (ptr->mlet != S_UNICORN || 754. 			    objects[otmp->otyp].oc_material == GEMSTONE) &&  755.  			   /* Don't get stuck circling an Elbereth */  756.  			   !(onscary(xx, yy, mtmp))) { 757. 			    minr = distmin(omx,omy,xx,yy); 758. 			    oomx = min(COLNO-1, omx+minr); 759. 			    oomy = min(ROWNO-1, omy+minr); 760. 			    lmx = max(1, omx-minr); 761. 			    lmy = max(0, omy-minr); 762. 			    gx = otmp->ox; 763. 			    gy = otmp->oy; 764. 			    if (gx == omx && gy == omy) { 765. 				mmoved = 3; /* actually unnecessary */ 766. 				goto postmov; 767. 			    }  768.  			}  769.  		    }  770.  		}  771.  	    }  772.  	} else if(likegold) { 773. 	    /* don't try to pick up anything else, but use the same loop */ 774. 	    uses_items = 0; 775. 	    likegems = likeobjs = likemagic = likerock = conceals = 0; 776. 	    goto look_for_obj; 777. 	}  778.   779.  	if(minr < SQSRCHRADIUS && appr == -1) { 780. 	    if(distmin(omx,omy,mtmp->mux,mtmp->muy) <= 3) { 781. 		gx = mtmp->mux; 782. 		gy = mtmp->muy; 783. 	    } else 784. 		appr = 1; 785. 	}  786.        }  787.   788.  	if (can_tunnel && needspick(ptr) &&  789.  		(mw_tmp = MON_WEP(mtmp)) != 0 && mw_tmp->otyp != PICK_AXE) { 790. 	    /* not wielding its pick-axe yet; if its current weapon 791. 	       is cursed, then it can't switch; when approaching, 792. 	       it won't switch if the desired destination can be reached 793. 	       without digging [to inhibit repeated pick/weapon flip-flop] */ 794. 	    if (mw_tmp->cursed || (appr > 0 && m_cansee(mtmp, gx, gy))) 795. 		can_tunnel = FALSE; 796. 	}  797.   798.  	nix = omx; 799. 	niy = omy; 800. 	flag = 0L; 801. 	if (mtmp->mpeaceful && (!Conflict || resist(mtmp, RING_CLASS, 0, 0))) 802. 	    flag |= (ALLOW_SANCT | ALLOW_SSM); 803. 	else flag |= ALLOW_U; 804. 	if (ptr->mlet == S_UNICORN) flag |= NOTONL; 805. 	if (passes_walls(ptr)) flag |= (ALLOW_WALL | ALLOW_ROCK); 806. 	if (can_tunnel) flag |= ALLOW_DIG; 807. 	if (is_human(ptr) || ptr == &mons[PM_MINOTAUR]) flag |= ALLOW_SSM; 808. 	if (is_undead(ptr) && ptr->mlet != S_GHOST) flag |= NOGARLIC; 809. 	if (throws_rocks(ptr)) flag |= ALLOW_ROCK; 810. 	if (can_open) flag |= OPENDOOR; 811. 	if (can_unlock) flag |= UNLOCKDOOR; 812. 	if (doorbuster) flag |= BUSTDOOR; 813. 	{  814.  	    register int i, j, nx, ny, nearer; 815. 	    int jcnt, cnt; 816. 	    int ndist, nidist; 817. 	    register coord *mtrk; 818. 	    coord poss[9]; 819.  820.  	    cnt = mfndpos(mtmp, poss, info, flag); 821. 	    chcnt = 0; 822. 	    jcnt = min(MTSZ, cnt-1); 823. 	    chi = -1; 824. 	    nidist = dist2(nix,niy,gx,gy); 825. 	    /* allow monsters be shortsighted on some levels for balance */ 826. 	    if(!mtmp->mpeaceful && level.flags.shortsighted &&  827.  	       nidist > (couldsee(nix,niy) ? 144 : 36) && appr == 1) appr = 0; 828.  829.  	    for(i=0; i < cnt; i++) { 830. 		nx = poss[i].x;  831. ny = poss[i].y; 832. 833. 		if (appr != 0) { 834. 		    mtrk = &mtmp->mtrack[0]; 835. 		    for(j=0; j < jcnt; mtrk++, j++) 836. 			if(nx == mtrk->x && ny == mtrk->y) 837. 			    if(rn2(4*(cnt-j))) 838. 				goto nxti; 839. 		}  840.   841.  		nearer = ((ndist = dist2(nx,ny,gx,gy)) < nidist); 842.  843.  		if((appr == 1 && nearer) || (appr == -1 && !nearer) ||  844.  		   (!appr && !rn2(++chcnt)) || !mmoved) { 845. 		    nix = nx; 846. 		    niy = ny; 847. 		    nidist = ndist; 848. 		    chi = i;  849. mmoved = 1; 850. 		}  851.  	    nxti:	; 852. 	    }  853.  	}  854.   855.  	if(mmoved) { 856. 	    register int j;  857. 858. 	    if (mmoved==1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp)) 859. 		return(3); 860.  861.  	    if (mmoved==1 && can_tunnel && needspick(ptr) &&  862.  		(!(mw_tmp = MON_WEP(mtmp)) || mw_tmp->otyp != PICK_AXE)) { 863. 		mtmp->weapon_check = NEED_PICK_AXE; 864. 		(void)mon_wield_item(mtmp); 865. 	    }  866.  	    /* If ALLOW_U is set, either it's trying to attack you, or it  867. * thinks it is. In either case, attack this spot in preference to 868. * all others. 869. 	     */  870.  	/* Actually, this whole section of code doesn't work as you'd expect. 871. 	 * Most attacks are handled in dochug. It calls distfleeck, which 872. 	 * among other things sets nearby if the monster is near you--and if  873. * nearby is set, we never call m_move unless it is a special case 874. 	 * (confused, stun, etc.)  The effect is that this ALLOW_U (and  875.  	 * mfndpos) has no effect for normal attacks, though it lets a confused 876. 	 * monster attack you by accident. 877. 	 */  878.  	    if(info[chi] & ALLOW_U) { 879. 		nix = mtmp->mux; 880. 		niy = mtmp->muy; 881. 	    }  882.  	    if (nix == u.ux && niy == u.uy) { 883. 		mtmp->mux = u.ux; 884. 		mtmp->muy = u.uy; 885. 		return(0); 886. 	    }  887.  	    /* The monster may attack another based on 1 of 2 conditions: 888. 	     * 1 - It may be confused. 889. 	     * 2 - It may mistake the monster for your (displaced) image. 890. 	     * Pets get taken care of above and shouldn't reach this code. 891. 	     * Conflict gets handled even farther away (movemon). 892. 	     */  893.  	    if((info[chi] & ALLOW_M) ||  894.  		   (nix == mtmp->mux && niy == mtmp->muy)) { 895. 		struct monst *mtmp2; 896. 		int mstatus; 897. 		mtmp2 = m_at(nix,niy); 898.  899.  		mstatus = mattackm(mtmp, mtmp2); 900.  901.  		if (mstatus & MM_AGR_DIED)		/* aggressor died */ 902. 		    return 2; 903.  904.  		if ((mstatus & MM_HIT) && !(mstatus & MM_DEF_DIED)  &&  905.  		    rn2(4) && mtmp2->mlstmv != monstermoves) { 906. 		    mstatus = mattackm(mtmp2, mtmp);	/* return attack */ 907. 		    if (mstatus & MM_DEF_DIED) 908. 			return 2; 909. 		}  910.  		return 3; 911. 	    }  912.   913.  	    remove_monster(omx, omy); 914. 	    place_monster(mtmp, nix, niy); 915. 	    for(j = MTSZ-1; j > 0; j--) 916. 		mtmp->mtrack[j] = mtmp->mtrack[j-1]; 917. 	    mtmp->mtrack[0].x = omx; 918. 	    mtmp->mtrack[0].y = omy; 919. 	    /* Place a segment at the old position. */ 920.  	    if (mtmp->wormno) worm_move(mtmp); 921. 	} else { 922. 	    if(ptr->mlet == S_UNICORN && rn2(2)) { 923. 		rloc(mtmp); 924. 		return(1); 925. 	    }  926.  	    if(mtmp->wormno) worm_nomove(mtmp); 927. 	}  928.  postmov: 929. 	if(mmoved == 1 || mmoved == 3) { 930. 	    boolean canseeit = cansee(mtmp->mx, mtmp->my); 931.  932.  	    if(mmoved == 1) { 933. 		newsym(omx,omy);		/* update the old position */ 934. 		if (mintrap(mtmp) >= 2) { 935. 		    if(mtmp->mx) newsym(mtmp->mx,mtmp->my); 936. 		    return(2);	/* it died */ 937. 		}  938.  		ptr = mtmp->data; 939.  940.  		/* open a door, or crash through it, if you can */ 941. 		if(IS_DOOR(levl[mtmp->mx][mtmp->my].typ)  942.  			&& !passes_walls(ptr) /* doesn't need to open doors */  943.  			&& !can_tunnel /* taken care of below */  944.  		      ) { 945. 		    struct rm *here = &levl[mtmp->mx][mtmp->my]; 946. 		    boolean btrapped = (here->doormask & D_TRAPPED); 947.  948.  		    if(here->doormask & (D_LOCKED|D_CLOSED) && amorphous(ptr)) { 949. 			if (flags.verbose && canseeit) 950. 			    pline("%s %ss under the door.", Monnam(mtmp),  951.  				  (ptr == &mons[PM_FOG_CLOUD] || 952. 				   ptr == &mons[PM_YELLOW_LIGHT])  953.  				  ? "flow" : "ooze"); 954. 		    } else if(here->doormask & D_LOCKED && can_unlock) { 955. 			if(btrapped) { 956. 			    here->doormask = D_NODOOR; 957. 			    newsym(mtmp->mx, mtmp->my); 958. 			    unblock_point(mtmp->mx,mtmp->my); /* vision */ 959. 			    if(mb_trapped(mtmp)) return(2); 960. 			} else { 961. 			    if (flags.verbose) { 962. 				if (canseeit) 963. 				   You("see a door unlock and open."); 964. 				else if (flags.soundok) 965. 				   You_hear("a door unlock and open."); 966. 			    }  967.  			    here->doormask = D_ISOPEN; 968. 			    /* newsym(mtmp->mx, mtmp->my); */ 969. 			    unblock_point(mtmp->mx,mtmp->my); /* vision */ 970. 			}  971.  		    } else if (here->doormask == D_CLOSED && can_open) { 972. 			if(btrapped) { 973. 			    here->doormask = D_NODOOR; 974. 			    newsym(mtmp->mx, mtmp->my); 975. 			    unblock_point(mtmp->mx,mtmp->my); /* vision */ 976. 			    if(mb_trapped(mtmp)) return(2); 977. 			} else { 978. 			    if (flags.verbose) { 979. 				if (canseeit) 980. 				     You("see a door open."); 981. 				else if (flags.soundok) 982. 				     You_hear("a door open."); 983. 			    }  984.  			    here->doormask = D_ISOPEN; 985. 			    /* newsym(mtmp->mx, mtmp->my); */  /* done below */ 986. 			    unblock_point(mtmp->mx,mtmp->my); /* vision */ 987. 			}  988.  		    } else if (here->doormask & (D_LOCKED|D_CLOSED)) { 989. 			/* mfndpos guarantees this must be a doorbuster */ 990. 			if(btrapped) { 991. 			    here->doormask = D_NODOOR; 992. 			    newsym(mtmp->mx, mtmp->my); 993. 			    unblock_point(mtmp->mx,mtmp->my); /* vision */ 994. 			    if(mb_trapped(mtmp)) return(2); 995. 			} else { 996. 			    if (flags.verbose) { 997. 				if (canseeit) 998. 				    You("see a door crash open."); 999. 				else if (flags.soundok) 1000. 				   You_hear("a door crash open."); 1001. 			   }  1002. 			    if (here->doormask & D_LOCKED && !rn2(2)) 1003. 				   here->doormask = D_NODOOR; 1004. 			   else here->doormask = D_BROKEN; 1005. 			   /* newsym(mtmp->mx, mtmp->my); */ /* done below */ 1006. 			   unblock_point(mtmp->mx,mtmp->my); /* vision */ 1007. 			} 1008. 		    }  1009. 		}  1010.  1011. 		/* possibly dig */ 1012. 		if (can_tunnel && mdig_tunnel(mtmp)) 1013. 			return(2); /* mon died (position already updated) */ 1014. 1015. 		/* set also in domove, hack.c */ 1016. 		if (u.uswallow && mtmp == u.ustuck && 1017. 					(mtmp->mx != omx || mtmp->my != omy)) { 1018. 		   /* If the monster moved, then update */ 1019. 		   u.ux0 = u.ux; 1020. 		   u.uy0 = u.uy; 1021. 		   u.ux = mtmp->mx; 1022. 		   u.uy = mtmp->my; 1023. 		   swallowed(0); 1024. 		} else 1025. 		newsym(mtmp->mx,mtmp->my); 1026. 	   }  1027. 	    if(OBJ_AT(mtmp->mx, mtmp->my) && mtmp->mcanmove) { 1028. 		/* Maybe a rock mole just ate some metal object */ 1029. 		if (metallivorous(ptr)) { 1030. 		   if (meatgold(mtmp) == 2) return 2;	/* it died */ 1031. 		} 1032.  1033. 		if(g_at(mtmp->mx,mtmp->my) && likegold) mpickgold(mtmp); 1034. 1035. 		/* Maybe a cube ate just about anything */ 1036. 		if (ptr == &mons[PM_GELATINOUS_CUBE]) { 1037. 		   if (meatobj(mtmp) == 2) return 2;	/* it died */ 1038. 		} 1039.  1040. 		if(!*in_rooms(mtmp->mx, mtmp->my, SHOPBASE) || !rn2(25)) { 1041. 		   boolean picked = FALSE; 1042. 1043. 		    if(likeobjs) picked |= mpickstuff(mtmp, practical); 1044. 		   if(likemagic) picked |= mpickstuff(mtmp, magical); 1045. 		   if(likerock) picked |= mpickstuff(mtmp, boulder_class); 1046. 		   if(likegems) picked |= mpickstuff(mtmp, gem_class); 1047. 		   if(uses_items) picked |= mpickstuff(mtmp, (char *)0); 1048. 		   if(picked) mmoved = 3; 1049. 		} 1050.  1051. 		if(mtmp->minvis) { 1052. 		   newsym(mtmp->mx, mtmp->my); 1053. 		   if (mtmp->wormno) see_wsegs(mtmp); 1054. 		} 1055. 	    }  1056.  1057. 	    if(hides_under(ptr) || ptr->mlet == S_EEL) { 1058. 		/* Always set--or reset--mundetected if it's already hidden 1059. 		  (just in case the object it was hiding under went away); 1060. 		  usually set mundetected unless monster can't move. */ 1061. 		if (mtmp->mundetected ||  1062. 			(mtmp->mcanmove && !mtmp->msleep && rn2(5))) 1063. 		   mtmp->mundetected = (ptr->mlet != S_EEL) ? 1064. 			OBJ_AT(mtmp->mx, mtmp->my) : 1065. 			(is_pool(mtmp->mx, mtmp->my) && !Is_waterlevel(&u.uz)); 1066. 		newsym(mtmp->mx, mtmp->my); 1067. 	   }  1068. 	}  1069. 	return(mmoved); 1070. } 1071.  1072. #endif /* OVL0 */ 1073. #ifdef OVL2 1074. 1075. boolean 1076. closed_door(x, y) 1077. register int x, y; 1078. { 1079. 	return((boolean)(IS_DOOR(levl[x][y].typ) && 1080. 			(levl[x][y].doormask & (D_LOCKED | D_CLOSED)))); 1081. } 1082.  1083. boolean 1084. accessible(x, y) 1085. register int x, y; 1086. { 1087. 	return((boolean)(ACCESSIBLE(levl[x][y].typ) && !closed_door(x, y))); 1088. } 1089.  1090. #endif /* OVL2 */ 1091. #ifdef OVL0 1092. 1093. /* decide where the monster thinks you are standing */ 1094. void 1095. set_apparxy(mtmp) 1096. register struct monst *mtmp; 1097. { 1098. 	boolean notseen, gotu; 1099. 	register int disp, mx = mtmp->mux, my = mtmp->muy; 1100. 1101. 	/*  1102. 	 * do cheapest and/or most likely tests first 1103. 	 */ 1104.  1105. 	/* pet knows your smell; grabber still has hold of you */ 1106. 	if (mtmp->mtame || mtmp == u.ustuck) goto found_you; 1107. 1108. 	/* monsters which know where you are don't suddenly forget, 1109. 	  if you haven't moved away */ 1110. 	if (mx == u.ux && my == u.uy) goto found_you; 1111. 1112. 	notseen = (!mtmp->mcansee || (Invis && !perceives(mtmp->data))); 1113. 	/* add cases as required. eg. Displacement ... */ 1114. 	disp = ((notseen || Underwater) ? 1 :  1115. 		Displaced ? (couldsee(mx, my) ? 2 : 1) : 0); 1116. 	if (!disp) goto found_you; 1117. 1118. 	/* without something like the following, invis. and displ. 1119. 	  are too powerful */ 1120. 	gotu = notseen ? !rn2(3) : Displaced ? !rn2(4) : FALSE; 1121. 1122. #if 0		/* this never worked as intended & isn't needed anyway */ 1123. 	/* If invis but not displaced, staying around gets you 'discovered' */ 1124. 	gotu |= (!Displaced && u.dx == 0 && u.dy == 0); 1125. #endif 1126. 1127. 	if (!gotu) { 1128. 	   register int try_cnt = 0; 1129. 	   do { 1130. 		if (++try_cnt > 200) goto found_you;		/* punt */ 1131. 		mx = u.ux - disp + rn2(2*disp+1); 1132. 		my = u.uy - disp + rn2(2*disp+1); 1133. 	   } while (!isok(mx,my)  1134. 		  || (disp != 2 && mx == mtmp->mx && my == mtmp->my)  1135. 		  || ((mx != u.ux || my != u.uy) && 1136. 		     !passes_walls(mtmp->data) && 1137. 		     (!ACCESSIBLE(levl[mx][my].typ) ||  1138. 			(closed_door(mx, my) && !amorphous(mtmp->data))))); 1139. 	} else { 1140. found_you: 1141. 	   mx = u.ux; 1142. 	   my = u.uy; 1143. 	} 1144.  1145. 	mtmp->mux = mx; 1146. 	mtmp->muy = my; 1147. } 1148.  1149. #endif /* OVL0 */ 1150. 1151. /*monmove.c*/