Source:NetHack 3.0.0/mon.c

Below is the full text to mon.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/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	3.0	88/10/31 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.    #ifdef NAMED_ITEMS 8.   #  include "artifact.h"  9.    #endif 10.   11.   #ifdef HARD 12.  static boolean restrap; 13.  #endif 14.   15.   long lastwarntime; 16.  int lastwarnlev; 17.  static const char *warnings[] = { 18.  	"white", "pink", "red", "ruby", "purple", "black" }; 19.  struct monst *fdmon;	/* chain of dead monsters, need not to be saved */ 20.   21.   /* Creates a monster corpse, a "special" corpse, or nothing if it doesn't  22. * leave corpses. Monsters which leave "special" corpses should have 23.   * G_NOCORPSE set in order to prevent wishing for one, finding tins of one, 24.   * etc....  25. */ 26.   static struct obj * 27.  make_corpse(mtmp) 28.  register struct monst *mtmp; 29.  {  30.   	register struct permonst *mdat = mtmp->data; 31.  #ifdef GOLEMS 32.  	int pieces; 33.  #endif 34.  	struct obj *obj = 0; 35.  	int x = mtmp->mx, y = mtmp->my; 36.   37.   	switch(monsndx(mdat)) { 38.  	    case PM_KOBOLD_MUMMY: 39.  		obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 40.  	    case PM_KOBOLD_ZOMBIE: 41.  		obj = mksobj_at(CORPSE, x, y); 42.  		obj->corpsenm = PM_KOBOLD; 43.  		break; 44.  	    case PM_GNOME_MUMMY: 45.  		obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 46.  	    case PM_GNOME_ZOMBIE: 47.  		obj = mksobj_at(CORPSE, x, y); 48.  		obj->corpsenm = PM_GNOME; 49.  		break; 50.  	    case PM_ORC_MUMMY: 51.  		obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 52.  	    case PM_ORC_ZOMBIE: 53.  		obj = mksobj_at(CORPSE, x, y); 54.  		obj->corpsenm = PM_ORC; 55.  		break; 56.  	    case PM_ELF_MUMMY: 57.  		obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 58.  	    case PM_ELF_ZOMBIE: 59.  		obj = mksobj_at(CORPSE, x, y); 60.  		obj->corpsenm = PM_ELF; 61.  		break; 62.  	    case PM_HUMAN_MUMMY: 63.  		obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 64.  	    case PM_HUMAN_ZOMBIE: 65.  		obj = mksobj_at(CORPSE, x, y); 66.  		obj->corpsenm = PM_HUMAN; 67.  		break; 68.  	    case PM_GIANT_MUMMY: 69.  		obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 70.  	    case PM_GIANT_ZOMBIE: 71.  		obj = mksobj_at(CORPSE, x, y); 72.  		obj->corpsenm = PM_GIANT; 73.  		break; 74.  	    case PM_ETTIN_MUMMY: 75.  		obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 76.  	    case PM_ETTIN_ZOMBIE: 77.  		obj = mksobj_at(CORPSE, x, y); 78.  		obj->corpsenm = PM_ETTIN; 79.  		break; 80.  #ifdef GOLEMS 81.  	    case PM_IRON_GOLEM: 82.  		pieces = d(2,6); 83.  		while (pieces--) 84.  			obj = mksobj_at(IRON_CHAIN, x, y); 85.  		break; 86.  	    case PM_CLAY_GOLEM: 87.  		obj = mksobj_at(ROCK, x, y); 88.  		obj->quan = rn2(20) + 100; 89.  		obj->owt = weight(obj); 90.  		break; 91.  	    case PM_STONE_GOLEM: 92.  		obj = mkstatue(mdat, x, y); 93.  		break; 94.  	    case PM_WOOD_GOLEM: 95.  		pieces = d(2,4); 96.  		while(pieces--) 97.  			obj = mksobj_at(QUARTERSTAFF, x, y); 98.  		break; 99.  	    case PM_LEATHER_GOLEM: 100. 		pieces = d(2,4); 101. 		while(pieces--) 102. 			obj = mksobj_at(LEATHER_ARMOR, x, y); 103. 		break; 104. #endif 105. 	    default: 106. 		if (mdat->geno & G_NOCORPSE) 107. 			return (struct obj *)0; 108. 		else obj = mkcorpse_at(mdat, x, y); 109. 		break; 110. 	}  111.  	/* All special cases should precede the G_NOCORPSE check */ 112.  113.  	/* Note: oname cannot be used generically for non-inventory objects 114. 	 * unless you fix the link from the previous object in the chain. 115. 	 * (Here we know it's the first one, so there was no link.) 116. 	 */  117.  	if (mtmp->mnamelth) { 118. 		obj = oname(obj, NAME(mtmp), 0); 119. 		fobj = obj; 120. 	}  121.  	stackobj(fobj); 122. 	newsym(x, y); 123. 	return obj; 124. }  125.   126.   127.  static void 128. dmonsfree{ 129. register struct monst *mtmp; 130. 	while(mtmp = fdmon){ 131. 		fdmon = mtmp->nmon; 132. 		free((genericptr_t) mtmp); 133. 	}  134.  }  135.   136.  void 137. movemon 138. {  139.  	register struct monst *mtmp; 140. 	register int fr; 141.  142.  	warnlevel = 0; 143.  144.  	while(1) { 145. 		/*  Find a monster that we have not treated yet. 146. 		 *  Note that mtmp or mtmp->nmon might get killed 147. 		 *  while mtmp moves, so we cannot just walk down the 148. 		 *  chain (even new monsters might get created!) 149. 		 */  150.  		/* Do tame monsters first. Necessary so that when the tame 151. 		 * monster attacks something, the something gets a chance to  152. * attack the tame monster back (which it's permitted to do 153.  		 * only if it hasn't made its move yet). 154. 		 */  155.  		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 156. 			if(mtmp->mlstmv < moves && mtmp->mtame) goto next_mon; 157. 		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 158. 			if(mtmp->mlstmv < moves && !mtmp->mtame) goto next_mon; 159. 		/* treated all monsters */ 160. 		break; 161.  162.  	next_mon: 163. 		mtmp->mlstmv = moves; 164.  165.  		/* most monsters drown in pools */ 166. 		{ boolean inpool,infountain,iseel,isgremlin; 167.  168.  		  inpool = is_pool(mtmp->mx,mtmp->my); 169. 		  iseel = mtmp->data->mlet == S_EEL; 170. 		  isgremlin = mtmp->data->mlet == S_GREMLIN; 171. 		  infountain = IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ); 172. 		/* Gremlin multiplying won't go on forever since the hit points 173. 		 * keep going down, and when it gets to 1 hit point the clone 174. 		 * function will fail. 175. 		 */  176.  		  if((inpool || infountain) && isgremlin && rn2(3)) { 177. 			struct monst *mtmp2 = clone_mon(mtmp); 178.  179.  			if (mtmp2) { 180. 			    mtmp2->mhpmax = (mtmp->mhpmax /= 2); 181. 			    if(cansee(mtmp->mx,mtmp->my)) 182. 				pline("%s multiplies.", Monnam(mtmp)); 183. 			}  184.  #ifdef FOUNTAINS 185. 			if (infountain) dryup; 186. #endif 187. 		  } else 188. 		  if(inpool && !is_flyer(mtmp->data) && !is_swimmer(mtmp->data)) { 189. 			if(cansee(mtmp->mx,mtmp->my)) 190. 			    pline("%s drowns.", Monnam(mtmp)); 191. 			mondead(mtmp); 192. 			continue; 193. 		  } else 194. 		/* but eels have a difficult time outside */ 195. 		  if(iseel && !inpool) { 196. 			if(mtmp->mhp > 1) mtmp->mhp--; 197. 			mtmp->mflee = 1; 198. 			mtmp->mfleetim += 2; 199. 		  }  200.  		}  201.  		if(mtmp->mblinded && !--mtmp->mblinded) 202. 			mtmp->mcansee = 1; 203. 		if(mtmp->mfleetim && !--mtmp->mfleetim) 204. 			mtmp->mflee = 0; 205. #ifdef HARD 206. 		/* unwatched mimics and piercers may hide again  [MRS] */ 207. 		if(is_hider(mtmp->data) && restrap(mtmp))   continue; 208. #endif 209. 		if(mtmp->mimic) continue; 210. 		if(mtmp->mspeed != MSLOW || !(moves%2)){ 211. 			/* continue if the monster died fighting */ 212. 			fr = -1; 213. /* TODO:	Handle the case of the agressor dying? */ 214.  			if(Conflict && cansee(mtmp->mx,mtmp->my)  215.  				&& !mtmp->iswiz  216.  				&& (fr = fightm(mtmp)) == 2) 217. 				continue; 218.   			if(fr<0 && dochugw(mtmp)) 219. 				continue; 220. 		}  221.  		if(mtmp->mspeed == MFAST && dochugw(mtmp)) 222. 			continue; 223. 	}  224.  #ifdef NAMED_ITEMS 225. 	if (warnlevel == 100) { 226. 		Your("%s %s!", aobjnam(uwep, "glow"),  227.  			Hallucination ? hcolor : light_blue); 228. 		warnlevel = 0; 229. 	}  230.  #endif 231. 	warnlevel -= u.ulevel; 232. 	if(warnlevel >= SIZE(warnings)) 233. 		warnlevel = SIZE(warnings)-1; 234. 	if(!Blind && warnlevel >= 0) 235. 	if(warnlevel > lastwarnlev || moves > lastwarntime + 5){ 236. 	    register char *rr; 237. 	  238.  	    switch((int) (Warning & (LEFT_RING | RIGHT_RING))){ 239. 	    case LEFT_RING: 240. 		rr = "Your left ring glows"; 241. 		break; 242. 	    case RIGHT_RING: 243. 		rr = "Your right ring glows"; 244. 		break; 245. 	    case LEFT_RING | RIGHT_RING: 246. 		rr = "Both your rings glow"; 247. 		break; 248. 	    default: 249. 		{ char buf[33]; 250. 		Sprintf(buf, "Your %s glow", makeplural(body_part(FINGERTIP))); 251. 		rr = buf; 252. 		}  253.  		break; 254. 	    }  255.  	    pline("%s %s!", rr, Hallucination ? hcolor : warnings[warnlevel]); 256. 	    lastwarntime = moves; 257. 	    lastwarnlev = warnlevel; 258. 	}  259.   260.  	dmonsfree;	/* remove all dead monsters */ 261. }  262.   263.  void 264. meatgold(mtmp) 265. 	register struct monst *mtmp; 266. {  267.  	register struct gold *gold; 268. 	register struct obj *otmp; 269.  270.  	/* Eats gold if it is there */ 271. 	while(gold = g_at(mtmp->mx, mtmp->my)){ 272. 		if (cansee(mtmp->mx, mtmp->my) && flags.verbose) 273. 			pline("%s eats some gold!", Monnam(mtmp)); 274. 		mtmp->meating = (int)((gold->amount + 500L)/1000L); 275. 		freegold(gold); 276. 		/* Left behind a pile? */ 277.  		if(rnd(25) < 3) (void) mksobj_at(ROCK, mtmp->mx, mtmp->my); 278. 		newsym(mtmp->mx, mtmp->my); 279. 	}  280.  	/* Eats topmost metal object if it is there */ 281. 	for (otmp = fobj; otmp; otmp = otmp->nobj) 282. 	    if (otmp->ox == mtmp->mx && otmp->oy == mtmp->my &&  283.  		objects[otmp->otyp].oc_material == METAL) { 284. 		    if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 285. 			pline("%s eats %s!", Monnam(mtmp),  286.  				distant_name(otmp,doname)); 287. 		    else if (flags.soundok && flags.verbose) 288. 			You("hear a crunching sound."); 289. 		    mtmp->meating = otmp->owt/2 - 1; 290. 		    /* Heal up to the object's weight in hp */ 291. 		    if (mtmp->mhp < mtmp->mhpmax) { 292. 			mtmp->mhp += objects[otmp->otyp].oc_weight; 293. 			if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; 294. 		    }  295.  		    freeobj(otmp); 296. 		    /* Left behind a pile? */ 297.  		    if(rnd(25) < 3) (void) mksobj_at(ROCK, mtmp->mx, mtmp->my); 298. 		    newsym(mtmp->mx, mtmp->my); 299. 		    break; 300. 	    }  301.  	set_omask(mtmp->mx, mtmp->my); 302. }  303.   304.  void 305. meatobj(mtmp)		/* for gelatinous cubes */ 306. 	register struct monst *mtmp; 307. {  308.  	register struct obj *otmp, *otmp2; 309.  310.  	/* Eats organic, glass, or wood objects if there */ 311. 	/* Engulfs anything else, metal and rock */ 312. 	for (otmp = fobj; otmp; otmp = otmp2) { 313. 	    otmp2 = otmp->nobj; 314. 	    if (otmp->ox == mtmp->mx && otmp->oy == mtmp->my) { 315. 		if(!objects[otmp->otyp].oc_material <= WOOD) { 316. 		    if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 317. 			pline("%s eats %s!", Monnam(mtmp),  318.  				distant_name(otmp, doname)); 319. 		    else if (flags.soundok && flags.verbose) 320. 			You("hear a slurping sound."); 321.                     /* Heal up to the object's weight in hp */ 322. 		    if (mtmp->mhp < mtmp->mhpmax) { 323. 			mtmp->mhp += objects[otmp->otyp].oc_weight; 324. 			if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; 325. 		    }  326.  		    delobj(otmp);		/* munch */ 327. 		} else if (otmp->olet != ROCK_SYM && otmp->olet != BALL_SYM) { 328. 		    if (cansee(mtmp->mx, mtmp->my) && flags.verbose) 329. 			pline("%s engulfs %s.", Monnam(mtmp),  330.  				distant_name(otmp,doname)); 331. 		    freeobj(otmp); 332. 		    mpickobj(mtmp, otmp);	/* slurp */ 333. 		}  334.  	    }  335.  	    /* Engulf & devour is instant, so don't set meating */ 336. 	    newsym(mtmp->mx, mtmp->my); 337. 	}  338.  	set_omask(mtmp->mx, mtmp->my); 339. }  340.   341.  void 342. mpickgold(mtmp) 343. 	register struct monst *mtmp; 344. {  345.  	register struct gold *gold; 346.  347.  	while(gold = g_at(mtmp->mx, mtmp->my)){ 348. 		mtmp->mgold += gold->amount; 349. 		if (cansee(mtmp->mx, mtmp->my) && flags.verbose) 350. 			pline("%s picks up some gold.", Monnam(mtmp)); 351. 		freegold(gold); 352. 		if(levl[mtmp->mx][mtmp->my].scrsym == GOLD_SYM) 353. 			newsym(mtmp->mx, mtmp->my); 354. 	}  355.  	set_omask(mtmp->mx, mtmp->my); 356. }  357.   358.  /* Now includes giants which pick up enormous rocks. KAA */ 359. void 360. mpickgems(mtmp) 361. 	register struct monst *mtmp; 362. {  363.  	register struct obj *otmp; 364.  365.  	for(otmp = fobj; otmp; otmp = otmp->nobj) 366. 	  if(throws_rocks(mtmp->data) ? otmp->otyp == BOULDER :  367.  			(otmp->olet == GEM_SYM && otmp->otyp < LAST_GEM+5)) 368. 	    if(otmp->ox == mtmp->mx && otmp->oy == mtmp->my) 369. 	      if(mtmp->data->mlet != S_UNICORN  370.  		 || objects[otmp->otyp].g_val != 0){ 371. 		if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 372. 			pline("%s picks up %s.", Monnam(mtmp),  373.  				distant_name(otmp, doname)); 374. 		freeobj(otmp); 375. 		mpickobj(mtmp, otmp); 376. 		newsym(mtmp->mx, mtmp->my); 377. 		return;	/* pick only one object */ 378. 	      }  379.  	set_omask(mtmp->mx, mtmp->my); 380. }  381.   382.  int 383. curr_mon_load(mtmp) 384. register struct monst *mtmp; 385. {  386.  	register int curload = 0; 387. 	register struct obj *obj; 388.  389.  	for(obj = mtmp->minvent; obj; obj = obj->nobj) { 390. 		if(obj->otyp != BOULDER || !throws_rocks(mtmp->data)) 391. 			curload += weight(obj); 392. 	}  393.   394.  	return curload; 395. }  396.   397.  int 398. max_mon_load(mtmp) 399. register struct monst *mtmp; 400. {  401.  	register int maxload; 402.  403.  	/* Base monster carrying capacity is equal to human maximum 404. 	 * carrying capacity, or half human maximum if not strong. 405. 	 * (for a polymorphed player, the value used would be the  406.  	 * non-polymorphed carrying capacity instead of max/half max). 407. 	 * This is then modified by the ratio between the monster weights 408. 	 * and human weights (weight of a human=45). Limits for corpseless 409. 	 * monsters are arbitrary. 410. 	 */  411.  	maxload = (mtmp->data->cwt ? mtmp->data->cwt : mtmp->data->mlevel*6) 412. 		* MAX_CARR_CAP / 45; 413. 	if (!strongmonst(mtmp->data)) maxload /= 2; 414.  415.  	return maxload; 416. }  417.   418.  /* for restricting monsters' object-pickup */ 419. boolean 420. can_carry(mtmp,otmp) 421. struct monst *mtmp; 422. struct obj *otmp; 423. {  424.  	register int newload = weight(otmp); 425.  426.  	if (mtmp->isshk) return(TRUE); /* no limit */ 427. 	if (mtmp->mpeaceful && !mtmp->mtame) return(FALSE); 428. 	/* otherwise players might find themselves obligated to violate 429. 	 * their alignment if the monster takes something they need 430. 	 */  431.  	  432.  	/* special--boulder throwers carry unlimited amounts of boulders */ 433. 	if (throws_rocks(mtmp->data) && otmp->otyp == BOULDER) 434. 		return(TRUE); 435. 	  436.  	/* nymphs deal in stolen merchandise, but not boulders or statues */ 437. 	if (mtmp->data->mlet == S_NYMPH) 438. 		return !(otmp->olet == ROCK_SYM); 439.  440.  	if(curr_mon_load(mtmp) + newload > max_mon_load(mtmp)) return(FALSE); 441.  442.  	return(TRUE); 443. }  444.   445.  void 446. mpickstuff(mtmp, str) 447. 	register struct monst *mtmp; 448. 	register char *str; 449. {  450.  	register struct obj *otmp; 451.  452.  /*	prevent shopkeepers from leaving the door of their shop */ 453. 	if(mtmp->isshk && inhishop(mtmp)) return; 454.  455.  	for(otmp = fobj; otmp; otmp = otmp->nobj) 456. 	  if(index(str, otmp->olet)) 457. 	    if(otmp->ox == mtmp->mx && otmp->oy == mtmp->my) { 458. 		if(!can_carry(mtmp,otmp)) return; 459. 		if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 460. 			pline("%s picks up %s.", Monnam(mtmp), doname(otmp)); 461. 		freeobj(otmp); 462. 		mpickobj(mtmp, otmp); 463. 		if(index(str, (char) levl[mtmp->mx][mtmp->my].scrsym)) 464. 			newsym(mtmp->mx, mtmp->my); 465. 		set_omask(mtmp->mx, mtmp->my); 466. 		return;			/* pick only one object */ 467. 	    }  468.  }  469.   470.  /* return number of acceptable neighbour positions */ 471. int 472. mfndpos(mon, poss, info, flag) 473. 	register struct monst *mon; 474. 	coord *poss;	/* coord poss[9] */ 475. 	long *info;	/* long info[9] */ 476. 	long flag; 477. {  478.  	register int x,y,nx,ny,cnt = 0,ntyp; 479. 	int nowtyp; 480. 	boolean wantpool,poolok; 481.  482.  	x = mon->mx; 483. 	y = mon->my; 484. 	nowtyp = levl[x][y].typ; 485.  486.  	wantpool = mon->data->mlet == S_EEL; 487. 	poolok = is_flyer(mon->data) || (is_swimmer(mon->data) && !wantpool); 488. nexttry:	/* eels prefer the water, but if there is no water nearby, 489. 		   they will crawl over land */ 490. 	if(mon->mconf) { 491. 		flag |= ALLOW_ALL; 492. 		flag &= ~NOTONL; 493. 	}  494.  	if(!mon->mcansee) 495. 		flag |= ALLOW_SSM; 496. 	for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) { 497. 	    if((nx == x && ny == y) || !isok(nx,ny)) continue; 498. 	    if(IS_ROCK(ntyp = levl[nx][ny].typ) && !(flag & ALLOW_WALL) &&  499.  		!((flag & ALLOW_DIG) && may_dig(nx,ny))) continue; 500. 	    if(IS_DOOR(ntyp) && !amorphous(mon->data) &&  501.  	       ((levl[nx][ny].doormask & D_LOCKED &&  502.  		   !is_giant(mon->data) && !mon->isshk) || 503. 		(levl[nx][ny].doormask & D_CLOSED &&  504.  		   (verysmall(mon->data) || 505. 		    (!is_giant(mon->data) && nohands(mon->data)))) 506. 	       ) && !(flag & (ALLOW_WALL|ALLOW_DIG))) continue; 507. 	    if(nx != x && ny != y && (IS_DOOR(nowtyp) || IS_DOOR(ntyp))) 508. 		continue; 509. 	    if(is_pool(nx,ny) == wantpool || poolok) { 510. 		/* Displacement also displaces the Elbereth/scare monster, 511. 		 * as long as you are visible. 512. 		 */  513.  		int dispx = (Displaced && (!Invis || perceives(mon->data)) &&  514.  			(mon->mux==nx)) ? u.ux : nx; 515. 		int dispy = (Displaced && (!Invis || perceives(mon->data)) &&  516.  			(mon->muy==ny)) ? u.uy : ny; 517.  518.  		info[cnt] = 0; 519. 		if(sobj_at(SCR_SCARE_MONSTER, dispx, dispy)  520.  #ifdef ELBERETH  521.  		   || sengr_at("Elbereth", dispx, dispy)  522.  #endif  523.  		  ) { 524. 			if(!(flag & ALLOW_SSM)) continue; 525. 			info[cnt] |= ALLOW_SSM; 526. 		}  527.  		if((nx == u.ux && ny == u.uy) ||  528.  		   (nx == mon->mux && ny == mon->muy)) { 529. 			if(!(flag & ALLOW_U)) continue; 530. 			info[cnt] |= ALLOW_U; 531. 		} else { 532. 			if(levl[nx][ny].mmask) { 533. 				if(!(flag & ALLOW_M)) continue; 534. 				info[cnt] |= ALLOW_M; 535. 				if((m_at(nx,ny))->mtame) { 536. 					if(!(flag & ALLOW_TM)) continue; 537. 					info[cnt] |= ALLOW_TM; 538. 				}  539.  			}  540.  #if defined(ALTARS) && defined(THEOLOGY) 541. 			/* Note: ALLOW_SANCT only prevents movement, not */ 542. 			/* attack, into a temple. */ 543.  			if(!in_temple(x, y) && in_temple(nx, ny) &&  544.  					u_in_sanctuary(in_temple(nx, ny))) { 545. 				if(!(flag & ALLOW_SANCT)) continue; 546. 				info[cnt] |= ALLOW_SANCT; 547. 			}  548.  #endif 549. 		}  550.  		if(sobj_at(CLOVE_OF_GARLIC, nx, ny)) { 551. 			if(flag & NOGARLIC) continue; 552. 			info[cnt] |= NOGARLIC; 553. 		}  554.  		if(sobj_at(BOULDER, nx, ny)) { 555. 			if(!(flag & ALLOW_ROCK)) continue; 556. 			info[cnt] |= ALLOW_ROCK; 557. 		}  558.  		if((!Invis || perceives(mon->data)) && online(nx,ny)){ 559. 			if(flag & NOTONL) continue; 560. 			info[cnt] |= NOTONL; 561. 		}  562.  		/* we cannot avoid traps of an unknown kind */ 563. 		{ register struct trap *ttmp = t_at(nx, ny); 564. 		  register long tt; 565. 			if(ttmp) { 566. /*				tt = 1L << ttmp->ttyp;*/ 567. /* why don't we just have code look like what it's supposed to do? then it 568. /* might start working for every case. try this instead: -sac */ 569. 				tt = (ttmp->ttyp < TRAPNUM && ttmp->ttyp); 570. 				/* below if added by GAN 02/06/87 to avoid 571. 				 * traps out of range 572. 				 */  573.  				if(!(tt & ALLOW_TRAPS))  { 574. impossible("A monster looked at a very strange trap of type %d.", ttmp->ttyp); 575. 					continue; 576. 				}  577.  				if(mon->mtrapseen & tt) { 578.  579.  					if(!(flag & tt)) continue; 580. 					info[cnt] |= tt; 581. 				}  582.  			}  583.  		}  584.  		poss[cnt].x = nx; 585. 		poss[cnt].y = ny; 586. 		cnt++; 587. 	    }  588.  	}  589.  	if(!cnt && wantpool && !is_pool(x,y)) { 590. 		wantpool = FALSE; 591. 		goto nexttry; 592. 	}  593.  	return(cnt); 594. }  595.   596.  int 597. dist(x, y)  598. register int x,y; 599. {  600.  	register int dx = x - u.ux, dy = y - u.uy; 601. 	return dx*dx + dy*dy; 602. }  603.   604.  static const char *poiseff[] = { 605.  606.  	" feel very weak", "r brain is on fire", 607. 	" can't think straight", "r muscles won't obey you", 608. 	" feel very sick", " break out in hives" 609. };  610.   611.  void 612. poisontell(typ) 613.  614.  	int	typ; 615. {  616.  	pline("You%s.", poiseff[typ]); 617. }  618.   619.  void 620. poisoned(string, typ, pname) 621. register char *string, *pname; 622. register int  typ; 623. {  624.  	register int i, plural; 625. 	boolean thrown_weapon = !strncmp(string, "poison", 6); 626. 		/* admittedly a kludge... */ 627.   628.  	if(strcmp(string, "blast") && !thrown_weapon) { 629. 	    /* 'blast' has already given a 'poison gas' message */ 630. 	    /* so have "poison arrow", "poison dart", etc... */ 631.  	    plural = (string[strlen(string) - 1] == 's')? 1 : 0; 632.  	    if(Blind) 633. 		pline("%s poisoned.", (plural) ? "They were" : "It was"); 634. 	    else 635. 		pline("The %s %s poisoned!", string, (plural) ? "were" : "was"); 636. 	}  637.   638.  	if(Poison_resistance) { 639. 		if(!strcmp(string, "blast")) shieldeff(u.ux, u.uy); 640. 		pline("The poison doesn't seem to affect you."); 641. 		return; 642. 	}  643.  	i = rn2(10 + 20*thrown_weapon); 644. 	if(i == 0 && typ != A_CHA) { 645. 		u.uhp = -1; 646. 		pline("The poison was deadly..."); 647. 	} else if(i <= 5) { 648. 		pline("You%s!", poiseff[typ]); 649. 		adjattrib(typ, thrown_weapon ? -1 : -rn1(3,3), TRUE); 650. 	} else { 651. 		losehp(thrown_weapon ? rnd(6) : rn1(10,6), pname); 652. 	}  653.  	if(u.uhp < 1) { 654. 		killer = pname; 655. 		done("died"); 656. 	}  657.  }  658.   659.  static void 660. m_detach(mtmp) 661. register struct monst *mtmp; 662. {  663.  #ifdef WALKIES 664. 	if(mtmp->mleashed) m_unleash(mtmp); 665. #endif 666. 	relobj(mtmp,1); 667. 	unpmon(mtmp); 668. 	relmon(mtmp); 669. 	unstuck(mtmp); 670. }  671.   672.  void 673. mondead(mtmp) 674. register struct monst *mtmp; 675. {  676.  	m_detach(mtmp); 677. #ifdef KOPS 678. 	if(mtmp->data->mlet == S_KOP && allow_kops) { 679. 	    /* Dead Kops may come back. */ 680.  	    switch(rnd(5)) { 681. 		case 1:	     /* returns near the stairs */ 682. 			(void) mkmon_at(mtmp->data->mname,xdnstair,ydnstair); 683. 			break; 684. 		case 2:	     /* randomly */ 685. 			(void) mkmon_at(mtmp->data->mname,0,0); 686. 			break; 687. 		default: 688. 			break; 689. 	    }  690.  	}  691.  #endif 692. 	if(mtmp->isshk) shkdead(mtmp); 693. 	if(mtmp->isgd) gddead; 694. #ifdef WORM 695. 	if(mtmp->wormno) wormdead(mtmp); 696. #endif 697. #ifdef HARD 698. 	if(mtmp->iswiz) wizdead(mtmp); 699. #endif 700. #ifdef MEDUSA 701. 	if(mtmp->data == &mons[PM_MEDUSA]) u.ukilled_medusa = TRUE; 702. #endif 703. 	monfree(mtmp); 704. }  705.   706.  /* called when monster is moved to larger structure */ 707. void 708. replmon(mtmp, mtmp2) 709. register struct monst *mtmp, *mtmp2; 710. {  711.  	relmon(mtmp); 712. 	monfree(mtmp); 713. 	levl[mtmp2->mx][mtmp2->my].mmask = 1; 714. 	mtmp2->nmon = fmon; 715. 	fmon = mtmp2; 716. 	if(u.ustuck == mtmp) u.ustuck = mtmp2; 717. 	if(mtmp2->isshk) replshk(mtmp,mtmp2); 718. 	if(mtmp2->isgd) replgd(mtmp,mtmp2); 719. }  720.   721.  void 722. relmon(mon) 723. register struct monst *mon; 724. {  725.  	register struct monst *mtmp; 726.  727.  	if (fmon == 0)  panic ("relmon: no fmon available."); 728.  729.  	levl[mon->mx][mon->my].mmask = 0; 730.  731.  	if(mon == fmon) fmon = fmon->nmon; 732. 	else { 733. 		for(mtmp = fmon; mtmp && mtmp->nmon != mon; mtmp = mtmp->nmon) ; 734. 		if(mtmp)    mtmp->nmon = mon->nmon; 735. 		else	    panic("relmon: mon not in list."); 736. 	}  737.  }  738.   739.  /* we do not free monsters immediately, in order to have their name 740.    available shortly after their demise */ 741. void 742. monfree(mtmp) register struct monst *mtmp; { 743. 	mtmp->nmon = fdmon; 744. 	fdmon = mtmp; 745. 	levl[mtmp->mx][mtmp->my].mmask = 0; 746. }  747.   748.  void 749. unstuck(mtmp) 750. register struct monst *mtmp; 751. {  752.  	if(u.ustuck == mtmp) { 753. 		if(u.uswallow){ 754. 			u.ux = mtmp->mx; 755. 			u.uy = mtmp->my; 756. 			u.uswallow = 0; 757. 			setsee; 758. 			docrt; 759. 		}  760.  		u.ustuck = 0; 761. 	}  762.  }  763.   764.  void 765. killed(mtmp) 766. register struct monst *mtmp; 767. {  768.  	xkilled(mtmp, 1); 769. }  770.   771.  void 772. xkilled(mtmp, dest) 773. 	register struct monst *mtmp; 774. /*  775.   * Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse 776.  * either; dest=3, message but no corpse 777.  */  778.  	int	dest; 779. {  780.  	register int tmp, nk, x, y;  781. register struct permonst *mdat = mtmp->data; 782. 	register struct obj *otmp; 783. 	boolean chance; 784.  785.  	if (dest & 1) { 786. 	    if(!cansee(mtmp->mx,mtmp->my)) You("destroy it!"); 787. 	    else { 788. 		You("destroy %s!",  789.  			mtmp->mtame ? a_monnam(mtmp, "poor") : mon_nam(mtmp)); 790. 	    }  791.  	}  792.   793.  	/* restore chameleon, lycanthropes to true form at death */ 794. 	/* cannot do this in make_corpse since genociding monsters after 795. 	 * MAXMONNO were killed does the wrong type 796. 	 */  797.  	if(mtmp->cham) mtmp->data = mdat = &mons[PM_CHAMELEON]; 798. 	if(mdat == &mons[PM_JACKALWERE]) 799. 		mtmp->data = mdat = &mons[PM_WEREJACKAL]; 800. 	if(mdat == &mons[PM_WOLFWERE]) 801. 		mtmp->data = mdat = &mons[PM_WEREWOLF]; 802. 	if(mdat == &mons[PM_RATWERE]) 803. 		mtmp->data = mdat = &mons[PM_WERERAT]; 804.  805.  	if(u.umconf) { 806. 	    if(!Blind) { 807. 		Your("%s stop glowing %s.",  808.  		makeplural(body_part(HAND)),  809.  		Hallucination ? hcolor : red); 810. 	    }  811.  	    u.umconf = 0; 812. 	}  813.   814.  	/* if we have killed MAXMONNO monsters of a given type, and it  815. * can be done, genocide that monster. 816. 	 */  817.  	tmp = monsndx(mdat); 818. 	u.nr_killed[tmp]++; 819. 	nk = u.nr_killed[tmp]; 820. #ifdef TOLKIEN 821. 	if(nk > (tmp==PM_NAZGUL ? 9 : MAXMONNO) && 822.  				!(mons[tmp].geno & (G_NOGEN | G_GENOD))) { 823. #else 824. 	if(nk > MAXMONNO && !(mons[tmp].geno & (G_NOGEN | G_GENOD))) { 825. #endif 826. #ifdef DEBUG 827. 		pline("Automatically genocided %s.", makeplural(mons[tmp].mname)); 828. #endif 829. 		mons[tmp].geno |= G_GENOD; 830. 	}  831.  #ifdef MAIL 832. 	/* If you kill the mail daemon, no more mail delivery. -3. */ 833.  	else if(tmp==PM_MAIL_DAEMON) mons[tmp].geno |= G_GENOD; 834. #endif 835.  836.  	/* punish bad behaviour */ 837. 	if(is_human(mdat) && !always_hostile(mdat) &&  838.  	   (monsndx(mdat) < PM_ARCHEOLOGIST || monsndx(mdat) > PM_WIZARD) &&  839.  	   u.ualigntyp != U_CHAOTIC) { 840. 		HTelepat &= ~INTRINSIC; 841. 		change_luck(-2); 842. 	}  843.  	if((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame)	change_luck(-1); 844. 	if ((mdat==&mons[PM_BLACK_UNICORN] && u.ualigntyp == U_CHAOTIC) ||  845.  	    (mdat==&mons[PM_GREY_UNICORN] && u.ualigntyp == U_NEUTRAL) ||  846.  	    (mdat==&mons[PM_WHITE_UNICORN] && u.ualigntyp == U_LAWFUL)) 847. 		change_luck(-5); 848.  849.  	/* give experience points */ 850. 	tmp = experience(mtmp, nk); 851. 	more_experienced(tmp, 0); 852. 	newexplevel;		/* will decide if you go up */ 853.  854.  	/* adjust alignment points */ 855. 	if(mtmp->mtame) 856. 		adjalign(-15);	/* bad!! */ 857.  #if defined(ALTARS) && defined(THEOLOGY) 858. 	else if (mtmp->ispriest && !p_coaligned(mtmp)) 859. 		adjalign(2); 860. #endif 861. 	else if (mtmp->mpeaceful) 862. 		adjalign(-5); 863. 	/* malign was already adjusted for ualigntyp and randomization */ 864. 	adjalign(mtmp->malign); 865.  866.  	/* dispose of monster and make cadaver */ 867. 	if(stoned) { 868. 		monstone(mtmp); 869. 		return; 870. 	}  871.   872.  	x = mtmp->mx;   y = mtmp->my; 873.  874.  	mondead(mtmp); 875.  876.  	if((dest & 2)  877.  #ifdef REINCARNATION  878.  		 || dlevel == rogue_level  879.  #endif  880.  					) return; 881.  882.  #ifdef WORM 883. 	if(mdat == &mons[PM_LONG_WORM]) { 884. 		(void) mksobj_at(WORM_TOOTH, x, y); 885. 		stackobj(fobj); 886. 		newsym(x,y); 887. 	}  888.  #endif 889. #ifdef MAIL 890. 	if(mdat == &mons[PM_MAIL_DAEMON]) { 891. 		(void) mksobj_at(SCR_MAIL, x, y); 892. 		stackobj(fobj); 893. 		newsym(x,y); 894. 	}  895.  #endif 896. 	if(!ACCESSIBLE(levl[x][y].typ) ||  897.  	   (IS_DOOR(levl[x][y].typ) && 898. 	    levl[x][y].doormask & (D_CLOSED | D_LOCKED))) { 899. 	    /* might be mimic in wall or dead eel*/ 900.  	    newsym(x,y); 901. 	} else if(x != u.ux || y != u.uy) { 902. 		/* might be here after swallowed */ 903. 		if (!rn2(6) && !(mdat->geno & G_NOCORPSE)  904.  #ifdef KOPS  905.  					&& mdat->mlet != S_KOP  906.  #endif  907.  							) { 908. 			int typ; 909.  910.  			otmp = mkobj_at(RANDOM_SYM, x, y); 911. 			/* Don't create large objects from small monsters */ 912. 			typ = otmp->otyp; 913. 			if (!bigmonst(mdat) && typ != FOOD_RATION  914.  #ifdef WALKIES  915.  			    && typ != LEASH  916.  #endif  917.  			    && typ != FIGURINE  918.  			    && (otmp->owt > 3 || 919. 				(typ >= SPEAR && typ <= LANCE) || 920. 				(typ >= SCIMITAR && typ <= KATANA) || 921. 				(typ == MORNING_STAR || typ == QUARTERSTAFF) || 922. 				(typ >= BARDICHE && typ <= VOULGE) || 923. 				(typ>=PLATE_MAIL && typ<=DRAGON_SCALE_MAIL) || 924. 				(typ == LARGE_SHIELD))) { 925. 			    delobj(otmp); 926. 			} else newsym(x,y); 927. 		}  928.  		/* Whether or not it always makes a corpse is, in theory, 929. 		 * different from whether or not the corpse is "special"; 930. 		 * if we want both, we have to specify it explicitly. 931. 		 */  932.  		if (bigmonst(mdat)  933.  #ifdef GOLEMS  934.  				   || is_golem(mdat)  935.  #endif  936.  		   ) chance = 1; 937. 		else chance = !rn2((int)  938.  			(2 + ((mdat->geno & G_FREQ)<2) + verysmall(mdat))); 939. 		if (chance) 940. 			(void) make_corpse(mtmp); 941. 	}  942.  }  943.   944.  /*VARARGS2*/ 945. void 946. kludge(str, arg, arg2, arg3) 947. 	register char *str,*arg,*arg2,*arg3; 948. {  949.  	if(Blind || !flags.verbose) { 950. 		if(*str == '%') pline(str,"It",arg2,arg3); 951. 		else pline(str,"it",arg2,arg3); 952. 	} else pline(str,arg,arg2,arg3); 953. }  954.   955.  void 956. rescham {	/* force all chameleons to become normal */ 957.  958.  	register struct monst *mtmp; 959.  960.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 961. 		if(mtmp->cham) { 962. 			mtmp->cham = 0; 963. 			(void) newcham(mtmp, &mons[PM_CHAMELEON]); 964. 		}  965.  		if(is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN) 966. 			(void) new_were(mtmp); 967. 	}  968.  }  969.   970.  /* Let the chameleons change again -dgk */ 971. void 972. restartcham { 973.  974.  	register struct monst *mtmp; 975.  976.  	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) 977. 		if (mtmp->data->mlet == S_CHAMELEON) 978. 			mtmp->cham = 1; 979. }  980.   981.  int 982. newcham(mtmp, mdat)	/* make a chameleon look like a new monster */ 983. 			/* returns 1 if the monster actually changed */ 984. 	register struct monst *mtmp; 985. 	register struct permonst *mdat; 986. {  987.  	register int mhp, hpn, hpd; 988. 	int tryct; 989.  990.  	/* mdat = 0 -> caller wants a random monster shape */ 991. 	tryct = 0; 992. 	if(mdat == 0) { 993. 		while (++tryct < 100) { 994. 			static int num; 995. 			mdat = &mons[num=rn2(NUMMONS)]; 996. 			if ((!is_human(mdat) || num == PM_NURSE)  997.  				&& !type_is_pname(mdat)  998.  				&& !is_were(mdat)  999.  #ifdef MEDUSA  1000. 				&& num != PM_MEDUSA  1001. #endif  1002. #ifdef MAIL  1003. 				&& num != PM_MAIL_DAEMON  1004. #endif  1005. 				) 1006. 				break; 1007. 		} 1008. 		if (tryct >= 100) return(0); /* Should never happen */ 1009. 	} 1010.   	if(mdat == mtmp->data) return(0);	/* still the same monster */ 1011. 1012. #ifdef WORM 1013. 	if(mtmp->wormno) wormdead(mtmp);	/* throw tail away */ 1014. #endif 1015. 	mtmp->m_lev = adj_lev(mdat);		/* new monster level */ 1016. 1017. 	hpn = mtmp->mhp; 1018. 	hpd = (mtmp->m_lev < 50) ? (mtmp->m_lev)*8 : mdat->mlevel; 1019. 	if(!hpd) hpd = 4; 1020. 	mhp = (mtmp->m_lev < 50) ? (mtmp->m_lev)*8 : mdat->mlevel; 1021. 	if(!mhp) mhp = 4; 1022. 1023. 	/* new hp: same fraction of max as before */ 1024. #ifndef LINT 1025. 	mtmp->mhp = (int)(((long)hpn*(long)mhp)/(long)hpd); 1026. #endif 1027. 	if(mtmp->mhp < 0) mtmp->mhp = hpn;	/* overflow */ 1028. /* Unlikely but not impossible; a 1HD creature with 1HP that changes into a 1029. 0HD creature will require this statement */ 1030. 	if (!mtmp->mhp) mtmp->mhp = 1; 1031. 1032. /* and the same for maximum hit points */ 1033. 	hpn = mtmp->mhpmax; 1034. #ifndef LINT 1035. 	mtmp->mhpmax = (int)(((long)hpn*(long)mhp)/(long)hpd); 1036. #endif 1037. 	if(mtmp->mhpmax < 0) mtmp->mhpmax = hpn;	/* overflow */ 1038. 	if (!mtmp->mhpmax) mtmp->mhpmax = 1; 1039. 1040.  	mtmp->data = mdat; 1041. 	mtmp->minvis = !!(mdat->mlet == S_STALKER); 1042. 	mtmp->mhide = !!hides_under(mdat); 1043. 	if (!mtmp->mhide) mtmp->mundetected = 0; 1044. 	if (u.ustuck == mtmp 1045. #ifdef POLYSELF  1046. 			&& !sticks(uasmon)  1047. #endif  1048. 			&& !sticks(mdat)) 1049. 		u.ustuck = 0; 1050. #ifdef WORM 1051. 	if(mdat == &mons[PM_LONG_WORM] && getwn(mtmp)) initworm(mtmp); 1052. 			/* perhaps we should clear mtmp->mtame here? */ 1053. #endif 1054. 	unpmon(mtmp);	/* necessary for 'I' and to force pmon */ 1055. 	pmon(mtmp); 1056. 	return(1); 1057. } 1058.  1059. void 1060. mnexto(mtmp)	/* Make monster mtmp next to you (if possible) */ 1061. 	struct monst *mtmp; 1062. { 1063. 	coord mm; 1064. 	enexto(&mm, u.ux, u.uy); 1065. 	levl[mtmp->mx][mtmp->my].mmask = 0; 1066. 	levl[mm.x][mm.y].mmask = 1; 1067. 	mtmp->mx = mm.x; 1068. mtmp->my = mm.y; 1069. pmon(mtmp); 1070. 	set_apparxy(mtmp); 1071. } 1072.  1073. void 1074. mnearto(mtmp,x,y,gz)	/* Make monster near (or at) location if possible */ 1075. 	register struct monst *mtmp; 1076. 	xchar x, y; 1077. boolean gz; 1078. { 1079. 	coord mm; 1080. 	if(!gz || !goodpos(x,y)) { 1081. 		enexto(&mm, x, y); 1082. 		x = mm.x; y = mm.y; 1083. } 1084. 	if(x == mtmp->mx && y == mtmp->my) /* that was easy */ 1085. 		return; 1086. 	levl[mtmp->mx][mtmp->my].mmask = 0; 1087. 	levl[x][y].mmask = 1; 1088. 	mtmp->mx = x; 1089. mtmp->my = y; 1090. pmon(mtmp); 1091. 	set_apparxy(mtmp); 1092. } 1093.  1094. void 1095. setmangry(mtmp) 1096. 	register struct monst *mtmp; 1097. { 1098. 	if(!mtmp->mpeaceful) return; 1099. 	if(mtmp->mtame) return; 1100. 	mtmp->mpeaceful = 0; 1101. #if defined(ALTARS) && defined(THEOLOGY) 1102. 	if(mtmp->ispriest) { 1103. 		if(p_coaligned(mtmp)) adjalign(-5); /* very bad */ 1104. 		else adjalign(2); 1105. 	} else 1106. #endif 1107. 	adjalign(-1);		/* attacking peaceful monsters is bad */ 1108. 	if(humanoid(mtmp->data) || mtmp->isshk || mtmp->isgd) 1109. 		pline("%s gets angry!", Monnam(mtmp)); 1110. #ifdef SOUNDS 1111. 	else if (flags.verbose && flags.soundok) growl(mtmp); 1112. #endif 1113. } 1114.  1115. int 1116. disturb(mtmp)		/* awaken monsters while in the same room. 1117. 			 * return a 1 if they have been woken. 1118. 			 */ 1119. 	register struct monst *mtmp; 1120. { 1121. 	/* wake up, or get out of here. */ 1122. 	/* ettins are hard to surprise */ 1123. 	/* Nymphs and Leprechauns do not easily wake up */ 1124. 	if(cansee(mtmp->mx,mtmp->my) && 1125. 		(!Stealth || (mtmp->data == &mons[PM_ETTIN] && rn2(10))) &&  1126. 		(!(mtmp->data->mlet == S_NYMPH  1127. 		   || mtmp->data->mlet == S_LEPRECHAUN) || !rn2(50)) &&  1128. 		(Aggravate_monster || 1129. 		 (mtmp->data->mlet == S_DOG || mtmp->data->mlet == S_HUMAN) || 1130. 		(!rn2(7) && !mtmp->mimic))) { 1131. 		mtmp->msleep = 0; 1132. 		return(1); 1133. 	} 1134. 	if(Hallucination) pmon(mtmp); 1135. 	return(0); 1136. } 1137.  1138. #ifdef HARD 1139. static boolean 1140. restrap(mtmp) 1141. /* unwatched hiders may hide again, 1142. * if so, a 1 is returned. 1143. */  1144. register struct monst *mtmp; 1145. { 1146. 	if(mtmp->cham || mtmp->mcan || mtmp->mimic ||  1147. 	   cansee(mtmp->mx, mtmp->my) || rn2(3)) 1148. 		return(FALSE); 1149. 1150. 	if(mtmp->data->mlet == S_MIMIC) { 1151. 		set_mimic_sym(mtmp); 1152. 		return(TRUE); 1153. 	} else 1154. 	   if(levl[mtmp->mx][mtmp->my].typ == ROOM)  { 1155. 		(void) maketrap(mtmp->mx, mtmp->my, MONST_TRAP); 1156. 		/* override type selection */ 1157. 		ftrap->pm = monsndx(mtmp->data); 1158. 		mondead(mtmp); 1159. 		return(TRUE); 1160. 	   }  1161.  1162. 	return(FALSE); 1163. } 1164. #endif 1165. 1166. /* drop (perhaps) a cadaver and remove monster */ 1167. void 1168. mondied(mdef) 1169. register struct monst *mdef; 1170. { 1171. 	mondead(mdef); 1172. 	if(rn2(3) 1173. #ifdef REINCARNATION  1174. 	   && dlevel != rogue_level  1175. #endif  1176. 					) 1177. 		(void) make_corpse(mdef); 1178. } 1179.  1180. /* monster disappears, not dies */ 1181. void 1182. mongone(mdef) 1183. register struct monst *mdef; 1184. { 1185. 	register struct obj *otmp, *otmp2; 1186. 1187. 	/* release monster's inventory */ 1188. 	for (otmp = mdef->minvent; otmp; otmp = otmp2) { 1189. 		otmp2 = otmp->nobj; 1190. 		obfree(otmp, (struct obj *)0); 1191. 	} 1192. 	mdef->minvent = 0; 1193. 	mdef->mgold = 0; 1194. 	m_detach(mdef); 1195. 	monfree(mdef); 1196. } 1197.  1198. /* drop a statue or rock and remove monster */ 1199. void 1200. monstone(mdef) 1201. register struct monst *mdef; 1202. { 1203. 	struct obj *otmp; 1204. 1205. 	if(!verysmall(mdef->data) ||  1206. 	   !rn2(2 + ((mdef->data->geno & G_FREQ) > 2))) { 1207. 		otmp = mk_named_object(STATUE, mdef->data, mdef->mx, mdef->my, 1208. 			NAME(mdef), (int)mdef->mnamelth); 1209. 		otmp->spe = 0; /* no book inside */ 1210. 	} else 1211. 		(void) mksobj_at(ROCK, mdef->mx, mdef->my); 1212. 1213. 	stackobj(fobj); 1214. 1215. 	if(cansee(mdef->mx, mdef->my)){ 1216. 		unpmon(mdef); 1217. 		atl(mdef->mx,mdef->my,Hallucination ? rndobjsym : fobj->olet); 1218. 	} 1219. 	mondead(mdef); 1220. } 1221.  1222. #ifdef GOLEMS 1223. void 1224. golemeffects(mon, damtype, dam) 1225. register struct monst *mon; 1226. int damtype, dam; 1227. { 1228. 	int heal=0, slow=0; 1229. 1230. 	if (mon->data != &mons[PM_FLESH_GOLEM]  1231. 					&& mon->data != &mons[PM_IRON_GOLEM]) 1232. 		return; 1233. 1234. 	if (mon->data == &mons[PM_FLESH_GOLEM]) { 1235. 		if (damtype == AD_ELEC) heal = dam / 6; 1236. 		else if (damtype == AD_FIRE || damtype == AD_COLD) slow = 1; 1237. 	} else { 1238. 		if (damtype == AD_ELEC) slow = 1; 1239. 		else if (damtype == AD_FIRE) heal = dam; 1240. 	} 1241. 	if (slow) { 1242. 		if (mon->mspeed != MSLOW) { 1243. 			if (mon->mspeed == MFAST) mon->mspeed = 0; 1244. 			else mon->mspeed = MSLOW; 1245. 			if (cansee(mon->mx, mon->my)) 1246. 				pline("%s seems to be moving slower.", 1247. 					Monnam(mon)); 1248. 		} 1249. 	}  1250. 	if (heal) { 1251. 		if (mon->mhp < mon->mhpmax) { 1252. 			mon->mhp += dam; 1253. 			if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; 1254. 			if (cansee(mon->mx, mon->my)) 1255. 				pline("%s seems healthier.", Monnam(mon)); 1256. 		} 1257. 	}  1258. }  1259. #endif /* GOLEMS */