Source:Monmove.c

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