Source:NetHack 2.2a/mon.c

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

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

1.   /*	SCCS Id: @(#)mon.c	2.1	87/10/17 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.     4.    #include "hack.h"  5.    #include "mfndpos.h"  6.    extern struct monst *mkmon_at; 7.   extern struct trap *maketrap; 8.   extern struct obj *mkobj_at, *mksobj_at; 9.   extern char *hcolor; 10.  #ifdef KAA 11.  extern boolean	stoned; 12.  extern char mlarge[]; 13.  #endif 14.  #ifdef RPH 15.  extern struct obj *mk_named_obj_at; 16.  #endif 17.   18.   int warnlevel;		/* used by movemon and dochugw */ 19.  long lastwarntime; 20.  int lastwarnlev; 21.  char	*warnings[] = {	"white", "pink", "red", "ruby", "purple", "black"  }; 22.   23.   movemon 24.  {  25.   	register struct monst *mtmp; 26.  	register int fr; 27.   28.   	warnlevel = 0; 29.   30.   	while(1) { 31.  		/* find a monster that we haven't treated yet */ 32.  		/* note that mtmp or mtmp->nmon might get killed 33.  		   while mtmp moves, so we cannot just walk down the 34.  		   chain (even new monsters might get created!) */ 35.  		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 36.  			if(mtmp->mlstmv < moves) goto next_mon; 37.  		/* treated all monsters */ 38.  		break; 39.   40.   	next_mon: 41.  		mtmp->mlstmv = moves; 42.   43.   		/* most monsters drown in pools */ 44.  		{ boolean inpool, iseel; 45.   46.   		  inpool = (levl[mtmp->mx][mtmp->my].typ == POOL); 47.  		  iseel = (mtmp->data->mlet == ';'); 48.  		  if(inpool && !iseel) { 49.  			if(cansee(mtmp->mx,mtmp->my)) 50.  			    pline("%s drowns.", Monnam(mtmp)); 51.  			mondead(mtmp); 52.  			continue; 53.  		  }  54.   		/* but eels have a difficult time outside */ 55.  		  if(iseel && !inpool) { 56.  			if(mtmp->mhp > 1) mtmp->mhp--; 57.  			mtmp->mflee = 1; 58.  			mtmp->mfleetim += 2; 59.  		  }  60.   		}  61.   		if(mtmp->mblinded && !--mtmp->mblinded) 62.  			mtmp->mcansee = 1; 63.  		if(mtmp->mfleetim && !--mtmp->mfleetim) 64.  			mtmp->mflee = 0; 65.  #ifdef HARD 66.  		/* unwatched mimics and piercers may hide again  [MRS] */ 67.  		if(restrap(mtmp))	continue; 68.  #endif 69.  		if(mtmp->mimic) continue; 70.  		if(mtmp->mspeed != MSLOW || !(moves%2)){ 71.  			/* continue if the monster died fighting */ 72.  			fr = -1; 73.  			if(Conflict && cansee(mtmp->mx,mtmp->my)  74.   				&& (fr = fightm(mtmp)) == 2) 75.  				continue; 76.  			if(fr<0 && dochugw(mtmp)) 77.  				continue; 78.  		}  79.   		if(mtmp->mspeed == MFAST && dochugw(mtmp)) 80.  			continue; 81.  	}  82.    83.   	warnlevel -= u.ulevel; 84.  	if(warnlevel >= SIZE(warnings)) 85.  		warnlevel = SIZE(warnings)-1; 86.  	if(warnlevel >= 0) 87.  	if(warnlevel > lastwarnlev || moves > lastwarntime + 5){ 88.  	    register char *rr; 89.  	    switch((int) (Warning & (LEFT_RING | RIGHT_RING))){ 90.  	    case LEFT_RING: 91.  		rr = "Your left ring glows"; 92.  		break; 93.  	    case RIGHT_RING: 94.  		rr = "Your right ring glows"; 95.  		break; 96.  	    case LEFT_RING | RIGHT_RING: 97.  		rr = "Both your rings glow"; 98.  		break; 99.  	    default: 100. 		rr = "Your fingertips glow"; 101. 		break; 102. 	    }  103.  	    pline("%s %s!", rr, Hallucination ? hcolor : warnings[warnlevel]); 104. 	    lastwarntime = moves; 105. 	    lastwarnlev = warnlevel; 106. 	}  107.   108.  	dmonsfree;	/* remove all dead monsters */ 109. }  110.   111.  justswld(mtmp,name) 112. register struct monst *mtmp; 113. char *name; 114. {  115.   116.  	mtmp->mx = u.ux; 117. 	mtmp->my = u.uy; 118. 	u.ustuck = mtmp; 119. 	pmon(mtmp); 120. 	kludge("%s swallows you!",name); 121. 	more; 122. 	seeoff(1); 123. 	u.uswallow = 1; 124. 	u.uswldtim = 0; 125. 	swallowed; 126. }  127.   128.  youswld(mtmp,dam,die,name) 129. register struct monst *mtmp; 130. register dam,die; 131. char *name; 132. {  133.  	if(mtmp != u.ustuck) return; 134. 	kludge("%s digests you!",name); 135. 	u.uhp -= dam; 136. 	if(u.uswldtim++ >= die){	/* a3 */ 137. 		pline("It totally digests you!"); 138. 		u.uhp = -1; 139. 	}  140.  	if(u.uhp < 1) done_in_by(mtmp); 141. 	/* flags.botlx = 1;		/* should we show status line ? */ 142.  }  143.   144.  #ifdef ROCKMOLE 145. meatgold(mtmp) register struct monst *mtmp; { 146. register struct gold *gold; 147. register int pile; 148. register struct obj *otmp; 149. #ifdef KJSMODS 150. 	if(dlevel < 4) return; 151. #endif 152. 	/* Eats gold if it is there */ 153. 	while(gold = g_at(mtmp->mx, mtmp->my)){ 154. 		freegold(gold); 155. 		/* Left behind a pile? */ 156.  		pile = rnd(25); 157. 		if(pile < 3) mksobj_at(ROCK, mtmp->mx, mtmp->my); 158. 		newsym(mtmp->mx, mtmp->my); 159. 	}  160.  	/* Eats armor if it is there */ 161. 	otmp = o_at(mtmp->mx,mtmp->my); 162. 	if((otmp) && (otmp->otyp >= PLATE_MAIL) && (otmp->otyp <= RING_MAIL)){ 163. 		freeobj(otmp); 164. 		/* Left behind a pile? */ 165.  		pile = rnd(25); 166. 		if(pile < 3)  mksobj_at(ROCK, mtmp->mx, mtmp->my); 167. 		newsym(mtmp->mx, mtmp->my); 168. 	}  169.  }  170.  #endif /* ROCKMOLE /**/ 171.  172.  mpickgold(mtmp) register struct monst *mtmp; { 173. register struct gold *gold; 174. 	while(gold = g_at(mtmp->mx, mtmp->my)){ 175. 		mtmp->mgold += gold->amount; 176. 		freegold(gold); 177. 		if(levl[mtmp->mx][mtmp->my].scrsym == GOLD_SYM) 178. 			newsym(mtmp->mx, mtmp->my); 179. 	}  180.  }  181.   182.  /* Now includes giants which pick up enormous rocks. KAA */ 183. mpickgems(mtmp) register struct monst *mtmp; { 184. register struct obj *otmp; 185. 	for(otmp = fobj; otmp; otmp = otmp->nobj) 186. 	  if(otmp->olet ==  187.  #ifdef KAA  188.  			   (mtmp->data->mlet=='9' ? ROCK_SYM : GEM_SYM)) 189. #else 190. 			   GEM_SYM)  191.  #endif  192.  	    if(otmp->ox == mtmp->mx && otmp->oy == mtmp->my)  193.  	      if(mtmp->data->mlet != 'u' || objects[otmp->otyp].g_val != 0){  194.  		freeobj(otmp);  195.  		mpickobj(mtmp, otmp);  196.  #ifndef KAA  197.  		if(levl[mtmp->mx][mtmp->my].scrsym == GEM_SYM)  198.  #endif  199.  			newsym(mtmp->mx, mtmp->my);	/* %% */  200.  		return;	/* pick only one object */  201.  	      }  202.  }  203.   204.  /* return number of acceptable neighbour positions */  205.  mfndpos(mon,poss,info,flag)  206.  register struct monst *mon;  207.  coord poss[9];  208.  long info[9], flag;  209.  {  210.  	register int x,y,nx,ny,cnt = 0,ntyp;  211.  	register struct monst *mtmp;  212.  	int nowtyp;  213.  	boolean pool;  214.   215.  	x = mon->mx;  216.  	y = mon->my;  217.  	nowtyp = levl[x][y].typ;  218.   219.  	pool = (mon->data->mlet == ';');  220.  nexttry:	/* eels prefer the water, but if there is no water nearby, 221. 		   they will crawl over land */ 222. 	if(mon->mconf) { 223. 		flag |= ALLOW_ALL; 224. 		flag &= ~NOTONL; 225. 	}  226.  	for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) 227. 	if(nx != x || ny != y) if(isok(nx,ny)) 228. #ifdef ROCKMOLE 229. 	if(!IS_ROCK(ntyp = levl[nx][ny].typ) || (flag & ALLOW_WALL)) 230. #else 231. 	if(!IS_ROCK(ntyp = levl[nx][ny].typ)) 232. #endif 233. 	if(!(nx != x && ny != y && (nowtyp == DOOR || ntyp == DOOR))) 234. 	if((ntyp == POOL) == pool) { 235. 		info[cnt] = 0; 236. 		if(nx == u.ux && ny == u.uy){ 237. 			if(!(flag & ALLOW_U)) continue; 238. 			info[cnt] = ALLOW_U; 239. 		} else if(mtmp = m_at(nx,ny)){ 240. 			if(!(flag & ALLOW_M)) continue; 241. 			info[cnt] = ALLOW_M; 242. 			if(mtmp->mtame){ 243. 				if(!(flag & ALLOW_TM)) continue; 244. 				info[cnt] |= ALLOW_TM; 245. 			}  246.  		}  247.  		if(sobj_at(CLOVE_OF_GARLIC, nx, ny)) { 248. 			if(flag & NOGARLIC) continue; 249. 			info[cnt] |= NOGARLIC; 250. 		}  251.  		if(sobj_at(SCR_SCARE_MONSTER, nx, ny) ||  252.  		   (!mon->mpeaceful && sengr_at("Elbereth", nx, ny))) { 253. 			if(!(flag & ALLOW_SSM)) continue; 254. 			info[cnt] |= ALLOW_SSM; 255. 		}  256.  		if(sobj_at(ENORMOUS_ROCK, nx, ny)) { 257. 			if(!(flag & ALLOW_ROCK)) continue; 258. 			info[cnt] |= ALLOW_ROCK; 259. 		}  260.  		if(!Invis && online(nx,ny)){ 261. 			if(flag & NOTONL) continue; 262. 			info[cnt] |= NOTONL; 263. 		}  264.  		/* we cannot avoid traps of an unknown kind */ 265. 		{ register struct trap *ttmp = t_at(nx, ny); 266. 		  register long tt; 267. 			if(ttmp) { 268. 				tt = 1L << ttmp->ttyp; 269. 				/* below if added by GAN 02/06/87 to avoid 270. 				 * traps out of range 271. 				 */  272.  				if(!(tt & ALLOW_TRAPS))  { 273. 					impossible("A monster looked at a very strange trap"); 274. 					continue; 275. 				}  276.  				if(mon->mtrapseen & tt){ 277. 					if(!(flag & tt)) continue; 278. 					info[cnt] |= tt; 279. 				}  280.  			}  281.  		}  282.  		poss[cnt].x = nx; 283. 		poss[cnt].y = ny; 284. 		cnt++; 285. 	}  286.  	if(!cnt && pool && nowtyp != POOL) { 287. 		pool = FALSE; 288. 		goto nexttry; 289. 	}  290.  	return(cnt); 291. }  292.   293.  dist(x,y) int x,y; { 294. 	return((x-u.ux)*(x-u.ux) + (y-u.uy)*(y-u.uy)); 295. }  296.   297.  poisoned(string, pname) 298. register char *string, *pname; 299. {  300.  	register i, plural; 301.  302.  	plural = (string[strlen(string) - 1] == 's')? 1 : 0; 303.  	if(Blind) { 304. 		if (plural)	pline("They were poisoned."); 305. 		else		pline("It was poisoned."); 306. 	} else	{ 307. 		if (plural)	pline("The %s were poisoned!", string); 308. 		else		pline("The %s was poisoned!", string); 309. 	}  310.   311.  	if(Poison_resistance) { 312. 		pline("The poison doesn't seem to affect you."); 313. 		return; 314. 	}  315.  	i = rn2(10); 316. 	if(i == 0) { 317. 		u.uhp = -1; 318. 		pline("I am afraid the poison was deadly ..."); 319. 	} else if(i <= 5) { 320. 		losestr(rn1(3,3)); 321. 	} else { 322. 		losehp(rn1(10,6), pname); 323. 	}  324.  	if(u.uhp < 1) { 325. 		killer = pname; 326. 		done("died"); 327. 	}  328.  }  329.   330.  mondead(mtmp) 331. register struct monst *mtmp; 332. {  333.  	relobj(mtmp,1); 334. 	unpmon(mtmp); 335. 	relmon(mtmp); 336. 	unstuck(mtmp); 337. #ifdef KOPS 338.        if(mtmp->data->mlet == 'K' &&  339.            !strcmp(mtmp->data->mname,"Keystone Kop")) { 340. 	   /* When a Kop dies, he probably comes back. */ 341.  	   switch(rnd(3)) { 342.  343.  		case 1:	     /* returns near the stairs */ 344. 			mkmon_at('K',xdnstair,ydnstair); 345. 			break; 346. 		case 2:	     /* randomly */ 347. 			mkmon_at('K',0,0); 348. 			break; 349. 		default: 350. 			break; 351. 	   }  352.  	  }  353.  #endif 354. 	if(mtmp->isshk) shkdead(mtmp); 355. 	if(mtmp->isgd) gddead; 356. #ifndef NOWORM 357. 	if(mtmp->wormno) wormdead(mtmp); 358. #endif 359. #ifdef HARD 360. 	if(mtmp->data->mlet == '1') wizdead(mtmp); 361. #endif 362. 	monfree(mtmp); 363. }  364.   365.  /* called when monster is moved to larger structure */ 366. replmon(mtmp,mtmp2) 367. register struct monst *mtmp, *mtmp2; 368. {  369.  	relmon(mtmp); 370. 	monfree(mtmp); 371. 	mtmp2->nmon = fmon; 372. 	fmon = mtmp2; 373. 	if(u.ustuck == mtmp) u.ustuck = mtmp2; 374. 	if(mtmp2->isshk) replshk(mtmp,mtmp2); 375. 	if(mtmp2->isgd) replgd(mtmp,mtmp2); 376. }  377.   378.  relmon(mon) 379. register struct monst *mon; 380. {  381.  	register struct monst *mtmp; 382.  383.  	if (fmon == 0)  panic ("relmon: no fmon available."); 384.  385.  	if(mon == fmon) fmon = fmon->nmon; 386. 	else { 387. 		for(mtmp = fmon; mtmp->nmon != mon; mtmp = mtmp->nmon) ; 388. 		mtmp->nmon = mon->nmon; 389. 	}  390.  }  391.   392.  /* we do not free monsters immediately, in order to have their name 393.    available shortly after their demise */ 394. struct monst *fdmon;	/* chain of dead monsters, need not to be saved */ 395.  396.  monfree(mtmp) register struct monst *mtmp; { 397. 	mtmp->nmon = fdmon; 398. 	fdmon = mtmp; 399. }  400.   401.  dmonsfree{ 402. register struct monst *mtmp; 403. 	while(mtmp = fdmon){ 404. 		fdmon = mtmp->nmon; 405. 		free((char *) mtmp); 406. 	}  407.  }  408.   409.  unstuck(mtmp) 410. register struct monst *mtmp; 411. {  412.  	if(u.ustuck == mtmp) { 413. 		if(u.uswallow){ 414. 			u.ux = mtmp->mx; 415. 			u.uy = mtmp->my; 416. 			u.uswallow = 0; 417. 			setsee; 418. 			docrt; 419. 		}  420.  		u.ustuck = 0; 421. 	}  422.  }  423.   424.  killed(mtmp) 425. register struct monst *mtmp; 426. {  427.  	xkilled(mtmp, 1); 428. }  429.   430.  xkilled(mtmp, dest) 431. register struct monst *mtmp; 432. int	dest; 433. /* Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse 434.    either; dest=3, message but no corpse */ 435. {  436.  #ifdef LINT 437. #define	NEW_SCORING 438. #endif 439. 	register int tmp,tmp2,nk,x,y; 440. 	register struct permonst *mdat = mtmp->data; 441. 	extern long newuexp; 442. #ifdef RPH 443. 	int old_nlth; 444. 	char old_name[BUFSZ]; 445. #endif 446.  447.  	if(mtmp->cham) mdat = PM_CHAMELEON; 448. 	if (dest & 1) { 449. 	    if(Blind) pline("You destroy it!"); 450. 	    else { 451. 		pline("You destroy %s!",  452.  			mtmp->mtame ? amonnam(mtmp, "poor") : monnam(mtmp)); 453. 	    }  454.  	}  455.  	if(u.umconf) { 456. 		if(!Blind) 457. 		{  458.  			pline("Your hands stop glowing %s.",  459.  			Hallucination ? hcolor : "blue"); 460. 		}  461.  		u.umconf = 0; 462. 	}  463.   464.  	/* count killed monsters */ 465. #define	MAXMONNO	100 466. 	nk = 1;		      /* in case we cannot find it in mons */ 467. 	tmp = mdat - mons;    /* index in mons array (if not 'd', '@', ...) */ 468. 	if(tmp >= 0 && tmp < CMNUM+2) { 469. 	    extern char fut_geno[]; 470. 	    u.nr_killed[tmp]++; 471. 	    if((nk = u.nr_killed[tmp]) > MAXMONNO &&  472.  #ifdef HARD  473.  # ifdef KOPS  474.  		!index("KkO&", mdat->mlet) &&  475.  # else  476.  		!index("kO&", mdat->mlet) &&  477.  # endif  478.  #endif  479.  		!index(fut_geno, mdat->mlet)) 480. 		    charcat(fut_geno,  mdat->mlet); 481. 	}  482.   483.  	/* punish bad behaviour */ 484. 	if(mdat->mlet == '@') { 485. 		HTelepat = 0; 486. 		u.uluck -= 2; 487. 	}  488.  	if(mtmp->mpeaceful || mtmp->mtame) u.uluck--; 489. 	if(mdat->mlet == 'u') u.uluck -= 5; 490. 	if((int)u.uluck < LUCKMIN) u.uluck = LUCKMIN; 491.  492.  	/* give experience points */ 493. 	tmp = 1 + mdat->mlevel * mdat->mlevel; 494. 	if(mdat->ac < 3) tmp += 2*(7 - mdat->ac); 495. 	if(index( 496. #ifdef RPH 497. # ifdef KAA 498. 		 "AcsSDXaeRTVWU&In:P89", 499. # else 500. 		 "AcsSDXaeRTVWU&In:P8", 501. # endif 502. #else 503. # ifdef KAA 504. 		 "AcsSDXaeRTVWU&In:P9", 505. # else 506. 		 "AcsSDXaeRTVWU&In:P", 507. # endif 508. #endif 509. 					 mdat->mlet)) tmp += 2*mdat->mlevel; 510.  511.  	if(index("DeV&P",mdat->mlet)) tmp += (7*mdat->mlevel); 512. 	if(mdat->mlevel > 6) tmp += 50; 513. 	if(mdat->mlet == ';') tmp += 1000; 514.  515.  #ifdef NEW_SCORING 516. 	/* --- recent addition: make nr of points decrease 517. 		   when this is not the first of this kind */ 518. 	{ int ul = u.ulevel; 519. 	  int ml = mdat->mlevel; 520.  521.  	if(ul < 14)    /* points are given based on present and future level */ 522. 	    for(tmp2 = 0; !tmp2 || ul + tmp2 <= ml; tmp2++) 523. 		if(u.uexp + 1 + (tmp + ((tmp2 <= 0) ? 0 : 4<<(tmp2-1)))/nk  524.  		    >= 10*pow((unsigned)(ul-1))) 525. 			if(++ul == 14) break; 526.  527.  	tmp2 = ml - ul -1; 528. 	tmp = (tmp + ((tmp2 < 0) ? 0 : 4<= newuexp){ 538. #ifdef RPH 539. 		/* make experience gaining simiar to d&d, whereby you */ 540. 		/* can at most go up by one level at a time, extra expr */ 541. 		/* possibly helping you along. Afterall, how much real */ 542. 		/* experience does one get shooting a wand of death at */ 543. 		/* a dragon created w/ a poymorph?? */ 544.  		u.ulevel++; 545. 		if (u.uexp >= newuexp) 546. 		    u.uexp = newuexp - 1; 547. 		pline("Welcome to experience level %u.", u.ulevel); 548. #else 549. 		pline("Welcome to experience level %u.", ++u.ulevel); 550. #endif 551. 		tmp = rnd(10); 552. 		if(tmp < 3) tmp = rnd(10); 553. 		u.uhpmax += tmp; 554. 		u.uhp += tmp; 555. #ifdef SPELLS 556. 		tmp = rnd(u.ulevel/2+1) + 1;	/* M. Stephenson */ 557. 		u.uenmax += tmp; 558. 		u.uen += tmp; 559. #endif 560. 		flags.botl = 1; 561. 	}  562.   563.  	/* dispose of monster and make cadaver */ 564. 	x = mtmp->mx;	y = mtmp->my; 565. #ifdef RPH 566. 	old_nlth = mtmp->mnamelth; 567. 	if (old_nlth > 0)  (void) strcpy (old_name, NAME(mtmp)); 568. #endif 569. 	mondead(mtmp); 570. 	tmp = mdat->mlet; 571. 	if(tmp == 'm') { /* he killed a minotaur, give him a wand of digging */ 572. 			/* note: the dead minotaur will be on top of it! */ 573.  		mksobj_at(WAN_DIGGING, x, y); 574. 		/* if(cansee(x,y)) atl(x,y,fobj->olet); */ 575. 		stackobj(fobj); 576. 	} else 577. #ifndef NOWORM 578. 	if(tmp == 'w') { 579. 		mksobj_at(WORM_TOOTH, x, y); 580. 		stackobj(fobj); 581. 	} else 582. #endif 583. #ifdef KJSMODS 584. 	if(tmp == 'N') { 585. 		mksobj_at(POT_OBJECT_DETECTION, x, y); 586. 		stackobj(fobj); 587. 	} else 588. #endif 589. #ifdef KAA 590. 	if(tmp == '&') (void) mkobj_at(0, x, y); 591. 	else 592. 	if(stoned == FALSE && (!letter(tmp) || (!index("9&1", tmp) && !rn2(3)))) tmp = 0; 593. 	    if(dest & 2) { 594. 		newsym(x,y); 595. 		return; 596. 	    }  597.  #else 598. 	if(!letter(tmp) || (!index("mw", tmp) && !rn2(3))) tmp = 0; 599. #endif 600. 	tmp2 = rn2(5); 601. #ifdef KJSMODS 602. 	/* if a kobold or a giant rat does not become treasure, do  603. * not make a corpse. */ 604.  # ifdef KOPS 605. 	if(mdat->mlet == 'K'  606.  	   && !strcmp(mdat->mname,"kobold") && tmp) tmp2 = 0; 607. # endif 608. # ifdef ROCKMOLE 609. 	if((mdat->mlet == 'r' && dlevel < 4) && tmp) tmp2 = 0; 610. # endif 611. #endif 612. 	if(!ACCESSIBLE(levl[x][y].typ)) { 613. 	    /* might be mimic in wall or dead eel*/ 614.  	    newsym(x,y); 615. 	} else if(x != u.ux || y != u.uy) { 616. 		/* might be here after swallowed */ 617. #ifdef KAA 618. 		if(stoned) { 619. 			register int typetmp; 620. 			if(index(mlarge, tmp))	typetmp = ENORMOUS_ROCK; 621. 			else			typetmp = ROCK; 622. 			mksobj_at(typetmp, x, y); 623. 			if(cansee(x,y)) 624. 			    atl(x, y, Hallucination ? rndobjsym :  625.  				      objects[typetmp].oc_olet); 626. 		} else 627. #endif 628. 		if(index("NTVm&w",mdat->mlet) || tmp2) { 629. #ifndef RPH 630. 			register struct obj *obj2 = mkobj_at(tmp,x,y); 631. #else 632. 			register struct obj *obj2; 633. 			if (letter(tmp)) 634. 			    obj2 = mk_named_obj_at(tmp, x, y,  635.  						   old_name, old_nlth); 636. # ifdef KOPS 637. 			else if (mdat->mlet == 'K') 638. 			    obj2 = mksobj_at((rn2(4) ? CLUB : WHISTLE), x, y); 639. # endif 640. 			else 641. 			    obj2 = mkobj_at(tmp,x,y); 642. #endif   /* RPH /**/ 643. 			if(cansee(x,y)) 644. 			    atl(x, y, Hallucination ? rndobjsym : obj2->olet); 645. 			stackobj(obj2); 646. 		}  647.  	}  648.  }  649.   650.  kludge(str,arg) 651. register char *str,*arg; 652. {  653.  	if(Blind) { 654. 		if(*str == '%') pline(str,"It"); 655. 		else pline(str,"it"); 656. 	} else pline(str,arg); 657. }  658.   659.  rescham	/* force all chameleons to become normal */ 660. {  661.  	register struct monst *mtmp; 662.  663.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 664. 		if(mtmp->cham) { 665. 			mtmp->cham = 0; 666. 			(void) newcham(mtmp, PM_CHAMELEON); 667. 		}  668.  }  669.   670.  #ifdef DGKMOD 671. /* Let the chameleons change again -dgk */ 672. restartcham 673. {  674.  	register struct monst *mtmp; 675.  676.  	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) 677. 		if (mtmp->data->mlet == ':') 678. 			mtmp->cham = 1; 679. }  680.  #endif 681.  682.  newcham(mtmp,mdat)	/* make a chameleon look like a new monster */ 683. 			/* returns 1 if the monster actually changed */ 684. register struct monst *mtmp; 685. register struct permonst *mdat; 686. {  687.  	register mhp, hpn, hpd; 688.  689.  	if(mdat == mtmp->data) return(0);	/* still the same monster */ 690. #ifndef NOWORM 691. 	if(mtmp->wormno) wormdead(mtmp);	/* throw tail away */ 692. #endif 693. 	hpn = mtmp->mhp; 694. 	hpd = (mtmp->data->mlevel)*8;	if(!hpd) hpd = 4; 695. 	mhp = (mdat->mlevel)*8;		if(!mhp) mhp = 4; 696.  697.  	/* new hp: same fraction of max as before */ 698. 	mtmp->mhp = (hpn*mhp)/hpd; 699. 	if (mhp > hpd && mtmp->mhp < hpn) mtmp->mhp = 127; 700. /* Not totally foolproof. A 2HD monster with 80 HP that changes into a 6HD 701.    monster that really should have 240 and actually should have 127, the 702.    maximum possible, will wind up having 113. */ 703.  	if (!mtmp->mhp) mtmp->mhp = 1; 704. /* Unlikely but not impossible; a 1HD creature with 1HP that changes into a  705. 0HD creature will require this statement */ 706. 	mtmp->data = mdat; 707. /* and the same for maximum hit points */ 708. 	hpn = mtmp->mhpmax; 709. 	mtmp->mhpmax = (hpn*mhp)/hpd; 710. 	if (mhp > hpd && mtmp->mhpmax < hpn) mtmp->mhp = 127; 711. 	if (!mtmp->mhp) mtmp->mhp = 1; 712.  713.  	mtmp->minvis = (mdat->mlet == 'I') ? 1 : 0; 714.  	/* only snakes and scorpions can hide under things -dgk */ 715. 	/* also generated by GAN */ 716. 	mtmp->mhide = (mdat->mlet == 'S' || mdat->mlet == 's') ? 1 : 0; 717.  	if (!mtmp->mhide) mtmp->mundetected = 0; 718. #ifndef NOWORM 719. 	if(mdat->mlet == 'w' && getwn(mtmp)) initworm(mtmp); 720. 			/* perhaps we should clear mtmp->mtame here? */ 721.  #endif 722. 	unpmon(mtmp);	/* necessary for 'I' and to force pmon */ 723. 	pmon(mtmp); 724. 	return(1); 725. }  726.   727.  mnexto(mtmp)	/* Make monster mtmp next to you (if possible) */ 728. struct monst *mtmp; 729. {  730.  	coord mm; 731. 	enexto(&mm, u.ux, u.uy); 732. 	mtmp->mx = mm.x;  733. mtmp->my = mm.y; 734. pmon(mtmp); 735. }  736.   737.  ishuman(mtmp) register struct monst *mtmp; { 738. 	return(mtmp->data->mlet == '@'); 739. }  740.   741.  setmangry(mtmp) register struct monst *mtmp; { 742. 	if(!mtmp->mpeaceful) return; 743. 	if(mtmp->mtame) return; 744. 	mtmp->mpeaceful = 0; 745. 	if(ishuman(mtmp)) pline("%s gets angry!", Monnam(mtmp)); 746. }  747.   748.  /* not one hundred procent correct: now a snake may hide under an  749. invisible object */ 750. canseemon(mtmp) 751. register struct monst *mtmp; 752. {  753.  	return((!mtmp->minvis || See_invisible)  754.  		&& (!mtmp->mhide || !o_at(mtmp->mx,mtmp->my))  755.  		&& cansee(mtmp->mx, mtmp->my)); 756. }  757.   758.  disturb(mtmp)		/* awaken monsters while in the same room. 759. 			 * return a 1 if they have been woken. 760. 			 */  761.  register struct monst *mtmp; 762. {  763.  	/* wake up, or get out of here. */ 764.  	/* ettins are hard to surprise */ 765. 	/* Nymphs and Leprechauns do not easily wake up */ 766. 	if(cansee(mtmp->mx,mtmp->my) &&  767.  		(!Stealth || (mtmp->data->mlet == 'e' && rn2(10))) &&  768.  		(!index("NL",mtmp->data->mlet) || !rn2(50)) &&  769.  #ifdef RPH  770.  		(Aggravate_monster || index("8d1", mtmp->data->mlet) 771. #else 772. 		(Aggravate_monster || index("d1", mtmp->data->mlet)  773.  #endif  774.  			|| (!rn2(7) && !mtmp->mimic))) {  775.  		mtmp->msleep = 0;  776.  		return(1);  777.  	}  778.  	if(Hallucination) pmon(mtmp);  779.  	return(0);  780.  }  781.   782.  #ifdef HARD  783.  restrap(mtmp)		/* unwatched mimics and piercers may hide again,  784.  			 * if so, a 1 is returned.  785.  			 */  786.  register struct monst *mtmp;  787.  {  788.  	if(mtmp->data->mlet == 'M' && !mtmp->mimic && !mtmp->cham 789. 	   && !mtmp->mcan && !cansee(mtmp->mx, mtmp->my) 790. 	   && !rn2(3)) {  791.  		mtmp->mimic = 1;  792.  		mtmp->mappearance = (levl[mtmp->mx][mtmp->my].typ == DOOR) ? DOOR_SYM : GOLD_SYM;  793.  		return(1);  794.  	   }  795.   796.  	if(mtmp->data->mlet == 'p' && !mtmp->cham 797. 	   && !mtmp->mcan && !cansee(mtmp->mx, mtmp->my) 798. 	   && !rn2(3))  {  799.   800.  		if(levl[mtmp->mx][mtmp->my].typ == ROOM)  {  801.   802.  			maketrap(mtmp->mx, mtmp->my, PIERC);  803.  			mondead(mtmp);  804.  			return(1);  805.  		}  806.  	   }  807.  	return(0);  808.  }  809.  #endif