Source:SLASH'EM 0.0.7E7F2/monmove.c

Below is the full text to monmove.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/monmove.c#line123 ]], for example.

The latest source code for vanilla NetHack is at Source code.

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