Source:NetHack 3.2.0/trap.c

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

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

1.   /*	SCCS Id: @(#)trap.c	3.2	96/04/08	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.   STATIC_DCL void FDECL(dofiretrap, (struct obj *)); 8.   STATIC_DCL void NDECL(domagictrap); 9.   STATIC_DCL boolean FDECL(emergency_disrobe,(boolean *)); 10.  STATIC_DCL int FDECL(untrap_prob, (struct trap *ttmp)); 11.  STATIC_DCL void FDECL(cnv_trap_obj, (int, int, struct trap *)); 12.  STATIC_DCL void FDECL(move_into_trap, (struct trap *)); 13.  STATIC_DCL int FDECL(try_disarm, (struct trap *,BOOLEAN_P)); 14.  STATIC_DCL void FDECL(reward_untrap, (struct trap *, struct monst *)); 15.  STATIC_DCL int FDECL(disarm_beartrap, (struct trap *)); 16.  STATIC_DCL int FDECL(disarm_landmine, (struct trap *)); 17.  STATIC_DCL int FDECL(disarm_squeaky_board, (struct trap *)); 18.  STATIC_DCL int FDECL(disarm_shooting_trap, (struct trap *, int)); 19.  STATIC_DCL int FDECL(try_lift, (struct monst *, struct trap *, int, BOOLEAN_P)); 20.  STATIC_DCL int FDECL(help_monster_out, (struct monst *, struct trap *)); 21.  STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int)); 22.  STATIC_DCL int FDECL(mkroll_launch,  23.   			(struct trap *,XCHAR_P,XCHAR_P,SHORT_P,long)); 24.  STATIC_DCL boolean FDECL(isclearpath,(coord *, int, SCHAR_P, SCHAR_P)); 25.   26.   #ifndef OVLB 27.  STATIC_VAR const char *a_your[2]; 28.  STATIC_VAR const char *A_Your[2]; 29.  STATIC_VAR const char *the_your[2]; 30.  STATIC_VAR const char tower_of_flame[]; 31.  STATIC_VAR const char *A_gush_of_water_hits; 32.   33.   #else 34.   35.   STATIC_VAR const char *a_your[2] = { "a", "your" }; 36.  STATIC_VAR const char *A_Your[2] = { "A", "Your" }; 37.  STATIC_VAR const char *the_your[2] = { "the", "your" }; 38.  STATIC_VAR const char tower_of_flame[] = "tower of flame"; 39.  STATIC_VAR const char *A_gush_of_water_hits = "A gush of water hits"; 40.   41.   #endif /* OVLB */ 42.   43.   #ifdef OVLB 44.   45.   /* called when you're hit by fire (dofiretrap,buzz,zapyourself,explode) */ 46.  boolean			/* returns TRUE if hit on torso */ 47.  burnarmor 48.  {  49.   #define burn_dmg(obj,descr) rust_dmg(obj, descr, 0, FALSE) 50.      while (1) { 51.  	switch (rn2(5)) { 52.  	case 0: 53.  	    if (!burn_dmg(uarmh, "leather helmet")) continue; 54.  	    break; 55.  	case 1: 56.  	    if (uarmc) 57.  		(void) burn_dmg(uarmc, "cloak"); 58.  	    else if (uarm) 59.  		(void) burn_dmg(uarm, xname(uarm)); 60.  #ifdef TOURIST 61.  	    else if (uarmu) 62.  		(void) burn_dmg(uarmu, "shirt"); 63.  #endif 64.  	    return TRUE; 65.  	case 2: 66.  	    if (!burn_dmg(uarms, "wooden shield")) continue; 67.  	    break; 68.  	case 3: 69.  	    if (!burn_dmg(uarmg, "gloves")) continue; 70.  	    break; 71.  	case 4: 72.  	    if (!burn_dmg(uarmf, "boots")) continue; 73.  	    break; 74.  	}  75.   	break; /* Out of while loop */ 76.      }  77.       return FALSE; 78.  #undef burn_dmg 79.  }  80.    81.   /* Generic rust-armor function. Returns TRUE if a message was printed; 82.   * "print", if set, means to print a message (and thus to return TRUE) even 83.   * if the item could not be rusted; otherwise a message is printed and TRUE is  84. * returned only for rustable items. 85.   */  86.   boolean 87.  rust_dmg(otmp, ostr, type, print) 88.  register struct obj *otmp; 89.  register const char *ostr; 90.  int type; 91.  boolean print; 92.  {  93.   	static NEARDATA const char *action[] = { "smoulder", "rust", "rot", "corrode" }; 94.  	static NEARDATA const char *msg[] =  { "burnt", "rusted", "rotten", "corroded" }; 95.  	boolean vulnerable = FALSE; 96.  	boolean plural; 97.  	boolean grprot = FALSE; 98.   99.   	if (!otmp) return(FALSE); 100. 	switch(type) { 101. 		case 0: 102. 		case 2: vulnerable = is_flammable(otmp); break; 103. 		case 1: vulnerable = is_rustprone(otmp); grprot = TRUE; break; 104. 		case 3: vulnerable = is_corrodeable(otmp); grprot = TRUE; break; 105. 	}  106.   107.  	if (!print && (!vulnerable || otmp->oerodeproof || otmp->oeroded == MAX_ERODE)) 108. 		return FALSE; 109.  110.  	plural = is_gloves(otmp) || is_boots(otmp); 111.  112.  	if (!vulnerable) { 113. 		if (flags.verbose) 114. 		    Your("%s %s not affected.", ostr, plural ? "are" : "is"); 115. 	} else if (otmp->oeroded < MAX_ERODE) { 116. 		if (grprot && otmp->greased) { 117. 			grease_protect(otmp,ostr,plural); 118. 		} else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) { 119. 			if (flags.verbose) 120. 				pline("Somehow, your %s %s not affected.",  121.  					ostr, plural ? "are" : "is"); 122. 		} else { 123. 			Your("%s %s%s%s!", ostr, action[type],  124.  				plural ? "" : "s",  125.  				otmp->oeroded+1 == MAX_ERODE ? " completely" :  126.  				otmp->oeroded ? " further" : ""); 127. 			otmp->oeroded++; 128. 		}  129.  	} else { 130. 		if (flags.verbose) 131. 			Your("%s %s%s completely %s.", ostr,  132.  			     Blind ? "feel" : "look",  133.  			     plural ? "" : "s", msg[type]); 134. 	}  135.  	return(TRUE); 136. }  137.   138.  void 139. grease_protect(otmp,ostr,plu) 140. register struct obj *otmp; 141. register const char *ostr; 142. register boolean plu; 143. {  144.  	static const char txt[] = "protected by the layer of grease!"; 145.  146.  	if (ostr) 147. 		Your("%s %s %s",ostr,plu ? "are" : "is",txt); 148. 	else 149. 		Your("%s %s",aobjnam(otmp,"are"),txt); 150. 	if (!rn2(2)) { 151. 		pline_The("grease dissolves."); 152. 		otmp->greased = 0; 153. 	}  154.  }  155.   156.  struct trap * 157. maketrap(x,y,typ) 158. register int x, y, typ; 159. {  160.  	register struct trap *ttmp; 161. 	register struct rm *lev; 162. 	register boolean oldplace; 163.  164.  	if ((ttmp = t_at(x,y)) != 0) { 165. 	    if (ttmp->ttyp == MAGIC_PORTAL) return (struct trap *)0; 166. 	    oldplace = TRUE; 167. 	    if (u.utrap && (x == u.ux) && (y == u.uy) &&  168.  	      ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP) || 169. 	      (u.utraptype == TT_WEB && typ != WEB) || 170. 	      (u.utraptype == TT_PIT && typ != PIT && typ != SPIKED_PIT))) 171. 		    u.utrap = 0; 172. 	} else { 173. 	    oldplace = FALSE; 174. 	    ttmp = newtrap; 175. 	    ttmp->tx = x;  176. ttmp->ty = y; 177. ttmp->launch.x = -1;	/* force error if used before set */ 178. 	    ttmp->launch.y = -1; 179. 	}  180.  	ttmp->ttyp = typ; 181. 	switch(typ) { 182. 	    case STATUE_TRAP:	    /* create a "living" statue */ 183. 		(void) mkcorpstat(STATUE, &mons[rndmonnum], x, y, FALSE); 184. 		break; 185. 	    case ROLLING_BOULDER_TRAP:	/* boulder will roll towards trigger */ 186. 		(void) mkroll_launch(ttmp, x, y, BOULDER, 1L); 187. 		break; 188. 	    case HOLE: 189. 	    case PIT: 190. 	    case SPIKED_PIT: 191. 	    case TRAPDOOR: 192. 		lev = &levl[x][y]; 193. 		if (*in_rooms(x, y, SHOPBASE) &&  194.  			((typ == HOLE || typ == TRAPDOOR) || IS_DOOR(lev->typ))) 195. 		    add_damage(x, y,		/* schedule repair */  196.  			(IS_DOOR(lev->typ) && !flags.mon_moving) ? 200L : 0L); 197. 		lev->doormask = 0;	/* subsumes altarmask, icedpool... */ 198.  		if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */ 199. 		    lev->typ = ROOM; 200.  201.  		/*  202.  		 * some cases which can happen when digging 203. 		 * down while phazing thru solid areas 204. 		 */  205.  		else if (lev->typ == STONE || lev->typ == SCORR) 206. 		    lev->typ = CORR; 207. 		else if (IS_WALL(lev->typ) || lev->typ == SDOOR) 208. 		    lev->typ = level.flags.is_maze_lev ? ROOM : 209. 			       level.flags.is_cavernous_lev ? CORR : DOOR; 210.  211.  		unearth_objs(x, y); 212. 		break; 213. 	}  214.  	if (ttmp->ttyp == HOLE) ttmp->tseen = 1;  /* You can't hide a hole */ 215. 	else ttmp->tseen = 0; 216. 	ttmp->once = 0; 217. 	ttmp->madeby_u = 0; 218. 	ttmp->dst.dnum = -1; 219. 	ttmp->dst.dlevel = -1; 220. 	if (!oldplace) { 221. 	    ttmp->ntrap = ftrap; 222. 	    ftrap = ttmp; 223. 	}  224.  	return(ttmp); 225. }  226.   227.  void 228. fall_through(td) 229. boolean td;	/* td == TRUE : trapdoor or hole */ 230. {  231.  	d_level dtmp; 232. 	char msgbuf[BUFSZ]; 233. 	const char *dont_fall = 0; 234. 	register int newlevel = dunlev(&u.uz); 235.  236.  	if(Blind && Levitation) return; 237.  238.  	do { 239. 	    newlevel++; 240. 	} while(!rn2(4) && newlevel < dunlevs_in_dungeon(&u.uz)); 241.  242.  	if(td) { 243. 		struct trap *t=t_at(u.ux,u.uy); 244. 		if (t->ttyp == TRAPDOOR) 245. 			pline("A trap door opens up under you!"); 246. 		else 247. 			pline("There's a gaping hole under you!"); 248. 	} else pline_The("%s opens up under you!", surface(u.ux,u.uy)); 249.  250.  	if(Levitation || u.ustuck || !Can_fall_thru(&u.uz)  251.  	   || is_flyer(uasmon) || is_clinger(uasmon)  252.  	   || (Inhell && !u.uevent.invoked && 253. 					newlevel == dunlevs_in_dungeon(&u.uz))  254.  		) { 255. 	    dont_fall = "don't fall in."; 256. 	} else if (uasmon->msize >= MZ_HUGE) { 257. 	    dont_fall = "don't fit through."; 258. 	} else if (!next_to_u) { 259. 	    dont_fall = "are jerked back by your pet!"; 260. 	}  261.  	if (dont_fall) { 262. 	    You(dont_fall); 263. 	    /* hero didn't fall through, but any objects here might */ 264. 	    impact_drop((struct obj *)0, u.ux, u.uy, 0); 265. 	    if (!td) { 266. 		display_nhwindow(WIN_MESSAGE, FALSE); 267. 		pline_The("opening under you closes up."); 268. 	    }  269.  	    return; 270. 	}  271.   272.  	if(*u.ushops) shopdig(1); 273. 	if (Is_stronghold(&u.uz)) { 274. 	    find_hell(&dtmp); 275. 	} else { 276. 	    dtmp.dnum = u.uz.dnum; 277. 	    dtmp.dlevel = newlevel; 278. 	}  279.  	if (!td) 280. 	    Sprintf(msgbuf, "The hole in the %s above you closes up.",  281.  		    ceiling(u.ux,u.uy)); 282. 	schedule_goto(&dtmp, FALSE, TRUE, 0,  283.  		      (char *)0, !td ? msgbuf : (char *)0); 284. }  285.   286.  /* you've either stepped onto a statue trap's location 287.    or you've triggered a statue trap by searching next to it */ 288. void 289. activate_statue_trap(trap, x, y)  290. struct trap *trap; 291. xchar x, y;  292. { 293.  	struct monst *mtmp; 294. 	struct obj *otmp = sobj_at(STATUE, x, y); 295.  296.  	deltrap(trap); 297. 	if (otmp && (mtmp = makemon(&mons[otmp->corpsenm], x, y)) != 0) { 298. 	    delobj(otmp); 299. 	    /* mimic statue becomes seen mimic; other hiders won't be hidden */ 300. 	    if (mtmp->m_ap_type) seemimic(mtmp); 301. 	    else mtmp->mundetected = FALSE; 302. 	    if (x == u.ux && y == u.uy) 303. 		pline_The("statue comes to life!"); 304. 	    else 305. 		You("find %s posing as a statue.", a_monnam(mtmp)); 306. 	    /* avoid hiding under nothing */ 307. 	    if (x == u.ux && y == u.uy &&  308.  		    Upolyd && hides_under(uasmon) && !OBJ_AT(x, y)) 309. 		u.uundetected = 0; 310. 	}  311.  	if (Blind) feel_location(x, y); 312. 	else newsym(x, y); 313. }  314.   315.  void 316. dotrap(trap) 317. register struct trap *trap; 318. {  319.  	register int ttype = trap->ttyp; 320. 	register struct monst *mtmp; 321. 	register struct obj *otmp; 322. 	boolean already_seen = trap->tseen; 323.  324.  	nomul(0); 325. 	if(already_seen) { 326. 	    if ((Levitation || is_flyer(uasmon)) &&  327.  		    (ttype == PIT || ttype == SPIKED_PIT || ttype == HOLE || 328. 		    ttype == BEAR_TRAP)) { 329. 		You("%s over %s %s.",  330.  		    Levitation ? "float" : "fly",  331.  		    a_your[trap->madeby_u],  332.  		    defsyms[trap_to_defsym(ttype)].explanation); 333. 		return; 334. 	    }  335.  	    if(!Fumbling && ttype != MAGIC_PORTAL && ttype != ANTI_MAGIC &&  336.  		(!rn2(5) || 337. 	    ((ttype == PIT || ttype == SPIKED_PIT) && is_clinger(uasmon)))) { 338. 		You("escape %s %s.",  339.  		    (ttype == ARROW_TRAP && !trap->madeby_u) ? "an" :  340.  			a_your[trap->madeby_u],  341.  		    defsyms[trap_to_defsym(ttype)].explanation); 342. 		return; 343. 	    }  344.  	}  345.  		  346.  	switch(ttype) { 347. 	    case ARROW_TRAP: 348. 		seetrap(trap); 349. 		pline("An arrow shoots out at you!"); 350. 		otmp = mksobj(ARROW, TRUE, FALSE); 351. 		otmp->quan = 1L; 352. 		otmp->owt = weight(otmp); 353. 		if (thitu(8, dmgval(otmp, &youmonst), otmp, "arrow")) { 354. 		    obfree(otmp, (struct obj *)0); 355. 		} else { 356. 		    place_object(otmp, u.ux, u.uy); 357. 		    if (!Blind) otmp->dknown = 1; 358. 		    stackobj(otmp); 359. 		    newsym(u.ux, u.uy); 360. 		}  361.  		break; 362. 	    case DART_TRAP: 363. 		seetrap(trap); 364. 		pline("A little dart shoots out at you!"); 365. 		otmp = mksobj(DART, TRUE, FALSE); 366. 		otmp->quan = 1L; 367. 		otmp->owt = weight(otmp); 368. 		if (!rn2(6)) otmp->opoisoned = 1; 369. 		if (thitu(7, dmgval(otmp, &youmonst), otmp, "little dart")) { 370. 		    if (otmp->opoisoned) 371. 			poisoned("dart",A_CON,"poison dart",10); 372. 		    obfree(otmp, (struct obj *)0); 373. 		} else { 374. 		    place_object(otmp, u.ux, u.uy); 375. 		    if (!Blind) otmp->dknown = 1; 376. 		    stackobj(otmp); 377. 		    newsym(u.ux, u.uy); 378. 		}  379.  		break; 380. 	    case ROCKTRAP: 381. 		{  382.  		    int dmg = d(2,6); /* should be std ROCK dmg? */ 383.   384.  		    seetrap(trap); 385. 		    otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE); 386. 		    otmp->quan = 1L; 387. 		    otmp->owt = weight(otmp); 388.  389.      pline("A trap door in the %s opens and a rock falls on your %s!",  390.  			    ceiling(u.ux,u.uy),  391.  			    body_part(HEAD)); 392.  393.  		    if (uarmh) { 394. 			if(is_metallic(uarmh)) { 395. 			    pline("Fortunately, you are wearing a hard helmet."); 396. 			    dmg = 2; 397. 			} else if (flags.verbose) { 398. 			    Your("%s does not protect you.", xname(uarmh)); 399. 			}  400.  		    }  401.   402.  		    if (!Blind) otmp->dknown = 1; 403. 		    stackobj(otmp); 404. 		    newsym(u.ux,u.uy);	/* map the rock */ 405.  406.  		    losehp(dmg, "falling rock", KILLED_BY_AN); 407. 		    exercise(A_STR, FALSE); 408. 		}  409.  		break; 410.  411.  	    case SQKY_BOARD:	    /* stepped on a squeaky board */ 412. 		if (Levitation || is_flyer(uasmon)) { 413. 		    if (!Blind) { 414. 			seetrap(trap); 415. 			if (Hallucination) 416. 				You("notice a crease in the linoleum."); 417. 			else 418. 				You("notice a loose board below you."); 419. 		    }  420.  		} else { 421. 		    seetrap(trap); 422. 		    pline("A board beneath you squeaks loudly."); 423. 		    wake_nearby; 424. 		}  425.  		break; 426.  427.  	    case BEAR_TRAP: 428. 		if(Levitation || is_flyer(uasmon)) break; 429. 		seetrap(trap); 430. 		if(amorphous(uasmon) || is_whirly(uasmon) ||  431.  						    unsolid(uasmon)) { 432. 		    pline("%s bear trap closes harmlessly through you.",  433.  			    A_Your[trap->madeby_u]); 434. 		    break; 435. 		}  436.  		if(uasmon->msize <= MZ_SMALL) { 437. 		    pline("%s bear trap closes harmlessly over you.",  438.  			    A_Your[trap->madeby_u]); 439. 		    break; 440. 		}  441.  		u.utrap = rn1(4, 4); 442. 		u.utraptype = TT_BEARTRAP; 443. 		pline("%s bear trap closes on your %s!",  444.  			    A_Your[trap->madeby_u], body_part(FOOT)); 445. 		if(u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR) 446. 		    You("howl in anger!"); 447. 		exercise(A_DEX, FALSE); 448. 		break; 449.  450.  	    case SLP_GAS_TRAP: 451. 		seetrap(trap); 452. 		if(Sleep_resistance) { 453. 		    You("are enveloped in a cloud of gas!"); 454. 		    break; 455. 		}  456.  		pline("A cloud of gas puts you to sleep!"); 457. 		flags.soundok = 0; 458. 		fall_asleep(-rnd(25), TRUE); 459. 		afternmv = Hear_again; 460. 		break; 461.  462.  	    case RUST_TRAP: 463. 		seetrap(trap); 464. 		if (u.umonnum == PM_IRON_GOLEM) { 465. 		    pline("%s you!", A_gush_of_water_hits); 466. 		    You("are covered with rust!"); 467. 		    rehumanize; 468. 		    break; 469. 		} else if (u.umonnum == PM_GREMLIN && rn2(3)) { 470. 		    pline("%s you!", A_gush_of_water_hits); 471. 		    if ((mtmp = cloneu) != 0) { 472. 			mtmp->mhpmax = (u.mhmax /= 2); 473. 			You("multiply."); 474. 		    }  475.  		    break; 476. 		}  477.   478.  	    /* Unlike monsters, traps cannot aim their rust attacks at  479. * you, so instead of looping through and taking either the 480. 	     * first rustable one or the body, we take whatever we get, 481. 	     * even if it is not rustable. 482. 	     */  483.  		switch (rn2(5)) { 484. 		    case 0: 485. 			pline("%s you on the %s!", A_gush_of_water_hits,  486.  				    body_part(HEAD)); 487. 			(void) rust_dmg(uarmh, "helmet", 1, TRUE); 488. 			break; 489. 		    case 1: 490. 			pline("%s your left %s!", A_gush_of_water_hits,  491.  				    body_part(ARM)); 492. 			if (rust_dmg(uarms, "shield", 1, TRUE)) break; 493. 			if (uwep && bimanual(uwep)) 494. 			    goto two_hand; 495. 			/* Two goto statements in a row--aaarrrgggh! */ 496.  glovecheck:		    (void) rust_dmg(uarmg, "gauntlets", 1, TRUE); 497. 			/* Not "metal gauntlets" since it gets called 498. 			 * even if it's leather for the message 499. 			 */  500.  			break; 501. 		    case 2: 502. 			pline("%s your right %s!", A_gush_of_water_hits,  503.  				    body_part(ARM)); 504. two_hand:		    erode_weapon(FALSE); 505. 			goto glovecheck; 506. 		    default: 507. 			pline("%s you!", A_gush_of_water_hits); 508. 			for (otmp=invent; otmp; otmp = otmp->nobj) 509. 				    (void) snuff_lit(otmp); 510. 			if (uarmc) (void) rust_dmg(uarmc, "cloak", 1, TRUE); 511. 			else if (uarm) 512. 			    (void) rust_dmg(uarm, "armor", 1, TRUE); 513. #ifdef TOURIST 514. 			else if (uarmu) 515. 			    (void) rust_dmg(uarmu, "shirt", 1, TRUE); 516. #endif 517. 		}  518.  		break; 519.  520.  	    case FIRE_TRAP: 521. 		seetrap(trap); 522. 		dofiretrap((struct obj *)0); 523. 		break; 524.  525.  	    case PIT: 526. 	    case SPIKED_PIT: 527. 		if (Levitation || is_flyer(uasmon)) break; 528. 		seetrap(trap); 529. 		if (is_clinger(uasmon)) { 530. 		    if(trap->tseen) { 531. 			You("see %s %spit below you.", a_your[trap->madeby_u],  532.  			    ttype == SPIKED_PIT ? "spiked " : ""); 533. 		    } else { 534. 			pline("%s pit %sopens up under you!",  535.  			    A_Your[trap->madeby_u],  536.  			    ttype == SPIKED_PIT ? "full of spikes " : ""); 537. 			You("don't fall in!"); 538. 		    }  539.  		    break; 540. 		}  541.  		You("fall into %s pit!", a_your[trap->madeby_u]); 542. 		if (ttype == SPIKED_PIT) 543. 		    You("land on a set of sharp iron spikes!"); 544. 		if (!passes_walls(uasmon)) 545. 		    u.utrap = rn1(6,2); 546. 		u.utraptype = TT_PIT; 547. 		if (ttype == SPIKED_PIT) { 548. 		    losehp(rnd(10),"fell into a pit of iron spikes",  549.  			NO_KILLER_PREFIX); 550. 		    if (!rn2(6)) 551. 			poisoned("spikes", A_STR, "fall onto poison spikes", 8); 552. 		} else 553. 		    losehp(rnd(6),"fell into a pit", NO_KILLER_PREFIX); 554. 		if (Punished && !carried(uball)) { 555. 		    unplacebc; 556. 		    ballfall; 557. 		    placebc; 558. 		}  559.  		selftouch("Falling, you"); 560. 		vision_full_recalc = 1;	/* vision limits change */ 561. 		exercise(A_STR, FALSE); 562. 		exercise(A_DEX, FALSE); 563. 		break; 564. 	    case HOLE: 565. 	    case TRAPDOOR: 566. 		seetrap(trap); 567. 		if(!Can_fall_thru(&u.uz)) 568. 		    panic("Holes & trapdoors cannot exist on this level."); 569. 		fall_through(TRUE); 570. 		break; 571.  572.  	    case TELEP_TRAP: 573. 		seetrap(trap); 574. 		tele_trap(trap); 575. 		break; 576. 	    case LEVEL_TELEP: 577. 		seetrap(trap); 578. 		level_tele_trap(trap); 579. 		break; 580.  581.  	    case WEB: /* Our luckless player has stumbled into a web. */ 582.  		seetrap(trap); 583. 		if (amorphous(uasmon) || is_whirly(uasmon) ||  584.  						    unsolid(uasmon)) { 585. 		    if (acidic(uasmon) || u.umonnum == PM_GELATINOUS_CUBE ||  586.  			u.umonnum == PM_FIRE_ELEMENTAL) { 587. 			You("%s %s spider web!",  588.  			    (u.umonnum == PM_FIRE_ELEMENTAL) ? "burn" : "dissolve",  589.  			    a_your[trap->madeby_u]); 590. 			deltrap(trap); 591. 			newsym(u.ux,u.uy); 592. 			break; 593. 		    }  594.  		    You("flow through %s spider web.",  595.  			    a_your[trap->madeby_u]); 596. 		    break; 597. 		}  598.  		if (uasmon->mlet == S_SPIDER) { 599. 		    pline(trap->madeby_u ? "You take a walk on your web."  600.  					 : "There is a spider web here."); 601. 		    break; 602. 		}  603.  		You("%s into %s spider web!",  604.  		      Levitation ? (const char *)"float" :  605.  		      locomotion(uasmon, "stumble"),  606.  		      a_your[trap->madeby_u]); 607. 		u.utraptype = TT_WEB; 608.  609.  		/* Time stuck in the web depends on your strength. */ 610.  		{  611.  		    register int str = ACURR(A_STR); 612.  613.  		    if (str == 3) u.utrap = rn1(6,6); 614. 		    else if (str < 6) u.utrap = rn1(6,4); 615. 		    else if (str < 9) u.utrap = rn1(4,4); 616. 		    else if (str < 12) u.utrap = rn1(4,2); 617. 		    else if (str < 15) u.utrap = rn1(2,2); 618. 		    else if (str < 18) u.utrap = rnd(2); 619. 		    else if (str < 69) u.utrap = 1; 620. 		    else { 621. 			u.utrap = 0; 622. 			You("tear through %s web!", a_your[trap->madeby_u]); 623. 			deltrap(trap); 624. 			newsym(u.ux,u.uy);	/* get rid of trap symbol */ 625. 		    }  626.  		}  627.  		break; 628.  629.  	    case STATUE_TRAP: 630. 		activate_statue_trap(trap, u.ux, u.uy); 631. 		break; 632.  633.  	    case MAGIC_TRAP:	    /* A magic trap. */ 634.  		seetrap(trap); 635. 		if (!rn2(30)) { 636. 		    deltrap(trap); 637. 		    newsym(u.ux,u.uy);	/* update position */ 638. 		    You("are caught in a magical explosion!"); 639. 		    losehp(rnd(10), "magical explosion", KILLED_BY_AN); 640. 		    Your("body absorbs some of the magical energy!"); 641. 		    u.uen = (u.uenmax += 2); 642. 		} else domagictrap; 643. 		break; 644.  645.  	    case ANTI_MAGIC: 646. 		seetrap(trap); 647. 		if(Antimagic) { 648. 		    shieldeff(u.ux, u.uy); 649. 		    You_feel("momentarily lethargic."); 650. 		} else drain_en(rnd(u.ulevel) + 1); 651. 		break; 652.  653.  	    case POLY_TRAP: 654. 		seetrap(trap); 655. 		You("%s onto a polymorph trap!",  656.  		    Levitation ? (const char *)"float" :  657.  		    locomotion(uasmon, "step")); 658. 		if(Antimagic) { 659. 		    shieldeff(u.ux, u.uy); 660. 		    You_feel("momentarily different."); 661. 		    /* Trap did nothing; don't remove it --KAA */ 662. 		} else { 663. 		    deltrap(trap);	/* delete trap before polymorph */ 664. 		    newsym(u.ux,u.uy);	/* get rid of trap symbol */ 665. 		    You_feel("a change coming over you."); 666. 		    polyself; 667. 		}  668.  		break; 669.  670.  	    case LANDMINE: 671. 		if (Levitation || is_flyer(uasmon)) { 672. 		    if (!already_seen && rn2(3)) break; 673. 		    seetrap(trap); 674. 		    pline("%s %s in a pile of soil below you.",  675.  			    already_seen ? "There is" : "You discover",  676.  			    trap->madeby_u ? "the trigger of your mine" :  677.  					     "a trigger"); 678. 		    if (already_seen && rn2(3)) break; 679. 		    pline("KAABLAMM!!!  The air currents set %s%s off!",  680.  			    already_seen ? a_your[trap->madeby_u] : "",  681.  			    already_seen ? " land mine" : "it"); 682. 		} else { 683. 		    seetrap(trap); 684. 		    pline("KAABLAMM!!!  You triggered %s land mine!",  685.  					    a_your[trap->madeby_u]); 686. 		    set_wounded_legs(LEFT_SIDE, rn1(35, 41)); 687. 		    set_wounded_legs(RIGHT_SIDE, rn1(35, 41)); 688. 		    exercise(A_DEX, FALSE); 689. 		}  690.  		scatter(u.ux, u.uy, 4,  691.  			    MAY_DESTROY | MAY_HIT | MAY_FRACTURE | VIS_EFFECTS); 692. 		del_engr_at(u.ux, u.uy); 693. 		wake_nearto(u.ux, u.uy, 500); 694. 		trap->ttyp = PIT;		/* turn the mine into a pit */ 695. 		trap->madeby_u = FALSE;	/* resulting pit isn't yours */ 696. 		if (IS_DOOR(levl[u.ux][u.uy].typ)) 697. 		    levl[u.ux][u.uy].doormask = D_BROKEN; 698. 		newsym(u.ux,u.uy);		/* update trap symbol */ 699. 		losehp(rnd(16), "land mine", KILLED_BY_AN); 700. 		dotrap(trap);	/* fall recursively into the pit... */ 701.  		break; 702.  703.  	    case ROLLING_BOULDER_TRAP: 704. 		seetrap(trap); 705. 		pline("Click! You trigger a rolling boulder trap!"); 706. 		if(!launch_obj(BOULDER, trap->launch.x, trap->launch.y,  707. trap->launch2.x,trap->launch2.y, ROLL)) { 708. 		    deltrap(trap); 709. 		    newsym(u.ux,u.uy);	/* get rid of trap symbol */ 710. 		    pline("Fortunately for you, no boulder was released."); 711. 		}  712.  		break; 713.  714.  	    case MAGIC_PORTAL: 715. 		seetrap(trap); 716. 		domagicportal(trap); 717. 		break; 718.  719.  	    default: 720. 		seetrap(trap); 721. 		impossible("You hit a trap of type %u", trap->ttyp); 722. 	}  723.  }  724.  #endif /* OVLB */ 725. #ifdef OVL3 726.  727.  /*  728.   * Move obj from (x1,y1) to (x2,y2) 729.  *  730.   * Return 0 if no object was launched. 731.  *        1 if an object was launched and placed somewhere. 732.  *        2 if an object was launched, but used up. 733.  */  734.  int 735. launch_obj(otyp, x1, y1, x2, y2, style) 736. short otyp; 737. register int x1,y1,x2,y2; 738. int style; 739. {  740.  	register struct monst *mtmp; 741. 	register struct obj *otmp; 742. 	register int dx,dy; 743. 	struct obj *singleobj; 744. 	boolean used_up = FALSE; 745. 	boolean otherside = FALSE; 746. 	int dist; 747. 	int tmp; 748. 	int delaycnt = 0; 749.  750.  	otmp = sobj_at(otyp, x1, y1); 751. 	/* Try the other side too, for rolling boulder traps */ 752. 	if (!otmp && otyp == BOULDER) { 753. 		otherside = TRUE; 754. 		otmp = sobj_at(otyp, x2, y2); 755. 	}  756.  	if (!otmp) return 0; 757. 	if (otherside) {	/* swap 'em */ 758. 		int tx, ty; 759.  760.  		tx = x1; ty = y1; 761. 		x1 = x2; y1 = y2; 762. 		x2 = tx; y2 = ty; 763. 	}  764.   765.  	if (otmp->quan == 1L) { 766. 	    obj_extract_self(otmp); 767. 	    singleobj = otmp; 768. 	    otmp = (struct obj *) 0; 769. 	} else { 770. 	    singleobj = splitobj(otmp, otmp->quan - 1L); 771. 	    obj_extract_self(singleobj); 772. 	}  773.  	newsym(x1,y1); 774. 	/* in case you're using a pick-axe to chop the boulder that's being 775. 	   launched (perhaps a monster triggered it), destroy context so that 776. 	   next dig attempt never thinks you're resuming previous effort */ 777. 	if ((otyp == BOULDER || otyp == STATUE) &&  778.  	    singleobj->ox == digging.pos.x && singleobj->oy == digging.pos.y)  779. (void) memset((genericptr_t)&digging, 0, sizeof digging); 780.  781.  	dist = distmin(x1,y1,x2,y2); 782. 	bhitpos.x = x1; 783. 	bhitpos.y = y1; 784. 	dx = sgn(x2 - x1); 785. 	dy = sgn(y2 - y1); 786. 	switch (style) { 787. 	    case ROLL: 788. 			delaycnt = 2; 789. 			/* fall through */ 790. 	    default: 791. 			if (!delaycnt) delaycnt = 1; 792. 			if (!cansee(bhitpos.x,bhitpos.y)) curs_on_u; 793. 			tmp_at(DISP_FLASH, obj_to_glyph(singleobj)); 794. 			tmp_at(bhitpos.x, bhitpos.y); 795. 	}  796.  	while(dist-- > 0 && !used_up) { 797. 		tmp_at(bhitpos.x, bhitpos.y); 798. 		tmp = delaycnt; 799. 		while (tmp-- > 0) delay_output; 800. 		bhitpos.x += dx; 801. 		bhitpos.y += dy; 802.  803.  		if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) { 804. 			if (otyp == BOULDER && throws_rocks(mtmp->data)) { 805. 			    if (rn2(3)) { 806. 				pline("%s snatches the boulder.",  807.  					Monnam(mtmp)); 808. 				mpickobj(mtmp, singleobj); 809. 				used_up = TRUE; 810. 				break; 811. 			    }  812.  			}  813.  			if (ohitmon(mtmp,singleobj, 814. 					(style==ROLL) ? -1 : dist, FALSE)) { 815. 				used_up = TRUE; 816. 				break; 817. 			}  818.  		} else if (bhitpos.x==u.ux && bhitpos.y==u.uy) { 819. 			int hitvalu, hitu; 820. 			if (multi) nomul(0); 821. 			hitvalu = 9 + singleobj->spe; 822. 			hitu = thitu(hitvalu,  823.  				dmgval(singleobj, &youmonst),  824.  				singleobj,  825.  				xname(singleobj)); 826. 			if (hitu) stop_occupation; 827. 		}  828.  		if (style == ROLL) { 829. 		    if (down_gate(bhitpos.x, bhitpos.y) != -1) { 830. 		       if (ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)){ 831. 				used_up = TRUE; 832. 				break; 833. 			}  834.  		    }  835.  		    if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) { 836. 			used_up = TRUE; 837. 			break; 838. 		    }  839.  		}  840.  		if (otyp == BOULDER && closed_door(bhitpos.x,bhitpos.y)) { 841. 			if (cansee(bhitpos.x, bhitpos.y)) 842. 				pline_The("boulder crashes through a door."); 843. 			levl[bhitpos.x][bhitpos.y].doormask = D_BROKEN; 844. 		}  845.  	}  846.  	tmp_at(DISP_END, 0); 847. 	if (!used_up) { 848. 		place_object(singleobj, x2,y2); 849. 		newsym(x2,y2); 850. 		return 1; 851. 	} else 852. 		return 2; 853. }  854.  #endif /* OVL3 */ 855. #ifdef OVLB 856.  857.  void 858. seetrap(trap) 859. 	register struct trap *trap; 860. {  861.  	if(!trap->tseen) { 862. 	    trap->tseen = 1; 863. 	    newsym(trap->tx, trap->ty); 864. 	}  865.  }  866.   867.  #endif /* OVLB */ 868. #ifdef OVL3 869.  870.  STATIC_OVL int 871. mkroll_launch(ttmp, x, y, otyp, ocount) 872. struct trap *ttmp; 873. xchar x,y; 874. short otyp; 875. long ocount; 876. {  877.  	struct obj *otmp; 878. 	register int tmp; 879. 	schar dx,dy; 880. 	int distance; 881. 	coord cc; 882. 	coord bcc; 883. 	int trycount = 0; 884. 	boolean success = FALSE; 885. 	int mindist = 4; 886.  887.  	if (ttmp->ttyp == ROLLING_BOULDER_TRAP) mindist = 2; 888. 	distance = rn1(5,4);    /* 4..8 away */ 889. 	tmp = rn2(8);		/* randomly pick a direction to try first */ 890. 	while (distance >= mindist) { 891. 		dx = xdir[tmp]; 892. 		dy = ydir[tmp]; 893. 		cc.x = x; cc.y = y;  894. /* Prevent boulder from being placed on water */ 895. 		if (ttmp->ttyp == ROLLING_BOULDER_TRAP  896.  				&& is_pool(x+distance*dx,y+distance*dy)) 897. 			success = FALSE; 898. 		else success = isclearpath(&cc, distance, dx, dy); 899. 		if (ttmp->ttyp == ROLLING_BOULDER_TRAP) { 900. 			boolean success_otherway; 901. 			bcc.x = x; bcc.y = y;  902. success_otherway = isclearpath(&bcc, distance, 903.  						-(dx), -(dy)); 904. 			if (!success_otherway) success = FALSE; 905. 		}  906.  		if (success) break; 907. 		if (++tmp > 7) tmp = 0; 908. 		if ((++trycount % 8) == 0) --distance; 909. 	}  910.  	if (!success) { 911. 	    /* create the trap without any ammo, launch pt at trap location */ 912. 		cc.x = bcc.x = x;  913. cc.y = bcc.y = y; 914. } else { 915. 		otmp = mksobj(otyp, TRUE, FALSE); 916. 		otmp->quan = ocount; 917. 		otmp->owt = weight(otmp); 918. 		place_object(otmp, cc.x, cc.y); 919. 		stackobj(otmp); 920. 	}  921.  	ttmp->launch.x = cc.x;  922. ttmp->launch.y = cc.y; 923. if (ttmp->ttyp == ROLLING_BOULDER_TRAP) { 924. 		ttmp->launch2.x = bcc.x;  925. ttmp->launch2.y = bcc.y; 926. } else 927. 		ttmp->launch_otyp = otyp; 928. 	newsym(ttmp->launch.x, ttmp->launch.y); 929. 	return 1; 930. }  931.   932.  STATIC_OVL boolean 933. isclearpath(cc,distance,dx,dy) 934. coord *cc; 935. int distance; 936. schar dx,dy; 937. {  938.  	uchar typ; 939. 	xchar x, y;  940. 941. 	x = cc->x; 942. 	y = cc->y; 943. 	while (distance-- > 0) { 944. 		x += dx; 945. 		y += dy; 946. 		typ = levl[x][y].typ; 947. 		if (!isok(x,y) || !ZAP_POS(typ) || closed_door(x,y)) 948. 			return FALSE; 949. 	}  950.  	cc->x = x;  951. cc->y = y; 952. return TRUE; 953. }  954.  #endif /* OVL3 */ 955. #ifdef OVL1 956.  957.  int 958. mintrap(mtmp) 959. register struct monst *mtmp; 960. {  961.  	register struct trap *trap = t_at(mtmp->mx, mtmp->my); 962. 	boolean trapkilled = FALSE; 963. 	struct permonst *mptr = mtmp->data; 964. 	struct obj *otmp; 965.  966.  	if(!trap) { 967. 		mtmp->mtrapped = 0;	/* perhaps teleported? */ 968.  	} else if (mtmp->mtrapped) {	/* was in trap */ 969. 		if(!rn2(40)) { 970. 			if (sobj_at(BOULDER, mtmp->mx, mtmp->my) &&  971.  			    ((trap->ttyp == PIT) || 972. 			     (trap->ttyp == SPIKED_PIT))) { 973. 				if (!rn2(2)) { 974. 					mtmp->mtrapped = 0; 975. 					fill_pit(mtmp->mx, mtmp->my); 976. 				}  977.  			} else 978. 				mtmp->mtrapped = 0; 979. 		} else if (trap->ttyp == BEAR_TRAP && metallivorous(mptr)) { 980. 			if (canseemon(mtmp)) 981. 			    pline("%s eats a bear trap!", Monnam(mtmp)); 982. 			deltrap(trap); 983. 			mtmp->meating = 5; 984. 			mtmp->mtrapped = 0; 985. 		}  986.  	} else { 987. 	    register int tt = trap->ttyp; 988. 	    boolean in_sight, tear_web, see_it; 989.  990.  	    if ((mtmp->mtrapseen & (1 << (tt-1))) != 0 ||  991.  		    (tt == HOLE && !mindless(mtmp->data))) { 992. 		/* it has been in such a trap - perhaps it escapes */ 993. 		if(rn2(4)) return(0); 994. 	    } else { 995. 		mtmp->mtrapseen |= (1 << (tt-1)); 996. 	    }  997.  	    /* Monster is aggravated by being trapped by you. 998. 	       Recognizing who made the trap isn't completely 999. 	       unreasonable; everybody has their own style. */ 1000. 	    if (trap->madeby_u && rnl(5)) setmangry(mtmp); 1001. 1002. 	    /* bug? `in_sight' ought to be split to distinguish between 1003. 	      trap_in_sight and can_see_victim to handle invisible monsters */ 1004. 	   in_sight = canseemon(mtmp); 1005. 	   switch (tt) { 1006. 		case ARROW_TRAP: 1007. 			otmp = mksobj(ARROW, TRUE, FALSE); 1008. 			otmp->quan = 1L; 1009. 			otmp->owt = weight(otmp); 1010. 			if (in_sight) seetrap(trap); 1011. 			if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE; 1012. 			break; 1013. 		case DART_TRAP: 1014. 			otmp = mksobj(DART, TRUE, FALSE); 1015. 			otmp->quan = 1L; 1016. 			otmp->owt = weight(otmp); 1017. 			if (!rn2(6)) otmp->opoisoned = 1; 1018. 			if (in_sight) seetrap(trap); 1019. 			if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE; 1020. 			break; 1021. 		case ROCKTRAP: 1022. 			otmp = mksobj(ROCK, TRUE, FALSE); 1023. 			otmp->quan = 1L; 1024. 			otmp->owt = weight(otmp); 1025. 			if (in_sight) seetrap(trap); 1026. 			if (is_whirly(mptr) || passes_walls(mptr)) { 1027. 			   if (in_sight) 1028. 				pline("A rock falls harmlessly through %s.", 1029. 				      mon_nam(mtmp)); 1030. 			   else if (cansee(mtmp->mx, mtmp->my)) 1031. 				pline("A rock falls to the %s.", 1032. 				      surface(mtmp->mx, mtmp->my)); 1033. 			   place_object(otmp, mtmp->mx, mtmp->my); 1034. 			   stackobj(otmp); 1035. 			} else if (thitm(0, mtmp, otmp, d(2, 6))) 1036. 			   trapkilled = TRUE; 1037. 			break; 1038. 1039. 		case SQKY_BOARD: 1040. 			if(is_flyer(mptr)) break; 1041. 			/* stepped on a squeaky board */ 1042. 			if (in_sight) { 1043. 			   pline("A board beneath %s squeaks loudly.", mon_nam(mtmp)); 1044. 			   seetrap(trap); 1045. 			} else 1046. 			  You_hear("a distant squeak."); 1047. 			/* wake up nearby monsters */ 1048. 			wake_nearto(mtmp->mx, mtmp->my, 40); 1049. 			break; 1050. 1051. 		case BEAR_TRAP: 1052. 			if(mptr->msize > MZ_SMALL && 1053. 				!amorphous(mptr) && !is_flyer(mptr) &&  1054. 				!is_whirly(mptr) && !unsolid(mptr)) { 1055. 			   mtmp->mtrapped = 1; 1056. 			   if(in_sight) { 1057. 				pline("%s is caught in %s bear trap!", 1058. 				      Monnam(mtmp), a_your[trap->madeby_u]); 1059. 				seetrap(trap); 1060. 			   } else { 1061. 				if((mptr == &mons[PM_OWLBEAR] 1062. 				   || mptr == &mons[PM_BUGBEAR])  1063. 				   && flags.soundok) 1064. 				   You_hear("the roaring of an angry bear!"); 1065. 			   }  1066. 			}  1067. 			break; 1068. 1069. 		case SLP_GAS_TRAP: 1070. 			if (!resists_sleep(mtmp) && 1071. 				!mtmp->msleep && mtmp->mcanmove) { 1072. 			   mtmp->mcanmove = 0; 1073. 			   mtmp->mfrozen = rnd(25); 1074. 			   if (in_sight) { 1075. 				pline("%s suddenly falls asleep!", 1076. 				      Monnam(mtmp)); 1077. 				seetrap(trap); 1078. 			   }  1079. 			}  1080. 			break; 1081. 1082. 		case RUST_TRAP: 1083. 			if (in_sight) { 1084. 			   pline("%s %s!", A_gush_of_water_hits,  1085. 				  mon_nam(mtmp)); 1086. 			   seetrap(trap); 1087. 			} 1088. 			if (mptr == &mons[PM_IRON_GOLEM]) { 1089. 				if (in_sight) 1090. 				   pline("%s falls to pieces!", Monnam(mtmp)); 1091. 				else if(mtmp->mtame) 1092. 				   pline("May %s rust in peace.",  1093. 								mon_nam(mtmp)); 1094. 				mondied(mtmp); 1095. 				if (mtmp->mhp <= 0) 1096. 					trapkilled = TRUE; 1097. 			} else if (mptr == &mons[PM_GREMLIN] && rn2(3)) { 1098. 				struct monst *mtmp2 = clone_mon(mtmp); 1099. 1100. 				if (mtmp2) { 1101. 				   mtmp2->mhpmax = (mtmp->mhpmax /= 2); 1102. 				   if(in_sight) 1103. 					pline("%s multiplies.", Monnam(mtmp)); 1104. 				} 1105. 			}  1106. 			if (rn2(2)) 1107. 			   for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) 1108. 				(void) snuff_lit(otmp); 1109. 			break; 1110. 1111. 		case FIRE_TRAP: 1112. mfiretrap: 1113. 			see_it = cansee(mtmp->mx, mtmp->my); 1114. 			if (in_sight) 1115. 			   pline("A %s erupts from the %s under %s!",  1116. 				  tower_of_flame,  1117. 				  surface(mtmp->mx,mtmp->my), mon_nam(mtmp)); 1118. 			else if (see_it) /* evidently `mtmp' is invisible */ 1119. 			   You("see a %s erupt from the %s!",  1120. 				tower_of_flame, surface(mtmp->mx,mtmp->my)); 1121. 1122. 			if (resists_fire(mtmp)) { 1123. 			   if (in_sight) { 1124. 				shieldeff(mtmp->mx,mtmp->my); 1125. 				pline("%s is uninjured.", Monnam(mtmp)); 1126. 			   }  1127. 			} else { 1128. 			   int num = d(2,4); 1129. 1130. 			    if (thitm(0, mtmp, (struct obj *)0, num)) 1131. 				trapkilled = TRUE; 1132. 			   else 1133. 				/* we know mhp is at least `num' below mhpmax, 1134. 				  so no (mhp > mhpmax) check is needed here */ 1135. 				mtmp->mhpmax -= rn2(num + 1); 1136. 			} 1137. 			(void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); 1138. 			(void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); 1139. 			(void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); 1140. 			if (burn_floor_paper(mtmp->mx, mtmp->my, see_it) && 1141. 				!see_it && distu(mtmp->mx, mtmp->my) <= 3*3) 1142. 			   You("smell smoke."); 1143. 			if (is_ice(mtmp->mx,mtmp->my)) 1144. 			   melt_ice(mtmp->mx,mtmp->my); 1145. 			if (see_it) seetrap(trap); 1146. 			break; 1147. 1148. 		case PIT: 1149. 		case SPIKED_PIT: 1150. 			if ( !is_flyer(mptr) && 1151. 			     (!mtmp->wormno || (count_wsegs(mtmp) < 6)) &&  1152. 			     !is_clinger(mptr) ) { 1153. 				if (!passes_walls(mptr)) 1154. 				   mtmp->mtrapped = 1; 1155. 				if(in_sight) { 1156. 				   pline("%s falls into %s pit!",  1157. 					Monnam(mtmp), a_your[trap->madeby_u]); 1158. 				   seetrap(trap); 1159. 				} 1160. 				mselftouch(mtmp, "Falling, ", FALSE); 1161. 				if(mtmp->mhp <= 0 || 1162. 					thitm(0, mtmp, (struct obj *)0, 1163. 					 rnd((tt==PIT) ? 6 : 10))) 1164. 				   trapkilled = TRUE; 1165. 			} 1166. 			break; 1167. 		case HOLE: 1168. 		case TRAPDOOR: 1169. 			if(!Can_fall_thru(&u.uz)) 1170. 			 panic("Holes & trapdoors cannot exist on this level."); 1171. 1172. 			if (is_flyer(mptr) || mptr == &mons[PM_WUMPUS] ||  1173. 			    (mtmp->wormno && count_wsegs(mtmp) > 5) ||  1174. 			    mptr->msize >= MZ_HUGE) break; 1175. 			/* Fall through */ 1176. 		case LEVEL_TELEP: 1177. 		case MAGIC_PORTAL: 1178. 			{ 1179. 			    int mlev_res; 1180. 			   mlev_res = mlevel_tele_trap(mtmp, trap, in_sight); 1181. 			   if (mlev_res) return(mlev_res); 1182. 			} 1183. 			break; 1184. 1185. 		case TELEP_TRAP: 1186. 			mtele_trap(mtmp, trap, in_sight); 1187. 			break; 1188. 1189. 		case WEB: 1190. 			/* Monster in a web. */ 1191. 			if (mptr->mlet == S_SPIDER) break; 1192. 			if (amorphous(mptr) || is_whirly(mptr) || unsolid(mptr)){ 1193. 			   if(acidic(mptr) ||  1194. 			       mptr == &mons[PM_GELATINOUS_CUBE] ||  1195. 			       mptr == &mons[PM_FIRE_ELEMENTAL]) { 1196. 				if (in_sight) 1197. 				   pline("%s %s %s spider web!",  1198. 					  Monnam(mtmp),  1199. 					  (mptr == &mons[PM_FIRE_ELEMENTAL]) ?  1200. 					    "burns" : "dissolves",  1201. 					  a_your[trap->madeby_u]); 1202. 				deltrap(trap); 1203. 				newsym(mtmp->mx, mtmp->my); 1204. 				break; 1205. 			   }  1206. 			    if (in_sight) { 1207. 				pline("%s flows through %s spider web.", 1208. 				      Monnam(mtmp),  1209. 				      a_your[trap->madeby_u]); 1210. 				seetrap(trap); 1211. 			   }  1212. 			    break; 1213. 			} 1214. 			tear_web = FALSE; 1215. 			switch (monsndx(mptr)) { 1216. 			   case PM_OWLBEAR: /* Eric Backus */ 1217. 			   case PM_BUGBEAR: 1218. 				if (!in_sight) { 1219. 				   You_hear("the roaring of a confused bear!"); 1220. 				   mtmp->mtrapped = 1; 1221. 				   break; 1222. 				} 1223. 				/* fall though */ 1224. 			   default: 1225. 				if (mptr->mlet == S_GIANT || 1226. 				    (mptr->mlet == S_DRAGON && 1227. 					extra_nasty(mptr)) || /* excl. babies */ 1228. 				    (mtmp->wormno && count_wsegs(mtmp) > 5)) { 1229. 				   tear_web = TRUE; 1230. 				} else if (in_sight) { 1231. 				   pline("%s is caught in %s spider web.",  1232. 					  Monnam(mtmp),  1233. 					  a_your[trap->madeby_u]); 1234. 				   seetrap(trap); 1235. 				} 1236. 				mtmp->mtrapped = tear_web ? 0 : 1; 1237. 				break; 1238. 			   /* this list is fairly arbitrary; it deliberately 1239. 			      excludes wumpus & giant/ettin zombies/mummies */ 1240. 			   case PM_TITANOTHERE: 1241. 			   case PM_BALUCHITHERIUM: 1242. 			   case PM_PURPLE_WORM: 1243. 			   case PM_JABBERWOCK: 1244. 			   case PM_IRON_GOLEM: 1245. 			   case PM_BALROG: 1246. 			   case PM_KRAKEN: 1247. 				tear_web = TRUE; 1248. 				break; 1249. 			} 1250. 			if (tear_web) { 1251. 			   if (in_sight) 1252. 				pline("%s tears through %s spider web!", 1253. 				      Monnam(mtmp), a_your[trap->madeby_u]); 1254. 			   deltrap(trap); 1255. 			   newsym(mtmp->mx, mtmp->my); 1256. 			} 1257. 			break; 1258. 1259. 		case STATUE_TRAP: 1260. 			break; 1261. 1262. 		case MAGIC_TRAP: 1263. 			/* A magic trap. Monsters usually immune. */ 1264. 			if (!rn2(21)) goto mfiretrap; 1265. 			break; 1266. 		case ANTI_MAGIC: 1267. 			break; 1268. 1269. 		case LANDMINE: 1270. 			if(rn2(3)) 1271. 				break; /* monsters usually don't set it off */ 1272. 			if(is_flyer(mptr)) { 1273. 				boolean already_seen = trap->tseen; 1274. 				if (in_sight && !already_seen) { 1275. 	pline("A trigger appears in a pile of soil below %s.", mon_nam(mtmp)); 1276. 					seetrap(trap); 1277. 				} 1278. 				if (rn2(3)) break; 1279. 				if (in_sight) { 1280. 					newsym(mtmp->mx, mtmp->my); 1281. 					pline_The("air currents set %s off!", 1282. 					  already_seen ? "a land mine" : "it"); 1283. 				} 1284. 			} else if(in_sight) { 1285. 			   newsym(mtmp->mx, mtmp->my); 1286. 			   pline("KAABLAMM!!!  %s triggers %s land mine!",  1287. 				Monnam(mtmp), a_your[trap->madeby_u]); 1288. 			} 1289. 			if (!in_sight) 1290. 				pline("Kaablamm! You hear an explosion in the distance!"); 1291. 			scatter(mtmp->mx, mtmp->my, 4, 1292. 				MAY_DESTROY | MAY_HIT | MAY_FRACTURE | VIS_EFFECTS); 1293. 			del_engr_at(mtmp->mx, mtmp->my); 1294. 			if (IS_DOOR(levl[mtmp->mx][mtmp->my].typ)) 1295. 				levl[mtmp->mx][mtmp->my].doormask = D_BROKEN; 1296. 1297. 			trap->ttyp = PIT;       /* explosion creates a pit */ 1298. 			trap->madeby_u = FALSE; /* resulting pit isn't yours */ 1299. 			if(thitm(0, mtmp, (struct obj *)0, rnd(16))) 1300. 				trapkilled = TRUE; 1301. 			else { 1302. 				/* monsters recursively fall into new pit */ 1303. 				if (mintrap(mtmp) == 2) trapkilled=TRUE; 1304. 			} 1305. 			wake_nearto(mtmp->mx, mtmp->my, 500); 1306. 			if (unconscious) { 1307. 				multi = -1; 1308. 				nomovemsg="The explosion awakens you!"; 1309. 			} 1310. 			break; 1311. 1312. 		case POLY_TRAP: 1313. 		   if (resists_magm(mtmp)) { 1314. 			shieldeff(mtmp->mx, mtmp->my); 1315. 		   } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) { 1316. 			(void) newcham(mtmp, (struct permonst *)0); 1317. 			if (in_sight) seetrap(trap); 1318. 		   }  1319. 		    break; 1320. 1321. 		case ROLLING_BOULDER_TRAP: 1322. 		   newsym(mtmp->mx,mtmp->my); 1323. 		   if (in_sight) 1324. 			pline("Click! %s triggers %s.", Monnam(mtmp), 1325. 				trap->tseen ?  1326. 				"a rolling boulder trap" :  1327. 				something); 1328. 		   if (launch_obj(BOULDER, trap->launch.x, trap->launch.y,  1329. trap->launch2.x, trap->launch2.y, ROLL)) { 1330. 			if (in_sight) trap->tseen = TRUE; 1331. 			else You_hear(Hallucination ? 1332. 					"someone bowling." :  1333. 					"rumbling in the distance."); 1334. 			if (mtmp->mhp <= 0) trapkilled = TRUE; 1335. 		   } else { 1336. 			deltrap(trap); 1337. 			newsym(mtmp->mx,mtmp->my); 1338. 		   }  1339. 		    break; 1340. 1341. 		default: 1342. 			impossible("Some monster encountered a strange trap of type %d.", tt); 1343. 	   }  1344. 	}  1345. 	if(trapkilled) return 2; 1346. 	return mtmp->mtrapped; 1347. } 1348.  1349. #endif /* OVL1 */ 1350. #ifdef OVLB 1351. 1352. /* Combine cockatrice checks into single functions to avoid repeating code. */ 1353. void 1354. instapetrify(str) 1355. const char *str; 1356. { 1357. 	if (resists_ston(&youmonst)) return; 1358. 	if (poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)) 1359. 	   return; 1360. 	You("turn to stone..."); 1361. 	killer_format = KILLED_BY; 1362. 	killer = str; 1363. 	done(STONING); 1364. } 1365.  1366. void 1367. minstapetrify(mon,byplayer) 1368. struct monst *mon; 1369. boolean byplayer; 1370. { 1371. 	if (resists_ston(mon)) return; 1372. 	if (cansee(mon->mx, mon->my)) 1373. 		pline("%s turns to stone.", Monnam(mon)); 1374. 	if (poly_when_stoned(mon->data)) { 1375. 		mon_to_stone(mon); 1376. 		return; 1377. 	} 1378. 	if (byplayer) { 1379. 		stoned = TRUE; 1380. 		xkilled(mon,0); 1381. 	} else monstone(mon); 1382. } 1383.  1384. void 1385. selftouch(arg) 1386. const char *arg; 1387. { 1388. 	if (uwep && uwep->otyp == CORPSE && uwep->corpsenm == PM_COCKATRICE) { 1389. 		pline("%s touch the cockatrice corpse.", arg); 1390. 		instapetrify("cockatrice corpse"); 1391. 	} 1392. }  1393.  1394. void 1395. mselftouch(mon,arg,byplayer) 1396. struct monst *mon; 1397. const char *arg; 1398. boolean byplayer; 1399. { 1400. 	struct obj *mwep = MON_WEP(mon); 1401. 1402. 	if (mwep && mwep->otyp == CORPSE && mwep->corpsenm == PM_COCKATRICE) { 1403. 		if (cansee(mon->mx, mon->my)) { 1404. 			pline("%s%s touches the cockatrice corpse.", 1405. 			    arg ? arg : "", arg ? mon_nam(mon) : Monnam(mon)); 1406. 		} 1407. 		minstapetrify(mon, byplayer); 1408. 	} 1409. }  1410.  1411. void 1412. float_up 1413. { 1414. 	if(u.utrap) { 1415. 		if(u.utraptype == TT_PIT) { 1416. 			u.utrap = 0; 1417. 			You("float up, out of the pit!"); 1418. 			vision_full_recalc = 1;	/* vision limits change */ 1419. 			fill_pit(u.ux, u.uy); 1420. 		} else if (u.utraptype == TT_INFLOOR) { 1421. 			Your("body pulls upward, but your %s are still stuck.", 1422. 			     makeplural(body_part(LEG))); 1423. 		} else { 1424. 			You("float up, only your %s is still stuck.", 1425. 				body_part(LEG)); 1426. 		} 1427. 	}  1428. 	else if(Is_waterlevel(&u.uz)) 1429. 		pline("It feels as though you'd lost some weight."); 1430. 	else if(u.uinwater) 1431. 		spoteffects; 1432. 	else if(u.uswallow) 1433. 		You(is_animal(u.ustuck->data) ? 1434. 			"float away from the %s."  :  1435. 			"spiral up into %s.",  1436. 		    is_animal(u.ustuck->data) ?  1437. 			surface(u.ux, u.uy) :  1438. 			mon_nam(u.ustuck)); 1439. 	else if (Hallucination) 1440. 		pline("Up, up, and awaaaay! You're walking on air!"); 1441. 	else if(Is_airlevel(&u.uz)) 1442. 		You("gain control over your movements."); 1443. 	else 1444. 		You("start to float in the air!"); 1445. } 1446.  1447. void 1448. fill_pit(x, y) 1449. int x, y; 1450. { 1451. 	struct obj *otmp; 1452. 	struct trap *t; 1453. 1454. 	if ((t = t_at(x, y)) &&  1455. 	    ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT)) &&  1456. 	    (otmp = sobj_at(BOULDER, x, y))) { 1457. 		obj_extract_self(otmp); 1458. 		(void) flooreffects(otmp, x, y, "settle"); 1459. 	} 1460. }  1461.  1462. int 1463. float_down(override_mask) 1464. long override_mask;	/* might cancel timeout */ 1465. { 1466. 	register struct trap *trap = (struct trap *)0; 1467. 	d_level current_dungeon_level; 1468. 	boolean no_msg = FALSE; 1469. 1470. 	HLevitation &= ~override_mask; 1471. 	if(Levitation) return(0); /* maybe another ring/potion/boots */ 1472. 1473. 	if (Punished && !carried(uball) &&  1474. 	    (is_pool(uball->ox, uball->oy) || 1475. 	    ((trap = t_at(uball->ox, uball->oy)) &&  1476. 	      ((trap->ttyp == PIT) || (trap->ttyp == SPIKED_PIT) || 1477. 	      (trap->ttyp == TRAPDOOR) || (trap->ttyp == HOLE))))) { 1478. 			u.ux0 = u.ux; 1479. 			u.uy0 = u.uy; 1480. 			u.ux = uball->ox; 1481. 			u.uy = uball->oy; 1482. 			movobj(uchain, uball->ox, uball->oy); 1483. 			newsym(u.ux0, u.uy0); 1484. 			vision_full_recalc = 1;	/* in case the hero moved. */ 1485. 	}  1486. 	/* check for falling into pool - added by GAN 10/20/86 */ 1487. 	if(!is_flyer(uasmon)) { 1488. 		/* kludge alert: 1489. 		 * drown and lava_effects print various messages almost 1490. 		 * every time they're called which conflict with the "fall 1491. 		 * into" message below. Thus, we want to avoid printing 1492. 		 * confusing, duplicate or out-of-order messages. 1493. 		 * Use knowledge of the two routines as a hack -- this 1494. 		 * should really handled differently -dlc 1495. 		 */ 1496. 		if(is_pool(u.ux,u.uy) && !Wwalking && !u.uinwater) 1497. 			no_msg = drown; 1498. 1499. 		if(is_lava(u.ux,u.uy)) { 1500. 			(void) lava_effects; 1501. 			no_msg = TRUE; 1502. 		} 1503. 	}  1504. 	if (!trap) { 1505. 		if(Is_airlevel(&u.uz)) 1506. 			You("begin to tumble in place."); 1507. 		else if (Is_waterlevel(&u.uz) && !no_msg) 1508. 			You_feel("heavier."); 1509. 		/* u.uinwater msgs already in spoteffects/drown */ 1510. 		else if (!u.uinwater && !no_msg) { 1511. 			if (Hallucination) 1512. 				pline("Bummer! You've %s.",  1513. 				      is_pool(u.ux,u.uy) ?  1514. 					"splashed down" : "hit the ground"); 1515. 			else 1516. 				You("float gently to the %s.", 1517. 				    surface(u.ux, u.uy)); 1518. 		} 1519. 		trap = t_at(u.ux,u.uy); 1520. 	} 1521.  1522. 	/* can't rely on u.uz0 for detecting trap door-induced level change; 1523. 	  it gets changed to reflect the new level before we can check it */ 1524. 	assign_level(&current_dungeon_level, &u.uz); 1525. 1526. 	if(trap) 1527. 		switch(trap->ttyp) { 1528. 		case STATUE_TRAP: 1529. 			break; 1530. 		case HOLE: 1531. 		case TRAPDOOR: 1532. 			if(!Can_fall_thru(&u.uz) || u.ustuck) 1533. 				break; 1534. 			/* fall into next case */ 1535. 		default: 1536. 			dotrap(trap); 1537. 	} 1538.  1539. 	if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !u.uswallow &&  1540. 		/* falling through trap door calls goto_level,  1541. 		   and goto_level does its own pickup call */  1542. 		on_level(&u.uz, &current_dungeon_level)) 1543. 	   pickup(1); 1544. 	return 1; 1545. } 1546.  1547. STATIC_OVL void 1548. dofiretrap(box) 1549. struct obj *box;	/* null for floor trap */ 1550. { 1551. 	boolean see_it = !Blind; 1552. 	int num; 1553. 1554. 	if ((box && !carried(box)) ? is_pool(box->ox, box->oy) : Underwater) { 1555. 	   pline("A cascade of steamy bubbles erupts from %s!",  1556. 		    the(box ? xname(box) : surface(u.ux,u.uy))); 1557. 	   if (Fire_resistance) You("are uninjured."); 1558. 	   else losehp(rnd(3), "boiling water", KILLED_BY); 1559. 	   return; 1560. 	} 1561. 	pline("A %s %s from %s!", tower_of_flame,  1562. 	      box ? "bursts" : "erupts",  1563. 	      the(box ? xname(box) : surface(u.ux,u.uy))); 1564. 	if (Fire_resistance) { 1565. 	   shieldeff(u.ux, u.uy); 1566. 	   num = rn2(2); 1567. 	} else { 1568. 	   num = d(2,4); 1569. 	   if (u.uhpmax > u.ulevel) 1570. 		u.uhpmax -= rn2(min(u.uhpmax,num + 1)), flags.botl = 1; 1571. 	} 1572. 	if (!num) 1573. 	   You("are uninjured."); 1574. 	else 1575. 	   losehp(num, tower_of_flame, KILLED_BY_AN); 1576. 1577. 	if (burnarmor || rn2(3)) { 1578. 	   destroy_item(SCROLL_CLASS, AD_FIRE); 1579. 	   destroy_item(SPBOOK_CLASS, AD_FIRE); 1580. 	   destroy_item(POTION_CLASS, AD_FIRE); 1581. 	} 1582. 	if (!box && burn_floor_paper(u.ux, u.uy, see_it) && !see_it) 1583. 	   You("smell paper burning."); 1584. 	if (is_ice(u.ux, u.uy)) 1585. 	   melt_ice(u.ux, u.uy); 1586. } 1587.  1588. STATIC_OVL void 1589. domagictrap 1590. { 1591. 	register int fate = rnd(20); 1592. 1593. 	/* What happened to the poor sucker? */ 1594.  1595. 	if (fate < 10) { 1596. 1597. 	  /* Most of the time, it creates some monsters. */ 1598. 	  register int cnt = rnd(4); 1599. 1600. 	  /* below checks for blindness added by GAN 10/30/86 */ 1601. 	 if (!Blind)  { 1602. 		You("are momentarily blinded by a flash of light!"); 1603. 		make_blinded((long)rn1(5,10),FALSE); 1604. 	 }  else 1605. 		You_hear("a deafening roar!"); 1606. 	 while(cnt--) 1607. 		(void) makemon((struct permonst *) 0, u.ux, u.uy); 1608. 	} 1609. 	else 1610. 	 switch (fate) { 1611. 1612. 	     case 10: 1613. 	    case 11: 1614. 		     /* sometimes nothing happens */ 1615. 			break; 1616. 	    case 12: /* a flash of fire */ 1617. 			dofiretrap((struct obj *)0); 1618. 			break; 1619. 1620. 	     /* odd feelings */ 1621. 	    case 13:	pline("A shiver runs up and down your %s!",  1622. 			      body_part(SPINE)); 1623. 			break; 1624. 	    case 14:	You_hear(Hallucination ?  1625. 				"the moon howling at you." :  1626. 				"distant howling."); 1627. 			break; 1628. 	    case 15:	if (on_level(&u.uz, &qstart_level)) 1629. 			   You_feel("%slike the prodigal son.",  1630. 			      (flags.female || (Upolyd && is_neuter(uasmon))) ?  1631. 				     "oddly " : ""); 1632. 			else 1633. 			   You("suddenly yearn for %s.",  1634. 				Hallucination ? "Cleveland" :  1635. 			    (In_quest(&u.uz) || at_dgn_entrance("The Quest")) ?  1636. 						"your nearby homeland" :  1637. 						"your distant homeland"); 1638. 			break; 1639. 	    case 16:   Your("pack shakes violently!"); 1640. 			break; 1641. 	    case 17:	You(Hallucination ?  1642. 				"smell hamburgers." :  1643. 				"smell charred flesh."); 1644. 			break; 1645. 	    case 18:	You_feel("tired."); 1646. 			break; 1647. 1648. 	     /* very occasionally something nice happens. */ 1649.  1650. 	     case 19: 1651. 		   /* tame nearby monsters */ 1652. 		  {   register int i,j; 1653. 		      register struct monst *mtmp; 1654. 1655. 		       (void) adjattrib(A_CHA,1,FALSE); 1656. 		      for(i = -1; i <= 1; i++) for(j = -1; j <= 1; j++) { 1657. 			  if(!isok(u.ux+i, u.uy+j)) continue; 1658. 			  mtmp = m_at(u.ux+i, u.uy+j); 1659. 			  if(mtmp) 1660. 			      (void) tamedog(mtmp, (struct obj *)0); 1661. 		      }  1662. 		       break; 1663. 		  }  1664.  1665. 	     case 20: 1666. 		   /* uncurse stuff */ 1667. 		  {  register struct obj *obj; 1668. 1669. 			/* below plines added by GAN 10/30/86 */ 1670. 			You_feel(Hallucination ? 1671. 				"in touch with the Universal Oneness." :  1672. 				"like someone is helping you."); 1673. 			for(obj = invent; obj ; obj = obj->nobj) 1674. 			      if(obj->owornmask || obj->otyp == LOADSTONE) 1675. 					uncurse(obj); 1676. 		      if(Punished) unpunish; 1677. 		      break; 1678. 		  }  1679. 	     default: break; 1680. 	 }  1681. }  1682.  1683. void 1684. water_damage(obj, force, here) 1685. register struct obj *obj; 1686. register boolean force, here; 1687. { 1688. 	/* Scrolls, spellbooks, potions, weapons and 1689. 	  pieces of armor may get affected by the water */ 1690. 	for (obj; obj = (here ? obj->nexthere : obj->nobj)) { 1691. 1692. 		(void) snuff_lit(obj); 1693. 1694. 		if(obj->greased) { 1695. 			if (force || !rn2(2)) obj->greased = 0; 1696. 		} else if(Is_container(obj) && !Is_box(obj) && 1697. 			(obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) { 1698. 			water_damage(obj->cobj, force, FALSE); 1699. 		} else if (!force && (Luck + 5) > rn2(20)) { 1700. 			/* chance per item of sustaining damage: 1701. 			 *	max luck (full moon):	 5% 1702. 			 *	max luck (elsewhen):	10% 1703. 			 *	avg luck (Luck==0):	75% 1704. 			 *	awful luck (Luck<-4): 100% 1705. 			 */ 1706. 			continue; 1707. 		} else if (obj->oclass == SCROLL_CLASS) { 1708. #ifdef MAIL 1709. 		   if (obj->otyp != SCR_MAIL) 1710. #endif 1711. 			obj->otyp = SCR_BLANK_PAPER; 1712. 			obj->spe = 0; 1713. 		} else if (obj->oclass == SPBOOK_CLASS) { 1714. 			if (obj->otyp == SPE_BOOK_OF_THE_DEAD) 1715. 				pline("Steam rises from %s.", the(xname(obj))); 1716. 			else obj->otyp = SPE_BLANK_PAPER; 1717. 		} else if (obj->oclass == POTION_CLASS) { 1718. 			if (obj->odiluted) { 1719. 				obj->otyp = POT_WATER; 1720. 				obj->blessed = obj->cursed = 0; 1721. 				obj->odiluted = 0; 1722. 			} else if (obj->otyp != POT_WATER || 1723. 				   obj->blessed || obj->cursed) 1724. 				obj->odiluted++; 1725. 		} else if (is_rustprone(obj) && obj->oeroded < MAX_ERODE && 1726. 			  !(obj->oerodeproof || (obj->blessed && !rnl(4)))) { 1727. 			/* all metal stuff and armor except (body armor 1728. 			   protected by oilskin cloak) */ 1729. 			if(obj->oclass != ARMOR_CLASS || obj != uarm || 1730. 			   !uarmc || uarmc->otyp != OILSKIN_CLOAK ||  1731. 			   (uarmc->cursed && !rn2(3))) 1732. 				obj->oeroded++; 1733. 		} 1734. 	}  1735. }  1736.  1737. /*  1738.  * This function is potentially expensive - rolling 1739. * inventory list multiple times. Luckily it's seldom needed. 1740. * Returns TRUE if disrobing made player unencumbered enough to  1741. * crawl out of the current predicament. 1742. */  1743. STATIC_OVL boolean 1744. emergency_disrobe(lostsome) 1745. boolean *lostsome; 1746. { 1747. 	int invc = inv_cnt; 1748. 1749. 	while (near_capacity > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) { 1750. 		register struct obj *obj, *otmp = (struct obj *)0; 1751. 		register int i = rn2(invc); 1752. 1753. 		for (obj = invent; obj; obj = obj->nobj) { 1754. 			/* 1755. 			 * Undroppables are: body armor, boots, gloves, 1756. 			 * amulets, and rings because of the time and effort 1757. 			 * in removing them + loadstone and other cursed stuff 1758. 			 * for obvious reasons. 1759. 			 */ 1760. 			if (!((obj->otyp == LOADSTONE && obj->cursed) || 1761. 			     obj == uamul || obj == uleft || obj == uright || 1762. 			     obj == ublindf || obj == uarm || obj == uarmc || 1763. 			     obj == uarmg || obj == uarmf || 1764. #ifdef TOURIST 1765. 			     obj == uarmu || 1766. #endif 1767. 			     (obj->cursed && (obj == uarmh || obj == uarms)) || 1768. 			     welded(obj))) 1769. 				otmp = obj; 1770. 			/* reached the mark and found some stuff to drop? */ 1771. 			if (--i < 0 && otmp) break; 1772. 1773. 			/* else continue */ 1774. 		} 1775.  1776. 		/* nothing to drop and still overweight */ 1777. 		if (!otmp) return(FALSE); 1778. 1779. 		if (otmp == uarmh) (void) Helmet_off; 1780. 		else if (otmp == uarms) (void) Shield_off; 1781. 		else if (otmp == uwep) setuwep((struct obj *)0); 1782. 		*lostsome = TRUE; 1783. 		dropx(otmp); 1784. 		invc--; 1785. 	} 1786. 	return(TRUE); 1787. } 1788.  1789. /*  1790.  *  return(TRUE) == player relocated 1791. */  1792. boolean 1793. drown 1794. { 1795. 	boolean inpool_ok = FALSE, crawl_ok; 1796. 	int i, x, y; 1797. 1798. 	/* happily wading in the same contiguous pool */ 1799. 	if (u.uinwater && is_pool(u.ux-u.dx,u.uy-u.dy) && 1800. 	    (is_swimmer(uasmon) || Amphibious)) { 1801. 		/* water effects on objects every now and then */ 1802. 		if (!rn2(5)) inpool_ok = TRUE; 1803. 		else return(FALSE); 1804. 	} 1805.  1806. 	if (!u.uinwater) { 1807. 	   You("%s into the water%c",  1808. 		Is_waterlevel(&u.uz) ? "plunge" : "fall",  1809. 		Amphibious ? '.' : '!'); 1810. 	   if(!is_swimmer(uasmon)) 1811. 		if (!Is_waterlevel(&u.uz)) 1812. 		   You("sink like %s.",  1813. 			Hallucination ? "the Titanic" : "a rock"); 1814. 	} 1815.  1816. 	water_damage(invent, FALSE, FALSE); 1817. 1818. 	if(u.umonnum == PM_GREMLIN && rn2(3)) { 1819. 		struct monst *mtmp; 1820. 		if ((mtmp = cloneu) != 0) { 1821. 			mtmp->mhpmax = (u.mhmax /= 2); 1822. 			You("multiply."); 1823. 		} 1824. 	}  1825. 	if (inpool_ok) return(FALSE); 1826. 1827. 	if ((i = number_leashed) > 0) { 1828. 		pline_The("leash%s slip%s loose.", 1829. 			(i > 1) ? "es" : "",  1830. 			(i > 1) ? "" : "s"); 1831. 		unleash_all; 1832. 	} 1833.  1834. 	if (Amphibious || is_swimmer(uasmon)) { 1835. 		if (Amphibious) { 1836. 			if (flags.verbose) 1837. 				pline("But you aren't drowning."); 1838. 			if (!Is_waterlevel(&u.uz)) 1839. 				if (Hallucination) 1840. 					Your("keel hits the bottom."); 1841. 				else 1842. 					You("touch bottom."); 1843. 		} 1844. 		if (Punished) { 1845. 			unplacebc; 1846. 			placebc; 1847. 		} 1848. 		vision_recalc(2);	/* unsee old position */ 1849. 		u.uinwater = 1; 1850. 		under_water(1); 1851. 		vision_full_recalc = 1; 1852. 		return(FALSE); 1853. 	} 1854. 	if((Teleportation || can_teleport(uasmon)) &&  1855. 	   (Teleport_control || rn2(3) < Luck+2)) { 1856. 		You("attempt a teleport spell.");	/* utcsri!carroll */ 1857. 		(void) dotele; 1858. 		if(!is_pool(u.ux,u.uy)) 1859. 			return(TRUE); 1860. 	} 1861. 	crawl_ok = FALSE; 1862. 	/* look around for a place to crawl to */ 1863. 	for (i = 0; i < 100; i++) { 1864. 		x = rn1(3,u.ux - 1); 1865. 		y = rn1(3,u.uy - 1); 1866. 		if (goodpos(x, y, (struct monst *)0, &playermon) 1867. 			|| goodpos(x, y, (struct monst *)0, uasmon)) { 1868. 			crawl_ok = TRUE; 1869. 			goto crawl; 1870. 		} 1871. 	}  1872. 	/* one more scan */ 1873. 	for (x = u.ux - 1; x <= u.ux + 1; x++) 1874. 		for (y = u.uy - 1; y <= u.uy + 1; y++) 1875. 			if (goodpos(x, y, (struct monst *)0, &playermon) 1876. 				|| goodpos(x, y, (struct monst *)0, uasmon)) { 1877. 				crawl_ok = TRUE; 1878. 				goto crawl; 1879. 			} 1880. crawl:; 1881. 	if (crawl_ok) { 1882. 		boolean lost = FALSE; 1883. 		/* time to do some strip-tease... */ 1884. 		boolean succ = Is_waterlevel(&u.uz) ? TRUE : 1885. 				emergency_disrobe(&lost); 1886. 1887. 		You("try to crawl out of the water."); 1888. 		if (lost) 1889. 			You("dump some of your gear to lose weight..."); 1890. 		if (succ) { 1891. 			pline("Pheew! That was close."); 1892. 			teleds(x,y); 1893. 			return(TRUE); 1894. 		} 1895. 		/* still too much weight */ 1896. 		pline("But in vain."); 1897. 	} 1898. 	u.uinwater = 1; 1899. 	You("drown."); 1900. 	killer_format = KILLED_BY_AN; 1901. 	killer = (levl[u.ux][u.uy].typ == POOL || Is_medusa_level(&u.uz)) ? 1902. 	   "pool of water" : "moat"; 1903. 	done(DROWNING); 1904. 	/* oops, we're still alive. better get out of the water. */ 1905. 	while (!safe_teleds) { 1906. 		pline("You're still drowning."); 1907. 		done(DROWNING); 1908. 	} 1909. 	u.uinwater = 0; 1910. 	You("find yourself back %s.", Is_waterlevel(&u.uz) ? 1911. 		"in an air bubble" : "on land"); 1912. 	return(TRUE); 1913. } 1914.  1915. void 1916. drain_en(n) 1917. register int n; 1918. { 1919. 	if (!u.uenmax) return; 1920. 	You_feel("your magical energy drain away!"); 1921. 	u.uen -= n; 1922. if(u.uen < 0) { 1923. 		u.uenmax += u.uen; 1924. 		if(u.uenmax < 0) u.uenmax = 0; 1925. 		u.uen = 0; 1926. 	} 1927. 	flags.botl = 1; 1928. } 1929.  1930. int 1931. dountrap	/* disarm a trap */ 1932. { 1933. 	if (near_capacity >= HVY_ENCUMBER) { 1934. 	   pline("You're too strained to do that."); 1935. 	   return 0; 1936. 	} 1937. 	if (nohands(uasmon) || !uasmon->mmove) { 1938. 	   pline("And just how do you expect to do that?"); 1939. 	   return 0; 1940. 	} else if (u.ustuck && sticks(uasmon)) { 1941. 	   pline("You'll have to let go of %s first.", mon_nam(u.ustuck)); 1942. 	   return 0; 1943. 	} 1944. 	if (u.ustuck || (welded(uwep) && bimanual(uwep))) { 1945. 	   Your("%s seem to be too busy for that.",  1946. 		 makeplural(body_part(HAND))); 1947. 	   return 0; 1948. 	} 1949. 	return untrap(FALSE); 1950. } 1951. #endif /* OVLB */ 1952. #ifdef OVL2 1953. 1954. /* Probability of disabling a trap. Helge Hafting */ 1955. STATIC_OVL int 1956. untrap_prob(ttmp) 1957. struct trap *ttmp; 1958. { 1959. 	int chance = 3; 1960. 1961. 	if (Confusion || Hallucination) chance++; 1962. 	if (Blind) chance++; 1963. 	if (Stunned) chance += 2; 1964. 	if (Fumbling) chance *= 2; 1965. 	/* Your own traps are better known than others. */ 1966. 	if (ttmp && ttmp->madeby_u) chance--; 1967. 	if (Role_is('R')) { 1968. 	   if (rn2(2 * MAXULEV) < u.ulevel) chance--; 1969. 	   if (u.uhave.questart && chance > 1) chance--; 1970. 	} 1971. 	return rn2(chance); 1972. } 1973.  1974. /* Replace trap with object(s). Helge Hafting */ 1975. STATIC_OVL void 1976. cnv_trap_obj(otyp, cnt, ttmp) 1977. int otyp; 1978. int cnt; 1979. struct trap *ttmp; 1980. { 1981. 	struct obj *otmp = mksobj(otyp, TRUE, FALSE); 1982. 	otmp->quan=cnt; 1983. 	otmp->owt = weight(otmp); 1984. 	place_object(otmp, ttmp->tx, ttmp->ty); 1985. 	/* Sell your own traps only... */ 1986. 	if (ttmp->madeby_u) sellobj(otmp, ttmp->tx, ttmp->ty); 1987. 	stackobj(otmp); 1988. 	newsym(ttmp->tx, ttmp->ty); 1989. 	deltrap(ttmp); 1990. } 1991.  1992. /* while attempting to disarm an adjacent trap, we've fallen into it */ 1993. STATIC_OVL void 1994. move_into_trap(ttmp) 1995. struct trap *ttmp; 1996. { 1997. 	int bc; 1998. 	xchar x = ttmp->tx, y = ttmp->ty, bx, by, cx, cy; 1999. 	boolean unused; 2000. 2001. 	/* we know there's no monster in the way, and we're not trapped */ 2002. 	if (!Punished || drag_ball(x, y, &bc, &bx, &by, &cx, &cy, &unused)) { 2003. 	   u.ux0 = u.ux,  u.uy0 = u.uy; 2004. 	   u.ux = x,  u.uy = y;  2005. u.umoved = TRUE; 2006. 	   newsym(u.ux0, u.uy0); 2007. 	   vision_recalc(1); 2008. 	   check_leash(u.ux0, u.uy0); 2009. 	   if (Punished) move_bc(0, bc, bx, by, cx, cy); 2010. 	   spoteffects;	/* dotrap */ 2011. 	   exercise(A_WIS, FALSE); 2012. 	} 2013. }  2014.  2015. /* 0: doesn't even try 2016. * 1: tries and fails 2017. * 2: succeeds 2018. */  2019. STATIC_OVL int 2020. try_disarm(ttmp, force_failure) 2021. struct trap *ttmp; 2022. boolean force_failure; 2023. { 2024. 	struct monst *mtmp = m_at(ttmp->tx,ttmp->ty); 2025. 	int ttype = ttmp->ttyp; 2026. 	boolean under_u = (!u.dx && !u.dy); 2027. 2028. 	/* Test for monster first, monsters are displayed instead of trap. */ 2029. 	if (mtmp && (!mtmp->mtrapped || ttype != BEAR_TRAP)) { 2030. 		pline("%s is in the way.", Monnam(mtmp)); 2031. 		return 0; 2032. 	} 2033. 	/* We might be forced to move onto the trap's location. */ 2034. 	if (sobj_at(BOULDER, ttmp->tx, ttmp->ty)  2035. 				&& !passes_walls(uasmon) && !under_u) { 2036. 		pline("There is a boulder in your way."); 2037. 		return 0; 2038. 	} 2039. 	/* untrappable traps are located on the ground. */ 2040. 	if (!can_reach_floor) { 2041. 		You("are unable to reach the %s!", 2042. 			defsyms[trap_to_defsym(ttype)].explanation); 2043. 		return 0; 2044. 	} 2045.  2046. 	/* Will our hero succeed? */ 2047. 	if (force_failure || untrap_prob(ttmp)) { 2048. 		if (rnl(5)) { 2049. 		   pline("Whoops..."); 2050. 		   if (mtmp) {		/* must be a bear trap */ 2051. 			if (mtmp->mtame) abuse_dog(mtmp); 2052. 			if ((mtmp->mhp -= rnd(4)) <= 0) killed(mtmp); 2053. 		   } else if (under_u) { 2054. 			dotrap(ttmp); 2055. 		   } else { 2056. 			move_into_trap(ttmp); 2057. 		   }  2058. 		} else { 2059. 		   pline("%s %s is difficult to disarm.",  2060. 			  ttmp->madeby_u ? "Your" : under_u ? "This" : "That",  2061. 			  defsyms[trap_to_defsym(ttype)].explanation); 2062. 		} 2063. 		return 1; 2064. 	} 2065. 	return 2; 2066. } 2067.  2068. STATIC_OVL void 2069. reward_untrap(ttmp, mtmp) 2070. struct trap *ttmp; 2071. struct monst *mtmp; 2072. { 2073. 	if (!ttmp->madeby_u) { 2074. 		if (rnl(10)<8 && !mtmp->mpeaceful && 2075. 						mtmp->data->mlet != S_HUMAN) { 2076. 			mtmp->mpeaceful = 1; 2077. 			pline("%s is grateful.", Monnam(mtmp)); 2078. 		} 2079. 		/* Helping someone out of a trap is a nice thing to do, 2080. 		 * A lawful may be rewarded, but not too often. */ 2081. 		if (!rn2(3) && !rnl(8) && u.ualign.type == A_LAWFUL) { 2082. 			adjalign(1); 2083. 			You_feel("that you did the right thing."); 2084. 		} 2085. 	}  2086. }  2087.  2088. STATIC_OVL int 2089. disarm_beartrap(ttmp) /* Helge Hafting */ 2090. struct trap *ttmp; 2091. { 2092. 	struct monst *mtmp; 2093. 	int fails = try_disarm(ttmp, FALSE); 2094. 2095. 	if (fails < 2) return fails; 2096. 2097. 	/* ok, disarm it. */ 2098.  2099. 	/* untrap the monster, if any. 2100. 	  There's no need for a cockatrice test, only the trap is touched */ 2101. 	if ((mtmp = m_at(ttmp->tx,ttmp->ty)) != 0) { 2102. 		mtmp->mtrapped = 0; 2103. 		You("remove %s bear trap from %s.", the_your[ttmp->madeby_u], 2104. 			mon_nam(mtmp)); 2105. 		reward_untrap(ttmp, mtmp); 2106. 	} else You("disarm %s bear trap.", the_your[ttmp->madeby_u]); 2107. 	cnv_trap_obj(BEARTRAP, 1, ttmp); 2108. 	return 1; 2109. } 2110.  2111. STATIC_OVL int 2112. disarm_landmine(ttmp) /* Helge Hafting */ 2113. struct trap *ttmp; 2114. { 2115. 	int fails = try_disarm(ttmp, FALSE); 2116. 2117. 	if (fails < 2) return fails; 2118. 	You("disarm %s land mine.", the_your[ttmp->madeby_u]); 2119. 	cnv_trap_obj(LAND_MINE, 1, ttmp); 2120. 	return 1; 2121. } 2122.  2123. /* getobj will filter down to cans of grease and known potions of oil */ 2124. static NEARDATA const char oil[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS, 0 }; 2125. 2126. /* it may not make much sense to use grease on floor boards, but so what? */ 2127. STATIC_OVL int 2128. disarm_squeaky_board(ttmp) 2129. struct trap *ttmp; 2130. { 2131. 	struct obj *obj; 2132. 	boolean bad_tool; 2133. 	int fails; 2134. 2135. 	obj = getobj(oil, "untrap with"); 2136. 	if (!obj) return 0; 2137. 2138. 	bad_tool = (obj->cursed ||  2139. 			((obj->otyp != POT_OIL || obj->lamplit) && 2140. 			 (obj->otyp != CAN_OF_GREASE || !obj->spe))); 2141. 2142. 	fails = try_disarm(ttmp, bad_tool); 2143. 	if (fails < 2) return fails; 2144. 2145. 	/* successfully used oil or grease to fix squeaky board */ 2146. 	if (obj->otyp == CAN_OF_GREASE) { 2147. 	   check_unpaid(obj); 2148. 	   obj->spe--; 2149. 	} else { 2150. 	   useup(obj);	/* oil */ 2151. 	   makeknown(POT_OIL); 2152. 	} 2153. 	You("repair the squeaky board.");	/* no madeby_u */ 2154. 	deltrap(ttmp); 2155. 	newsym(u.ux + u.dx, u.uy + u.dy); 2156. 	more_experienced(1, 5); 2157. 	return 1; 2158. } 2159.  2160. /* removes traps that shoot arrows, darts, etc. */ 2161. STATIC_OVL int 2162. disarm_shooting_trap(ttmp, otyp) 2163. struct trap *ttmp; 2164. int otyp; 2165. { 2166. 	int fails = try_disarm(ttmp, FALSE); 2167. 2168. 	if (fails < 2) return fails; 2169. 	You("disarm %s trap", the_your[ttmp->madeby_u]); 2170. 	cnv_trap_obj(otyp, 50-rnl(50), ttmp); 2171. 	return 1; 2172. } 2173.  2174. /* Is the weight too heavy? 2175. * Formula as in near_capacity & check_capacity */ 2176. STATIC_OVL int 2177. try_lift(mtmp, ttmp, wt, stuff) 2178. struct monst *mtmp; 2179. struct trap *ttmp; 2180. int wt; 2181. boolean stuff; 2182. { 2183. 	int wc = weight_cap; 2184. 2185. 	if ((((wt<<1) / wc)+1) >= EXT_ENCUMBER) { 2186. 		pline("%s is %s for you to lift.", Monnam(mtmp), 2187. 			stuff ? "carrying too much" : "too heavy"); 2188. 		if (!ttmp->madeby_u && !mtmp->mpeaceful 2189. 			&& mtmp->data->mlet != S_HUMAN && rnl(10) < 3) { 2190. 		   mtmp->mpeaceful = 1; 2191. 		   pline("%s thinks it was nice of you to try.", Monnam(mtmp)); 2192. 		} 2193. 		return 0; 2194. 	} 2195. 	return 1; 2196. } 2197.  2198. /* Help trapped monster (out of a (spiked) pit) */ 2199. STATIC_OVL int 2200. help_monster_out(mtmp, ttmp) 2201. struct monst *mtmp; 2202. struct trap *ttmp; 2203. { 2204. 	int wt; 2205. 	struct obj *otmp; 2206. 2207. 	/*  2208. 	 * This works when levitating too -- consistent with the ability 2209. 	 * to hit monsters while levitating. 2210. 	 * 2211. 	 * Should perhaps check that our hero has arms/hands at the 2212. 	 * moment. Helping can also be done by engulfing... 2213. * 2214. 	 * Test the monster first - monsters are displayed before traps. 2215. 	 */ 2216. 	if (!mtmp->mtrapped) { 2217. 		pline("%s isn't trapped.", Monnam(mtmp)); 2218. 		return 0; 2219. 	} 2220. 	/* Do you have the necessary capacity to lift anything? */ 2221. 	if (check_capacity((char *)0)) return 1; 2222. 2223. 	/* Will our hero succeed? */ 2224. 	if (untrap_prob(ttmp)) { 2225. 		You("try to reach out your %s, but %s backs away skeptically.", 2226. 			makeplural(body_part(ARM)),  2227. 			mon_nam(mtmp)); 2228. 		return 1; 2229. 	} 2230.  2231.  2232. 	/* is it a cockatrice?... */ 2233. 	if (mtmp->data == &mons[PM_COCKATRICE] && !uarmg  2234. 		    && !resists_ston(&youmonst)) { 2235. 		You("grab the trapped cockatrice using your bare %s.", 2236. 			makeplural(body_part(HAND))); 2237. 2238. 		if (poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)) 2239. 			display_nhwindow(WIN_MESSAGE, FALSE); 2240. 		else { 2241. 		     instapetrify("trying to help a cockatrice out of a pit"); 2242. 			return 1; 2243. 		} 2244. 	}  2245. 	You("reach out your %s and grab %s.",  2246. 			makeplural(body_part(ARM)), mon_nam(mtmp)); 2247. 2248. 	/* is the monster too heavy? */ 2249. 	wt = inv_weight + mtmp->data->cwt; 2250. 	if (!try_lift(mtmp, ttmp, wt, FALSE)) return 1; 2251. 2252. 	/* is the monster with inventory too heavy? */ 2253. 	for (otmp = mtmp->minvent; otmp; otmp=otmp->nobj) 2254. 		wt += otmp->owt; 2255. 	if (!try_lift(mtmp, ttmp, wt, TRUE)) return 1; 2256. 2257. 	You("pull %s out of the pit.", mon_nam(mtmp)); 2258. 	mtmp->mtrapped = 0; 2259. 	reward_untrap(ttmp, mtmp); 2260. 	return 1; 2261. } 2262.  2263. int 2264. untrap(force) 2265. boolean force; 2266. { 2267. 	register struct obj *otmp; 2268. 	register boolean confused = (Confusion > 0 || Hallucination > 0); 2269. 	register int x,y; 2270. 	int ch; 2271. 	struct trap *ttmp; 2272. 	struct monst *mtmp; 2273. 	boolean trap_skipped = FALSE; 2274. 2275. 	if(!getdir((char *)0)) return(0); 2276. 	x = u.ux + u.dx; 2277. 	y = u.uy + u.dy; 2278. 2279. 	if ((ttmp = t_at(x,y)) && ttmp->tseen) { 2280. 		if (u.utrap) { 2281. 			You("cannot deal with traps while trapped!"); 2282. 			return 1; 2283. 		} 2284. 		switch(ttmp->ttyp) { 2285. 			case BEAR_TRAP: 2286. 				return disarm_beartrap(ttmp); 2287. 			case LANDMINE: 2288. 				return disarm_landmine(ttmp); 2289. 			case SQKY_BOARD: 2290. 				return disarm_squeaky_board(ttmp); 2291. 			case DART_TRAP: 2292. 				return disarm_shooting_trap(ttmp, DART); 2293. 			case ARROW_TRAP: 2294. 				return disarm_shooting_trap(ttmp, ARROW); 2295. 			case PIT: 2296. 			case SPIKED_PIT: 2297. 				if (!u.dx && !u.dy) { 2298. 				   You("are already on the edge of the pit."); 2299. 				   return 0; 2300. 				} 2301. 				if (!(mtmp = m_at(x,y))) { 2302. 				   pline("Try filling the pit instead."); 2303. 				   return 0; 2304. 				} 2305. 				return help_monster_out(mtmp, ttmp); 2306. 			default: 2307. 				You("cannot disable %s trap.", (u.dx || u.dy) ? "that" : "this"); 2308. 				return 0; 2309. 		} /* end switch */ 2310. 	} /* end if */ 2311. 2312. 	if(!u.dx && !u.dy) { 2313. 	   for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) 2314. 		if(Is_box(otmp)) { 2315. 		   pline("There is %s here.", doname(otmp)); 2316. 2317. 		    switch (ynq("Check for traps?")) { 2318. 			case 'q': return(0); 2319. 			case 'n': continue; 2320. 		   }  2321.  2322. 		    if((otmp->otrapped && (force || (!confused 2323. 				&& rn2(MAXULEV + 1 - u.ulevel) < 10))) 2324. 		       || (!force && confused && !rn2(3))) { 2325. 			You("find a trap on %s!", the(xname(otmp))); 2326. 			exercise(A_WIS, TRUE); 2327. 2328. 			switch (ynq("Disarm it?")) { 2329. 			   case 'q': return(1); 2330. 			   case 'n': trap_skipped = TRUE;  continue; 2331. 			} 2332.  2333. 			if(otmp->otrapped) { 2334. 			   exercise(A_DEX, TRUE); 2335. 			   ch = ACURR(A_DEX) + u.ulevel; 2336. 			   if (Role_is('R')) ch *= 2; 2337. 			   if(!force && (confused || Fumbling || 2338. 				rnd(75+level_difficulty/2) > ch)) { 2339. 				(void) chest_trap(otmp, FINGER, TRUE); 2340. 			   } else { 2341. 				You("disarm it!"); 2342. 				otmp->otrapped = 0; 2343. 			   }  2344. 			} else pline("That %s was not trapped.", doname(otmp)); 2345. 			return(1); 2346. 		   } else { 2347. 			You("find no traps on %s.", the(xname(otmp))); 2348. 			return(1); 2349. 		   }  2350. 		}  2351.  2352. 	    You(trap_skipped ? "find no other traps here."  2353. 			     : "know of no traps here."); 2354. 	   return(0); 2355. 	} 2356.  2357. 	if ((mtmp = m_at(x,y))				&&  2358. 		mtmp->m_ap_type == M_AP_FURNITURE	&&  2359. 		(mtmp->mappearance == S_hcdoor || 2360. 			mtmp->mappearance == S_vcdoor)	&& 2361. 		!Protection_from_shape_changers)	 { 2362. 2363. 	    stumble_onto_mimic(mtmp); 2364. 	   return(1); 2365. 	} 2366.  2367. 	if (!IS_DOOR(levl[x][y].typ)) { 2368. 	   if ((ttmp = t_at(x,y)) && ttmp->tseen) 2369. 		You("cannot disable that trap."); 2370. 	   else 2371. 		You("know of no traps there."); 2372. 	   return(0); 2373. 	} 2374.  2375. 	switch (levl[x][y].doormask) { 2376. 	   case D_NODOOR: 2377. 		You("%s no door there.", Blind ? "feel" : "see"); 2378. 		return(0); 2379. 	   case D_ISOPEN: 2380. 		pline("This door is safely open."); 2381. 		return(0); 2382. 	   case D_BROKEN: 2383. 		pline("This door is broken."); 2384. 		return(0); 2385. 	} 2386.  2387. 	if ((levl[x][y].doormask & D_TRAPPED 2388. 	    && (force ||  2389. 		 (!confused && rn2(MAXULEV - u.ulevel + 11) < 10)))  2390. 	    || (!force && confused && !rn2(3))) { 2391. 		You("find a trap on the door!"); 2392. 		exercise(A_WIS, TRUE); 2393. 		if (ynq("Disarm it?") != 'y') return(1); 2394. 		if (levl[x][y].doormask & D_TRAPPED) { 2395. 		   ch = 15 + (Role_is('R') ? u.ulevel*3 : u.ulevel); 2396. 		   exercise(A_DEX, TRUE); 2397. 		   if(!force && (confused || Fumbling || 2398. 				    rnd(75+level_difficulty/2) > ch)) { 2399. 			   You("set it off!"); 2400. 			   b_trapped("door", FINGER); 2401. 		   } else 2402. 			   You("disarm it!"); 2403. 		   levl[x][y].doormask &= ~D_TRAPPED; 2404. 		} else pline("This door was not trapped."); 2405. 		return(1); 2406. 	} else { 2407. 		You("find no traps on the door."); 2408. 		return(1); 2409. 	} 2410. }  2411. #endif /* OVL2 */ 2412. #ifdef OVLB 2413. 2414. /* only called when the player is doing something to the chest directly */ 2415. boolean 2416. chest_trap(obj, bodypart, disarm) 2417. register struct obj *obj; 2418. register int bodypart; 2419. boolean disarm; 2420. { 2421. 	register struct obj *otmp = obj, *otmp2; 2422. 	char	buf[80]; 2423. 	const char *msg; 2424. 2425. 	You(disarm ? "set it off!" : "trigger a trap!"); 2426. 	display_nhwindow(WIN_MESSAGE, FALSE); 2427. 	if (Luck > -13 && rn2(13+Luck) > 7) {	/* saved by luck */ 2428. 	   /* trap went off, but good luck prevents damage */ 2429. 	   switch (rn2(13)) { 2430. 		case 12: 2431. 		case 11: msg = "explosive charge is a dud";  break; 2432. 		case 10: 2433. 		case 9:  msg = "electric charge is grounded";  break; 2434. 		case 8: 2435. 		case 7:  msg = "flame fizzles out";  break; 2436. 		case 6: 2437. 		case 5: 2438. 		case 4:  msg = "poisoned needle misses";  break; 2439. 		case 3: 2440. 		case 2: 2441. 		case 1: 2442. 		case 0:  msg = "gas cloud blows away";  break; 2443. 		default: impossible("chest disarm bug");  msg = (char *)0; 2444. 			 break; 2445. 	   }  2446. 	    if (msg) pline("But luckily the %s!", msg); 2447. 	} else { 2448. 	   switch(rn2(20) ? ((Luck >= 13) ? 0 : rn2(13-Luck)) : rn2(26)) { 2449. 		case 25: 2450. 		case 24: 2451. 		case 23: 2452. 		case 22: 2453. 		case 21: { 2454. 			 struct monst *shkp = 0; 2455. 			 long loss = 0L; 2456. 			 boolean costly, insider; 2457. 			 register xchar ox = obj->ox, oy = obj->oy; 2458. 2459. 			  /* the obj location need not be that of player */ 2460. 			 costly = (costly_spot(ox, oy) &&  2461. 				   (shkp = shop_keeper(*in_rooms(ox, oy, 2462. 				   SHOPBASE))) != (struct monst *)0); 2463. 			 insider = (*u.ushops && inside_shop(u.ux, u.uy) &&  2464. 				    *in_rooms(ox, oy, SHOPBASE) == *u.ushops); 2465. 2466. 			  pline("%s explodes!", The(xname(obj))); 2467. 			 Sprintf(buf, "exploding %s", xname(obj)); 2468. 2469. 			  if(costly) 2470. 			     loss += stolen_value(obj, ox, oy,  2471. 						(boolean)shkp->mpeaceful, TRUE); 2472. 			 delete_contents(obj); 2473. 			 for(otmp = level.objects[u.ux][u.uy];  2474. 							otmp; otmp = otmp2) { 2475. 			     otmp2 = otmp->nexthere; 2476. 			     if(costly) 2477. 				 loss += stolen_value(otmp, otmp->ox,  2478. 					  otmp->oy, (boolean)shkp->mpeaceful,  2479. 					  TRUE); 2480. 			     delobj(otmp); 2481. 			 }  2482. 			  wake_nearby; 2483. 			 losehp(d(6,6), buf, KILLED_BY_AN); 2484. 			 exercise(A_STR, FALSE); 2485. 			 if(costly && loss) { 2486. 			     if(insider) 2487. 			     You("owe %ld zorkmids for objects destroyed.",  2488. 							loss); 2489. 			     else { 2490. 				 You("caused %ld zorkmids worth of damage!",  2491. 							loss); 2492. 				 make_angry_shk(shkp, ox, oy); 2493. 			     }  2494. 			  }  2495. 			  return TRUE; 2496. 			} 2497. 		case 20: 2498. 		case 19: 2499. 		case 18: 2500. 		case 17: 2501. 			pline("A cloud of noxious gas billows from %s.", 2502. 							the(xname(obj))); 2503. 			poisoned("gas cloud", A_STR, "cloud of poison gas",15); 2504. 			exercise(A_CON, FALSE); 2505. 			break; 2506. 		case 16: 2507. 		case 15: 2508. 		case 14: 2509. 		case 13: 2510. 			You_feel("a needle prick your %s.",body_part(bodypart)); 2511. 			poisoned("needle", A_CON, "poisoned needle",10); 2512. 			exercise(A_CON, FALSE); 2513. 			break; 2514. 		case 12: 2515. 		case 11: 2516. 		case 10: 2517. 		case 9: 2518. 			dofiretrap(obj); 2519. 			break; 2520. 		case 8: 2521. 		case 7: 2522. 		case 6: { 2523. 			int dmg; 2524. 2525. 			You("are jolted by a surge of electricity!"); 2526. 			if(Shock_resistance) { 2527. 			   shieldeff(u.ux, u.uy); 2528. 			   You("don't seem to be affected."); 2529. 			   dmg = 0; 2530. 			} else 2531. 			   dmg = d(4, 4); 2532. 			destroy_item(RING_CLASS, AD_ELEC); 2533. 			destroy_item(WAND_CLASS, AD_ELEC); 2534. 			if (dmg) losehp(dmg, "electric shock", KILLED_BY_AN); 2535. 			break; 2536. 		     }  2537. 		case 5: 2538. 		case 4: 2539. 		case 3: 2540. 			pline("Suddenly you are frozen in place!"); 2541. 			nomul(-d(5, 6)); 2542. 			exercise(A_DEX, FALSE); 2543. 			nomovemsg = "You can move again."; 2544. 			break; 2545. 		case 2: 2546. 		case 1: 2547. 		case 0: 2548. 			pline("A cloud of %s gas billows from %s.", 2549. 						hcolor((char *)0),  2550. 						the(xname(obj))); 2551. 			if(!Stunned) { 2552. 			   if (Hallucination) 2553. 				pline("What a groovy feeling!"); 2554. 			   else if (Blind) 2555. 				You("stagger and get dizzy..."); 2556. 			   else 2557. 				You("stagger and your vision blurs..."); 2558. 			} 2559. 			make_stunned(HStun + rn1(7, 16),FALSE); 2560. 			make_hallucinated(HHallucination + rn1(5, 16),FALSE,0L); 2561. 			break; 2562. 		default: impossible("bad chest trap"); 2563. 			break; 2564. 	   }  2565. 	    bot;			/* to get immediate botl re-display */ 2566. 	} 2567. 	otmp->otrapped = 0;		/* these traps are one-shot things */ 2568. 2569. 	return FALSE; 2570. } 2571.  2572. #endif /* OVLB */ 2573. #ifdef OVL0 2574. 2575. struct trap * 2576. t_at(x,y) 2577. register int x, y; 2578. { 2579. 	register struct trap *trap = ftrap; 2580. 	while(trap) { 2581. 		if(trap->tx == x && trap->ty == y) return(trap); 2582. 		trap = trap->ntrap; 2583. 	} 2584. 	return((struct trap *)0); 2585. } 2586.  2587. #endif /* OVL0 */ 2588. #ifdef OVLB 2589. 2590. void 2591. deltrap(trap) 2592. register struct trap *trap; 2593. { 2594. 	register struct trap *ttmp; 2595. 2596. 	if(trap == ftrap) 2597. 		ftrap = ftrap->ntrap; 2598. 	else { 2599. 		for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ; 2600. 		ttmp->ntrap = trap->ntrap; 2601. 	} 2602. 	dealloc_trap(trap); 2603. } 2604.  2605. boolean delfloortrap(ttmp) 2606. register struct trap *ttmp; 2607. { 2608. 	/* Destroy a trap that emanates from the floor. */ 2609. 	/* some of these are arbitrary -dlc */ 2610. 	if (ttmp && ((ttmp->ttyp == SQKY_BOARD) || 2611. 		    (ttmp->ttyp == BEAR_TRAP) || 2612. 		    (ttmp->ttyp == LANDMINE) || 2613. 		    (ttmp->ttyp == FIRE_TRAP) || 2614. 		    (ttmp->ttyp == PIT) || 2615. 		    (ttmp->ttyp == SPIKED_PIT) || 2616. 		    (ttmp->ttyp == HOLE) || 2617. 		    (ttmp->ttyp == TRAPDOOR) || 2618. 		    (ttmp->ttyp == TELEP_TRAP) || 2619. 		    (ttmp->ttyp == LEVEL_TELEP) || 2620. 		    (ttmp->ttyp == WEB) || 2621. 		    (ttmp->ttyp == MAGIC_TRAP) || 2622. 		    (ttmp->ttyp == ANTI_MAGIC))) { 2623. 	   register struct monst *mtmp; 2624. 2625. 	    if (ttmp->tx == u.ux && ttmp->ty == u.uy) { 2626. 		u.utrap = 0; 2627. 		u.utraptype = 0; 2628. 	   } else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) { 2629. 		mtmp->mtrapped = 0; 2630. 	   }  2631. 	    deltrap(ttmp); 2632. 	   return TRUE; 2633. 	} else 2634. 	   return FALSE; 2635. } 2636.  2637. /* used for doors (also tins). can be used for anything else that opens. */ 2638. void 2639. b_trapped(item, bodypart) 2640. register const char *item; 2641. register int bodypart; 2642. { 2643. 	register int lvl = level_difficulty; 2644. 	int dmg = rnd(5 + (lvl < 5 ? lvl : 2+lvl/2)); 2645. 2646. 	pline("KABOOM!!  %s was booby-trapped!", The(item)); 2647. 	wake_nearby; 2648. 	losehp(dmg, "explosion", KILLED_BY_AN); 2649. 	exercise(A_STR, FALSE); 2650. 	if (bodypart) exercise(A_CON, FALSE); 2651. 	make_stunned(HStun + dmg, TRUE); 2652. } 2653.  2654. /* Monster is hit by trap. */ 2655. /* Note: doesn't work if both obj and d_override are null */ 2656. STATIC_OVL boolean 2657. thitm(tlev, mon, obj, d_override) 2658. register int tlev; 2659. register struct monst *mon; 2660. register struct obj *obj; 2661. int d_override; 2662. { 2663. 	register int strike; 2664. 	register boolean trapkilled = FALSE; 2665. 2666. 	if (d_override) strike = 1; 2667. 	else if (obj) strike = (find_mac(mon) + tlev + obj->spe <= rnd(20)); 2668. 	else strike = (find_mac(mon) + tlev <= rnd(20)); 2669. 2670. 	/* Actually more accurate than thitu, which doesn't take 2671. 	 * obj->spe into account. 2672. 	 */ 2673. 	if(!strike) { 2674. 		if (cansee(mon->mx, mon->my)) 2675. 			pline("%s is almost hit by %s!", Monnam(mon), 2676. 								doname(obj)); 2677. 	} else { 2678. 		int dam = 1; 2679. 2680. 		if (obj && cansee(mon->mx, mon->my)) 2681. 			pline("%s is hit by %s!", Monnam(mon), doname(obj)); 2682. 		if (d_override) dam = d_override; 2683. 		else if (obj) { 2684. 			dam = dmgval(obj, mon); 2685. 			if (dam < 1) dam = 1; 2686. 		} 2687. 		if ((mon->mhp -= dam) <= 0) { 2688. 			int xx = mon->mx; 2689. 			int yy = mon->my; 2690. 2691. 			monkilled(mon, "", AD_PHYS); 2692. 			if (mon->mhp <= 0) { 2693. 				newsym(xx, yy); 2694. 				trapkilled = TRUE; 2695. 			} 2696. 		}  2697. 	}  2698. 	if (obj && (!strike || d_override)) { 2699. 		place_object(obj, mon->mx, mon->my); 2700. 		stackobj(obj); 2701. 	} else if (obj) dealloc_obj(obj); 2702. 2703. 	return trapkilled; 2704. } 2705.  2706. boolean 2707. unconscious 2708. { 2709. 	return((boolean)(multi < 0 && (!nomovemsg ||  2710. 		u.usleep ||  2711. 		!strncmp(nomovemsg,"You regain con", 15) ||  2712. 		!strncmp(nomovemsg,"You are consci", 15)))); 2713. } 2714.  2715. static char lava_killer[] = "molten lava"; 2716. 2717. boolean 2718. lava_effects 2719. { 2720.     register struct obj *obj, *obj2; 2721.    int dmg; 2722. 2723.     if (likes_lava(uasmon)) return FALSE; 2724. 2725.     if (!Fire_resistance) { 2726. 	if(Wwalking) { 2727. 	   dmg = d(6,6); 2728. 	   pline_The("lava here burns you!"); 2729. 	   if(dmg < u.uhp) { 2730. 		losehp(dmg, lava_killer, KILLED_BY); 2731. 		goto burn_stuff; 2732. 	   }  2733. 	} else 2734. 	   You("fall into the lava!"); 2735. 2736. 	for(obj = invent; obj; obj = obj2) { 2737. 	   obj2 = obj->nobj; 2738. 	   if(is_organic(obj) && !obj->oerodeproof) { 2739. 		if(obj->owornmask) { 2740. 		   if(obj == uarm) (void) Armor_gone; 2741. 		   else if(obj == uarmc) (void) Cloak_off; 2742. 		   else if(obj == uarmh) (void) Helmet_off; 2743. 		   else if(obj == uarms) (void) Shield_off; 2744. 		   else if(obj == uarmg) (void) Gloves_off; 2745. 		   else if(obj == uarmf) (void) Boots_off; 2746. #ifdef TOURIST 2747. 		   else if(obj == uarmu) setnotworn(obj); 2748. #endif 2749. 		   else if(obj == uleft) Ring_gone(obj); 2750. 		   else if(obj == uright) Ring_gone(obj); 2751. 		   else if(obj == ublindf) Blindf_off(obj); 2752. 		   else if(obj == uwep) uwepgone; 2753. 		   if(Lifesaved  2754. #ifdef WIZARD  2755. 		       || wizard  2756. #endif  2757. 		       ) Your("%s into flame!", aobjnam(obj, "burst")); 2758. 		} 2759. 		useup(obj); 2760. 	   }  2761. 	}  2762.  2763. 	/* s/he died... */ 2764. 	u.uhp = -1; 2765. 	killer_format = KILLED_BY; 2766. 	killer = lava_killer; 2767. 	You("burn to a crisp..."); 2768. 	done(BURNING); 2769. 	while (!safe_teleds) { 2770. 		pline("You're still burning."); 2771. 		done(BURNING); 2772. 	} 2773. 	You("find yourself back on solid %s.", surface(u.ux, u.uy)); 2774. 	return(TRUE); 2775.    }  2776.  2777.     if (!Wwalking) { 2778. 	u.utrap = rn1(4, 4) + (rn1(4, 12) << 8); 2779. 	u.utraptype = TT_LAVA; 2780. 	You("sink into the lava, but it only burns slightly!"); 2781. 	if (u.uhp > 1) 2782. 	   losehp(1, lava_killer, KILLED_BY); 2783.    }  2784.     /* just want to burn boots, not all armor; destroy_item doesn't work on  2785. armor anyway */ 2786. burn_stuff: 2787.    if(uarmf && !uarmf->oerodeproof && is_organic(uarmf)) { 2788. 	/* save uarmf value because Boots_off sets uarmf to null */ 2789. 	obj = uarmf; 2790. 	Your("%s burst into flame!", xname(obj)); 2791. 	(void) Boots_off; 2792. 	useup(obj); 2793.    }  2794.     destroy_item(SCROLL_CLASS, AD_FIRE); 2795.    destroy_item(SPBOOK_CLASS, AD_FIRE); 2796.    destroy_item(POTION_CLASS, AD_FIRE); 2797.    return(FALSE); 2798. } 2799.  2800. #endif /* OVLB */ 2801. 2802. /*trap.c*/