Source:NetHack 3.4.0/monmove.c

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