Source:Hack 1.0/hack.mon.c

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

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

1.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ 2.     3.    #include "hack.h"  4.    #include "hack.mfndpos.h"  5.    #define	SIZE(x)	(int)(sizeof(x) / sizeof(x[0])) 6.   #define	NULL	(char *) 0 7.   extern struct monst *makemon; 8.    9.    int warnlevel;		/* used by movemon and dochugw */ 10.  long lastwarntime; 11.  int lastwarnlev; 12.  char *warnings[] = { 13.  	"white", "pink", "red", "ruby", "purple", "black" 14.  };  15.    16.   movemon 17.  {  18.   	register struct monst *mtmp; 19.  	register int fr; 20.   21.   	warnlevel = 0; 22.   23.   	while(1) { 24.  		/* find a monster that we haven't treated yet */ 25.  		/* note that mtmp or mtmp->nmon might get killed 26.  		   while mtmp moves, so we cannot just walk down the 27.  		   chain (even new monsters might get created!) */ 28.  		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 29.  			if(mtmp->mlstmv < moves) goto next_mon; 30.  		/* treated all monsters */ 31.  		break; 32.   33.   	next_mon: 34.  		mtmp->mlstmv = moves; 35.  		if(mtmp->mblinded && !--mtmp->mblinded) 36.  			mtmp->mcansee = 1; 37.  		if(mtmp->mimic) continue; 38.  		if(mtmp->mspeed != MSLOW || !(moves%2)){ 39.  			/* continue if the monster died fighting */ 40.  			fr = -1; 41.  			if(Conflict && cansee(mtmp->mx,mtmp->my)  42.   				&& (fr = fightm(mtmp)) == 2) 43.  				continue; 44.  			if(fr<0 && dochugw(mtmp)) 45.  				continue; 46.  		}  47.   		if(mtmp->mspeed == MFAST && dochugw(mtmp)) 48.  			continue; 49.  	}  50.    51.   	warnlevel -= u.ulevel; 52.  	if(warnlevel >= SIZE(warnings)) 53.  		warnlevel = SIZE(warnings)-1; 54.  	if(warnlevel >= 0) 55.  	if(warnlevel > lastwarnlev || moves > lastwarntime + 5){ 56.  	    register char *rr; 57.  	    switch(Warning & (LEFT_RING | RIGHT_RING)){ 58.  	    case LEFT_RING: 59.  		rr = "Your left ring glows"; 60.  		break; 61.  	    case RIGHT_RING: 62.  		rr = "Your right ring glows"; 63.  		break; 64.  	    case LEFT_RING | RIGHT_RING: 65.  		rr = "Both your rings glow"; 66.  		break; 67.  	    default: 68.  		rr = "Your fingertips glow"; 69.  		break; 70.  	    }  71.   	    pline("%s %s!", rr, warnings[warnlevel]); 72.  	    lastwarntime = moves; 73.  	    lastwarnlev = warnlevel; 74.  	}  75.    76.   	dmonsfree;	/* remove all dead monsters */ 77.  }  78.    79.   justswld(mtmp,name) 80.  register struct monst *mtmp; 81.  char *name; 82.  {  83.    84.   	mtmp->mx = u.ux; 85.  	mtmp->my = u.uy; 86.  	u.ustuck = mtmp; 87.  	pmon(mtmp); 88.  	kludge("%s swallows you!",name); 89.  	more; 90.  	seeoff(1); 91.  	u.uswallow = 1; 92.  	swallowed; 93.  }  94.    95.   youswld(mtmp,dam,die,name) 96.  register struct monst *mtmp; 97.  register dam,die; 98.  char *name; 99.  {  100.  	if(mtmp != u.ustuck) return; 101. 	kludge("%s digests you!",name); 102. 	u.uhp -= dam; 103. 	if(u.uswldtim++ == die){ 104. 		pline("It totally digests you!"); 105. 		u.uhp = -1; 106. 	}  107.   if(u.uhp < 1) done_in_by(mtmp); 108. }  109.   110.  dochugw(mtmp) register struct monst *mtmp; { 111. register x = mtmp->mx; 112. register y = mtmp->my; 113. register d = dochug(mtmp); 114. register dd; 115. 	if(!d)		/* monster still alive */ 116. 	if(Warning) 117. 	if(!mtmp->mpeaceful) 118. 	if((dd = dist(mtmp->mx,mtmp->my)) < dist(x,y)) 119. 	if(dd < 100) 120. 	if(!cansee(mtmp->mx, mtmp->my) || (mtmp->minvis && !See_invisible)) 121. 	if(mtmp->data->mlevel > warnlevel) 122. 		warnlevel = mtmp->data->mlevel; 123. 	return(d); 124. }  125.   126.  /* returns 1 if monster died moving, 0 otherwise */ 127. dochug(mtmp) 128. register struct monst *mtmp; 129. {  130.  	register struct permonst *mdat; 131. 	register tmp; 132.  133.  	if(mtmp->cham && !rn2(6)) 134. 		(void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]); 135. 	mdat = mtmp->data; 136. 	if(mdat->mlevel < 0) 137. 		panic("bad monster %c (%d)",mdat->mlet,mdat->mlevel); 138. 	if((!(moves%20) || index("ViT",mdat->mlet)) &&  139.  	    mtmp->mhporig_hp) 140. 		mtmp->mhp++; /* regenerate monsters. */ 141.  	if(mtmp->mfroz) return(0); /* frozen monsters don't do anything. */ 142.  	if(mtmp->msleep) {/* wake up a monster, or get out of here. */ 143.  		if(cansee(mtmp->mx,mtmp->my) && !Stealth &&  144.  			(!index("NL",mdat->mlet) || !rn2(50)) &&  145.  			(Aggravate_monster || (!rn2(7) && !mtmp->mimic))) 146. 			mtmp->msleep = 0; 147. 		else return(0); 148. 	}  149.   150.  	/* not frozen or sleeping: wipe out texts written in the dust */ 151. 	wipe_engr_at(mtmp->mx, mtmp->my, 1); 152.  153.  	/* confused monsters get unconfused with small probability */ 154. 	if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0; 155.  156.  	/* some monsters teleport */ 157. 	if(mtmp->mflee && index("tNL", mdat->mlet) && !rn2(40)){ 158. 		rloc(mtmp); 159. 		return(0); 160. 	}  161.  	if(mdat->mmove < rnd(6)) return(0); 162. 	if((mtmp->mflee || 163. 		mtmp->mconf || 164. 		(index("BIuy", mdat->mlet) && !rn2(4)) || 165. 		(mdat->mlet == 'L' && !u.ugold && (mtmp->mgold || rn2(2))) || 166. 		dist(mtmp->mx,mtmp->my) > 2 || 167. 		(!mtmp->mcansee && !rn2(4)) || 168. 		mtmp->mpeaceful 169. 	   ) && (tmp = m_move(mtmp,0)) && mdat->mmove <= 12) 170. 		return(tmp == 2); 171. 	if(tmp == 2) return(1);	/* monster died moving */ 172.  173.  	if(!index("Ea", mdat->mlet) && dist(mtmp->mx, mtmp->my) < 3 &&  174.  	 !mtmp->mpeaceful && u.uhp > 0 &&  175.  	 !sengr_at("Elbereth", u.ux, u.uy) &&  176.  	 !sobj_at(SCR_SCARE_MONSTER, u.ux, u.uy)) { 177. 		if(mhitu(mtmp)) 178. 			return(1);	/* monster died (e.g. 'y' or 'F') */ 179. 	}  180.  	/* extra movement for fast monsters */ 181. 	if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp,1); 182. 	return(tmp == 2); 183. }  184.   185.  inrange(mtmp) 186. register struct monst *mtmp; 187. {  188.  	register schar tx,ty; 189.  190.  	/* spit fire only when both in a room or both in a corridor */ 191. 	if(inroom(u.ux,u.uy) != inroom(mtmp->mx,mtmp->my)) return; 192. 	tx = u.ux - mtmp->mx; 193. 	ty = u.uy - mtmp->my; 194. 	if((!tx && abs(ty) < 8) || (!ty && abs(tx) < 8)  195.  	    || (abs(tx) == abs(ty) && abs(tx) < 8)){ 196. 		/* spit fire in the direction of @ (not nec. hitting) */ 197. 		buzz(-1,mtmp->mx,mtmp->my,sgn(tx),sgn(ty)); 198. 		if(u.uhp < 1) done_in_by(mtmp); 199. 	}  200.  }  201.   202.  m_move(mtmp,after) 203. register struct monst *mtmp; 204. {  205.  	register struct monst *mtmp2; 206. 	register nx,ny,omx,omy,appr,nearer,cnt,i,j; 207. 	xchar gx,gy,nix,niy,chcnt; 208. 	schar chi; 209. 	boolean likegold, likegems, likeobjs; 210. 	schar mmoved = 0;	/* not strictly nec.: chi >= 0 will do */ 211. 	coord poss[9]; 212. 	int info[9]; 213.  214.  	if(mtmp->mtrapped) { 215. 		i = mintrap(mtmp); 216. 		if(i == 2) return(2);	/* he died */ 217. 		if(i == 1) return(0);	/* still in trap, so didnt move */ 218. 	}  219.  	if(mtmp->mhide && o_at(mtmp->mx,mtmp->my) && rn2(10)) 220. 		return(0);		/* do not leave hiding place */ 221.  222.  	/* my dog gets a special treatment */ 223. 	if(mtmp->mtame) { 224. 		return( dog_move(mtmp, after) ); 225. 	}  226.   227.  	/* likewise for shopkeeper */ 228. 	if(mtmp->isshk) { 229. 		mmoved = shk_move; 230. 		goto postmov; 231. 	}  232.   233.  	/* and for the guard */ 234. 	if(mtmp->isgd) { 235. 		mmoved = gd_move; 236. 		goto postmov; 237. 	}  238.   239.  	if(mtmp->data->mlet == 't' && !rn2(5)) { 240. 		if(rn2(2)) 241. 			mnexto(mtmp); 242. 		else 243. 			rloc(mtmp); 244. 		mmoved = 1; 245. 		goto postmov; 246. 	}  247.  	if(mtmp->data->mlet == 'D' && !mtmp->mcan) 248. 		inrange(mtmp); 249. 	if(!Blind && !Confusion && mtmp->data->mlet == 'U' && !mtmp->mcan  250.  		&& cansee(mtmp->mx,mtmp->my) && rn2(5)) { 251. 		pline("%s's gaze has confused you!", Monnam(mtmp)); 252. 		if(rn2(5)) mtmp->mcan = 1; 253. 		Confusion = d(3,4);		/* timeout */ 254. 	}  255.  	if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1); 256. 	appr = 1; 257. 	if(mtmp->mflee) appr = -1; 258. 	if(mtmp->mconf || Invis ||  !mtmp->mcansee ||  259.  		(index("BIy",mtmp->data->mlet) && !rn2(3))) 260. 		appr = 0; 261. 	omx = mtmp->mx; 262. 	omy = mtmp->my; 263. 	gx = u.ux; 264. 	gy = u.uy; 265. 	if(mtmp->data->mlet == 'L' && appr == 1 && mtmp->mgold > u.ugold) 266. 		appr = -1; 267. #ifdef TRACK 268. 	/* random criterion for 'smell' 269. 	   should use mtmp->msmell 270. 	 */  271.  	if('a' <= mtmp->data->mlet && mtmp->data->mlet <= 'z') { 272. 	extern coord *gettrack; 273. 	register coord *cp; 274. 	schar mroom; 275. 		mroom = inroom(omx,omy); 276. 		if(mroom < 0 || mroom != inroom(u.ux,u.uy)){ 277. 		    cp = gettrack(omx,omy); 278. 		    if(cp){ 279. 			gx = cp->x; 280. 			gy = cp->y; 281. 		    }  282.  		}  283.  	}  284.  #endif TRACK 285. 	/* look for gold or jewels nearby */ 286. 	likegold = (index("LOD", mtmp->data->mlet) != NULL); 287. 	likegems = (index("ODu", mtmp->data->mlet) != NULL); 288. 	likeobjs = mtmp->mhide; 289. #define	SRCHRADIUS	25 290. 	{ xchar mind = SRCHRADIUS;		/* not too far away */ 291. 	  register int dd; 292. 	  if(likegold){ 293. 		register struct gen *gold; 294. 		for(gold = fgold; gold; gold = gold->ngen) 295. 		  if((dd = DIST(omx,omy,gold->gx,gold->gy)) < mind){ 296. 		    mind = dd; 297. 		    gx = gold->gx; 298. 		    gy = gold->gy; 299. 		}  300.  	  }  301.  	  if(likegems || likeobjs){ 302. 		register struct obj *otmp; 303. 		for(otmp = fobj; otmp; otmp = otmp->nobj) 304. 		if(likeobjs || otmp->olet == GEM_SYM) 305. 		if(mtmp->data->mlet != 'u' ||  306.  			objects[otmp->otyp].g_val != 0) 307. 		if((dd = DIST(omx,omy,otmp->ox,otmp->oy)) < mind){ 308. 		    mind = dd; 309. 		    gx = otmp->ox; 310. 		    gy = otmp->oy; 311. 		}  312.  	  }  313.  	  if(mind < SRCHRADIUS && appr == -1) { 314. 		if(dist(omx,omy) < 10) { 315. 		    gx = u.ux; 316. 		    gy = u.uy; 317. 		} else 318.    appr = 1; 319. 	  }  320.  	}  321.  	nix = omx; 322. 	niy = omy; 323. 	cnt = mfndpos(mtmp,poss,info,  324.  		mtmp->data->mlet == 'u' ? NOTONL :  325.  		index(" VWZ", mtmp->data->mlet) ? NOGARLIC : ALLOW_TRAPS); 326. 		/* ALLOW_ROCK for some monsters ? */ 327.  	chcnt = 0; 328. 	chi = -1; 329. 	for(i=0; imtrack[j].x && ny == mtmp->mtrack[j].y)  334. if(rn2(4*(cnt-j))) goto nxti; 335. #ifdef STUPID 336. 		/* some stupid compilers think that this is too complicated */ 337. 		{ int d1 = DIST(nx,ny,gx,gy); 338. 		  int d2 = DIST(nix,niy,gx,gy); 339. 		  nearer = (d1 < d2); 340. 		}  341.  #else 342. 		nearer = (DIST(nx,ny,gx,gy) < DIST(nix,niy,gx,gy)); 343. #endif STUPID 344. 		if((appr == 1 && nearer) || (appr == -1 && !nearer) ||  345.  			!mmoved ||  346.  			(!appr && !rn2(++chcnt))){ 347. 			nix = nx; 348. 			niy = ny; 349. 			chi = i;  350. mmoved = 1; 351. 		}  352.   nxti:	; 353. 	}  354.  	if(mmoved){ 355. 		if(info[chi] & ALLOW_M){ 356. 			mtmp2 = m_at(nix,niy); 357. 			if(hitmm(mtmp,mtmp2) == 1 && rn2(4) &&  358.  			  hitmm(mtmp2,mtmp) == 2) return(2); 359. 			return(0); 360. 		}  361.  		if(info[chi] & ALLOW_U){ 362. 		  (void) hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd)+1); 363. 		  return(0); 364. 		}  365.  		mtmp->mx = nix; 366. 		mtmp->my = niy; 367. 		for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1]; 368. 		mtmp->mtrack[0].x = omx; 369. 		mtmp->mtrack[0].y = omy; 370. #ifndef NOWORM 371. 		if(mtmp->wormno) worm_move(mtmp); 372. #endif NOWORM 373. 	} else { 374. 		if(mtmp->data->mlet == 'u' && rn2(2)){ 375. 			rloc(mtmp); 376. 			return(0); 377. 		}  378.  #ifndef NOWORM 379. 		if(mtmp->wormno) worm_nomove(mtmp); 380. #endif NOWORM 381. 	}  382.  postmov: 383. 	if(mmoved == 1) { 384. 		if(mintrap(mtmp) == 2)	/* he died */ 385. 			return(2); 386. 		if(likegold) mpickgold(mtmp); 387. 		if(likegems) mpickgems(mtmp); 388. 		if(mtmp->mhide) mtmp->mundetected = 1; 389. 	}  390.  	pmon(mtmp); 391. 	return(mmoved); 392. }  393.   394.  mpickgold(mtmp) register struct monst *mtmp; { 395. register struct gen *gold; 396. 	while(gold = g_at(mtmp->mx, mtmp->my, fgold)){ 397. 		mtmp->mgold += gold->gflag; 398. 		freegold(gold); 399. 		if(levl[mtmp->mx][mtmp->my].scrsym == '$') 400. 			newsym(mtmp->mx, mtmp->my); 401. 	}  402.  }  403.   404.  mpickgems(mtmp) register struct monst *mtmp; { 405. register struct obj *otmp; 406. 	for(otmp = fobj; otmp; otmp = otmp->nobj) 407. 	if(otmp->olet == GEM_SYM) 408. 	if(otmp->ox == mtmp->mx && otmp->oy == mtmp->my) 409. 	if(mtmp->data->mlet != 'u' || objects[otmp->otyp].g_val != 0){ 410. 		freeobj(otmp); 411. 		mpickobj(mtmp, otmp); 412. 		if(levl[mtmp->mx][mtmp->my].scrsym == GEM_SYM) 413. 			newsym(mtmp->mx, mtmp->my);	/* %% */ 414. 		return;	/* pick only one object */ 415. 	}  416.  }  417.   418.  /* return number of acceptable neighbour positions */ 419. mfndpos(mon,poss,info,flag) 420. register struct monst *mon; coord poss[9]; int info[9], flag; { 421. register int x,y,nx,ny,cnt = 0,tmp; 422. register struct monst *mtmp; 423. 	x = mon->mx; 424. 	y = mon->my; 425. 	if(mon->mconf) { 426. 		flag |= ALLOW_ALL; 427. 		flag &= ~NOTONL; 428. 	}  429.  	for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) 430. 	if(nx != x || ny != y) if(isok(nx,ny)) 431. 	if((tmp = levl[nx][ny].typ) >= DOOR) 432. 	if(!(nx != x && ny != y && 433. 		(levl[x][y].typ == DOOR || tmp == DOOR))){ 434. 		info[cnt] = 0; 435. 		if(nx == u.ux && ny == u.uy){ 436. 			if(!(flag & ALLOW_U)) continue; 437. 			info[cnt] = ALLOW_U; 438. 		} else if(mtmp = m_at(nx,ny)){ 439. 			if(!(flag & ALLOW_M)) continue; 440. 			info[cnt] = ALLOW_M; 441. 			if(mtmp->mtame){ 442. 				if(!(flag & ALLOW_TM)) continue; 443. 				info[cnt] |= ALLOW_TM; 444. 			}  445.  		}  446.  		if(sobj_at(CLOVE_OF_GARLIC, nx, ny)) { 447. 			if(flag & NOGARLIC) continue; 448. 			info[cnt] |= NOGARLIC; 449. 		}  450.  		if(sobj_at(SCR_SCARE_MONSTER, nx, ny) ||  451.  		   (!mon->mpeaceful && sengr_at("Elbereth", nx, ny))) { 452. 			if(!(flag & ALLOW_SSM)) continue; 453. 			info[cnt] |= ALLOW_SSM; 454. 		}  455.  		if(sobj_at(ENORMOUS_ROCK, nx, ny)) { 456. 			if(!(flag & ALLOW_ROCK)) continue; 457. 			info[cnt] |= ALLOW_ROCK; 458. 		}  459.  		if(!Invis && online(nx,ny)){ 460. 			if(flag & NOTONL) continue; 461. 			info[cnt] |= NOTONL; 462. 		}  463.  		/* we cannot avoid traps of an unknown kind */ 464. 		{ register struct gen *gtmp = g_at(nx, ny, ftrap); 465. 		  register int tt; 466. 			if(gtmp) { 467. 				tt = 1 << (gtmp->gflag & ~SEEN); 468. 				if(mon->mtrapseen & tt){ 469. 					if(!(flag & tt)) continue; 470. 					info[cnt] |= tt; 471. 				}  472.  			}  473.  		}  474.  		poss[cnt].x = nx; 475. 		poss[cnt].y = ny; 476. 		cnt++; 477. 	}  478.  	return(cnt); 479. }  480.   481.  dist(x,y) int x,y; { 482. 	return((x-u.ux)*(x-u.ux) + (y-u.uy)*(y-u.uy)); 483. }  484.   485.  poisoned(string, pname) 486. register char *string, *pname; 487. {  488.  	if(Blind) pline("It was poisoned."); 489. 	else pline("The %s was poisoned!",string); 490. 	if(Poison_resistance) { 491. 		pline("The poison doesn't seem to affect you."); 492. 		return; 493. 	}  494.  	switch(rnd(6)) { 495. 	case 1: 496. 		u.uhp = -1; 497. 		break; 498. 	case 2: 499. 	case 3: 500. 	case 4: 501. 		losestr(rn1(3,3)); 502. 		break; 503. 	case 5: 504. 	case 6: 505. 		losehp(rn1(10,6), pname); 506. 		return; 507. 	}  508.  	if(u.uhp < 1) killer = pname; 509. }  510.   511.  mondead(mtmp) 512. register struct monst *mtmp; 513. {  514.  	relobj(mtmp,1); 515. 	unpmon(mtmp); 516. 	relmon(mtmp); 517. 	if(u.ustuck == mtmp) { 518. 		u.ustuck = 0; 519. 		if(u.uswallow) { 520. 			u.uswallow = 0; 521. 			setsee; 522. 			docrt; 523. 		}  524.  	}  525.  	if(mtmp->isshk) shkdead; 526. 	if(mtmp->isgd) gddead; 527. #ifndef NOWORM 528. 	if(mtmp->wormno) wormdead(mtmp); 529. #endif NOWORM 530. 	monfree(mtmp); 531. }  532.   533.  /* called when monster is moved to larger structure */ 534. replmon(mtmp,mtmp2) 535. register struct monst *mtmp, *mtmp2; 536. {  537.  	relmon(mtmp); 538. 	monfree(mtmp); 539. 	mtmp2->nmon = fmon; 540. 	fmon = mtmp2; 541. }  542.   543.  relmon(mon) 544. register struct monst *mon; 545. {  546.  	register struct monst *mtmp; 547.  548.  	if(mon == fmon) fmon = fmon->nmon; 549. 	else { 550. 		for(mtmp = fmon; mtmp->nmon != mon; mtmp = mtmp->nmon) ; 551. 		mtmp->nmon = mon->nmon; 552. 	}  553.  }  554.   555.  /* we do not free monsters immediately, in order to have their name 556.    available shortly after their demise */ 557. struct monst *fdmon;	/* chain of dead monsters, need not to be saved */ 558.  559.  monfree(mtmp) register struct monst *mtmp; { 560. 	mtmp->nmon = fdmon; 561. 	fdmon = mtmp; 562. }  563.   564.  dmonsfree{ 565. register struct monst *mtmp; 566. 	while(mtmp = fdmon){ 567. 		fdmon = mtmp->nmon; 568. 		free((char *) mtmp); 569. 	}  570.  }  571.   572.  killed(mtmp) struct monst *mtmp; { 573. #ifdef lint 574. #define	NEW_SCORING 575. #endif lint 576. register int tmp,tmp2,nk,x,y; 577. register struct permonst *mdat = mtmp->data; 578. 	if(mtmp->cham) mdat = PM_CHAM; 579. 	if(Blind) pline("You destroy it!"); 580. 	else { 581. 		pline("You destroy %s!",  582.  			mtmp->mtame ? amonnam(mtmp, "poor") : monnam(mtmp)); 583. 	}  584.  	if(u.umconf) { 585. 		if(!Blind) pline("Your hands stop glowing blue."); 586. 		u.umconf = 0; 587. 	}  588.   589.  	/* count killed monsters */ 590. #define	MAXMONNO	100 591. 	nk = 1;		      /* in case we cannot find it in mons */ 592. 	tmp = mdat - mons;    /* index in mons array (if not 'd', '@', ...) */ 593. 	if(tmp >= 0 && tmp < CMNUM+2) { 594. 	    extern char fut_geno[]; 595. 	    u.nr_killed[tmp]++; 596. 	    if((nk = u.nr_killed[tmp]) > MAXMONNO &&  597.  		!index(fut_geno, mdat->mlet)) 598. 		    charcat(fut_geno,  mdat->mlet); 599. 	}  600.   601.  	/* punish bad behaviour */ 602. 	if(mdat->mlet == '@') Telepat = 0, u.uluck -= 2; 603. 	if(mtmp->mpeaceful || mtmp->mtame) u.uluck--; 604. 	if(mdat->mlet == 'u') u.uluck -= 5; 605.  606.  	/* give experience points */ 607. 	tmp = 1 + mdat->mlevel * mdat->mlevel; 608. 	if(mdat->ac < 3) tmp += 2*(7 - mdat->ac); 609. 	if(index("AcsSDXaeRTVWU&In:P", mdat->mlet)) 610. 		tmp += 2*mdat->mlevel; 611. 	if(index("DeV&P",mdat->mlet)) tmp += (7*mdat->mlevel); 612. 	if(mdat->mlevel > 6) tmp += 50; 613.  614.  #ifdef NEW_SCORING 615. 	/* --- recent addition: make nr of points decrease 616. 		   when this is not the first of this kind */ 617. 	{ int ul = u.ulevel; 618. 	  int ml = mdat->mlevel; 619.  620.  	if(ul < 14)    /* points are given based on present and future level */ 621. 	    for(tmp2 = 0; !tmp2 || ul + tmp2 <= ml; tmp2++) 622. 		if(u.uexp + 1 + (tmp + ((tmp2 <= 0) ? 0 : 4<<(tmp2-1)))/nk  623.  		    >= 10*pow((unsigned)(ul-1))) 624. 			if(++ul == 14) break; 625.  626.  	tmp2 = ml - ul -1; 627. 	tmp = (tmp + ((tmp2 < 0) ? 0 : 4<= 10*pow(u.ulevel-1)){ 638. 		pline("Welcome to level %d.", ++u.ulevel); 639. 		tmp = rnd(10); 640. 		if(tmp < 3) tmp = rnd(10); 641. 		u.uhpmax += tmp; 642. 		u.uhp += tmp; 643. 		flags.botl = 1; 644. 	}  645.   646.  	/* dispose of monster and make cadaver */ 647. 	x = mtmp->mx;	y = mtmp->my; 648. 	mondead(mtmp); 649. 	tmp = mdat->mlet; 650. 	if(tmp == 'm') { /* he killed a minotaur, give him a wand of digging */ 651. 			/* note: the dead minotaur will be on top of it! */ 652.  		mksobj_at(WAND_SYM, WAN_DIGGING, x, y); 653. 		/* if(cansee(x,y)) atl(x,y,fobj->olet); */ 654. 		stackobj(fobj); 655. 	} else 656. #ifndef NOWORM 657. 	if(tmp == 'w') { 658. 		mksobj_at(WEAPON_SYM, WORM_TOOTH, x, y); 659. 		stackobj(fobj); 660. 	} else 661. #endif	NOWORM 662. 	if(!letter(tmp) || !rn2(3)) tmp = 0; 663.  664.  	if(levl[x][y].typ >= DOOR)	/* might be mimic in wall */ 665. 	    if(x != u.ux || y != u.uy) /* might be here after swallowed */ 666. 		if(index("NTVm&",mdat->mlet) || rn2(5)) { 667. 		mkobj_at(tmp,x,y); 668. 		if(cansee(x,y)) atl(x,y,fobj->olet); 669. 		stackobj(fobj); 670. 	}  671.  }  672.   673.  kludge(str,arg) 674. register char *str,*arg; 675. {  676.  	if(Blind) { 677. 		if(*str == '%') pline(str,"It"); 678. 		else pline(str,"it"); 679. 	} else pline(str,arg); 680. }  681.   682.  rescham	/* force all chameleons to become normal */ 683. {  684.  	register struct monst *mtmp; 685.  686.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 687. 		if(mtmp->cham) { 688. 			mtmp->cham = 0; 689. 			(void) newcham(mtmp,PM_CHAM); 690. 		}  691.  }  692.   693.  newcham(mtmp,mdat)	/* make a chameleon look like a new monster */ 694. 			/* returns 1 if the monster actually changed */ 695. register struct monst *mtmp; 696. register struct permonst *mdat; 697. {  698.  	register mhp, hpn, hpd; 699.  700.  	if(mdat == mtmp->data) return(0);	/* still the same monster */ 701. #ifndef NOWORM 702. 	if(mtmp->wormno) wormdead(mtmp);	/* throw tail away */ 703. #endif NOWORM 704. 	hpn = mtmp->mhp; 705. 	hpd = (mtmp->data->mlevel)*8; 706. 	if(!hpd) hpd = 4; 707. 	mtmp->data = mdat; 708. 	mhp = (mdat->mlevel)*8; 709. 	/* new hp: same fraction of max as before */ 710. 	mtmp->mhp = 2 + (hpn*mhp)/hpd; 711. 	hpn = mtmp->orig_hp; 712. 	mtmp->orig_hp = 2 + (hpn*mhp)/hpd; 713. 	mtmp->minvis = (mdat->mlet == 'I') ? 1 : 0; 714.  #ifndef NOWORM 715. 	if(mdat->mlet == 'w' && getwn(mtmp)) initworm(mtmp); 716. #endif NOWORM 717. 	unpmon(mtmp);	/* necessary for 'I' and to force pmon */ 718. 	pmon(mtmp); 719. 	return(1); 720. }  721.   722.  mnexto(mtmp)	/* Make monster mtmp next to you (if possible) */ 723. struct monst *mtmp; 724. {  725.  	extern coord enexto; 726. 	coord mm; 727. 	mm = enexto(u.ux, u.uy); 728. 	mtmp->mx = mm.x;  729. mtmp->my = mm.y; 730. pmon(mtmp); 731. }  732.   733.  rloc(mtmp) 734. struct monst *mtmp; 735. {  736.  	register tx,ty; 737. 	register char ch = mtmp->data->mlet; 738.  739.  #ifndef NOWORM 740. 	if(ch == 'w' && mtmp->mx) return;	/* do not relocate worms */ 741. #endif NOWORM 742. 	do { 743. 		tx = rn1(COLNO-3,2); 744. 		ty = rn2(ROWNO); 745. 	} while(!goodpos(tx,ty)); 746. 	mtmp->mx = tx; 747. 	mtmp->my = ty; 748. 	if(u.ustuck == mtmp){ 749. 		if(u.uswallow) { 750. 			u.ux = tx; 751. 			u.uy = ty; 752. 			docrt; 753. 		} else	u.ustuck = 0; 754. 	}  755.  	pmon(mtmp); 756. }  757.   758.  ishuman(mtmp) register struct monst *mtmp; { 759. 	return(mtmp->data->mlet == '@'); 760. }  761.   762.  setmangry(mtmp) register struct monst *mtmp; { 763. 	if(!mtmp->mpeaceful) return; 764. 	if(mtmp->mtame) return; 765. 	mtmp->mpeaceful = 0; 766. 	if(ishuman(mtmp)) pline("%s gets angry!", Monnam(mtmp)); 767. }