Source:NetHack 3.1.0/monmove.c

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

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

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