Source:NetHack 3.3.0/monmove.c

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