Source:NetHack 2.3e/mon.c

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