Source:NetHack 3.4.0/trap.c

Below is the full text to trap.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.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.4	2001/09/06	*/ 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.   extern const char *destroy_strings[]; 8.    9.    STATIC_DCL void FDECL(dofiretrap, (struct obj *)); 10.  STATIC_DCL void NDECL(domagictrap); 11.  STATIC_DCL boolean FDECL(emergency_disrobe,(boolean *)); 12.  STATIC_DCL int FDECL(untrap_prob, (struct trap *ttmp)); 13.  STATIC_DCL void FDECL(cnv_trap_obj, (int, int, struct trap *)); 14.  STATIC_DCL void FDECL(move_into_trap, (struct trap *)); 15.  STATIC_DCL int FDECL(try_disarm, (struct trap *,BOOLEAN_P)); 16.  STATIC_DCL void FDECL(reward_untrap, (struct trap *, struct monst *)); 17.  STATIC_DCL int FDECL(disarm_holdingtrap, (struct trap *)); 18.  STATIC_DCL int FDECL(disarm_landmine, (struct trap *)); 19.  STATIC_DCL int FDECL(disarm_squeaky_board, (struct trap *)); 20.  STATIC_DCL int FDECL(disarm_shooting_trap, (struct trap *, int)); 21.  STATIC_DCL int FDECL(try_lift, (struct monst *, struct trap *, int, BOOLEAN_P)); 22.  STATIC_DCL int FDECL(help_monster_out, (struct monst *, struct trap *)); 23.  STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int)); 24.  STATIC_DCL int FDECL(mkroll_launch,  25.   			(struct trap *,XCHAR_P,XCHAR_P,SHORT_P,long)); 26.  STATIC_DCL boolean FDECL(isclearpath,(coord *, int, SCHAR_P, SCHAR_P)); 27.  #ifdef STEED 28.  STATIC_OVL int FDECL(steedintrap, (struct trap *, struct obj *)); 29.  #endif 30.   31.   #ifndef OVLB 32.  STATIC_VAR const char *a_your[2]; 33.  STATIC_VAR const char *A_Your[2]; 34.  STATIC_VAR const char *the_your[2]; 35.  STATIC_VAR const char tower_of_flame[]; 36.  STATIC_VAR const char *A_gush_of_water_hits; 37.   38.   #else 39.   40.   STATIC_VAR const char *a_your[2] = { "a", "your" }; 41.  STATIC_VAR const char *A_Your[2] = { "A", "Your" }; 42.  STATIC_VAR const char *the_your[2] = { "the", "your" }; 43.  STATIC_VAR const char tower_of_flame[] = "tower of flame"; 44.  STATIC_VAR const char *A_gush_of_water_hits = "A gush of water hits"; 45.   46.   #endif /* OVLB */ 47.   48.   #ifdef OVLB 49.   50.   /* called when you're hit by fire (dofiretrap,buzz,zapyourself,explode) */ 51.  boolean			/* returns TRUE if hit on torso */ 52.  burnarmor(victim) 53.  struct monst *victim; 54.  {  55.       struct obj *item; 56.      char buf[BUFSZ]; 57.      int mat_idx; 58.       59.       if (!victim) return 0; 60.  #define burn_dmg(obj,descr) rust_dmg(obj, descr, 0, FALSE, victim) 61.      while (1) { 62.  	switch (rn2(5)) { 63.  	case 0: 64.  	    item = (victim == &youmonst) ? uarmh : which_armor(victim, W_ARMH); 65.  	    if (item) { 66.  		mat_idx = objects[item->otyp].oc_material; 67.  	    	Sprintf(buf,"%s helmet", materialnm[mat_idx] ); 68.  	    }  69.   	    if (!burn_dmg(item, item ? buf : "helmet")) continue; 70.  	    break; 71.  	case 1: 72.  	    item = (victim == &youmonst) ? uarmc : which_armor(victim, W_ARMC); 73.  	    if (item) { 74.  		(void) burn_dmg(item, cloak_simple_name(item)); 75.  		return TRUE; 76.  	    }  77.   	    item = (victim == &youmonst) ? uarm : which_armor(victim, W_ARM); 78.  	    if (item) { 79.  		(void) burn_dmg(item, xname(item)); 80.  		return TRUE; 81.  	    }  82.   #ifdef TOURIST 83.  	    item = (victim == &youmonst) ? uarmu : which_armor(victim, W_ARMU); 84.  	    if (item) 85.  		(void) burn_dmg(item, "shirt"); 86.  #endif 87.  	    return TRUE; 88.  	case 2: 89.  	    item = (victim == &youmonst) ? uarms : which_armor(victim, W_ARMS); 90.  	    if (!burn_dmg(item, "wooden shield")) continue; 91.  	    break; 92.  	case 3: 93.  	    item = (victim == &youmonst) ? uarmg : which_armor(victim, W_ARMG); 94.  	    if (!burn_dmg(item, "gloves")) continue; 95.  	    break; 96.  	case 4: 97.  	    item = (victim == &youmonst) ? uarmf : which_armor(victim, W_ARMF); 98.  	    if (!burn_dmg(item, "boots")) continue; 99.  	    break; 100. 	}  101.  	break; /* Out of while loop */ 102.     }  103.      return FALSE; 104. #undef burn_dmg 105. }  106.   107.  /* Generic rust-armor function. Returns TRUE if a message was printed; 108.  * "print", if set, means to print a message (and thus to return TRUE) even 109.  * if the item could not be rusted; otherwise a message is printed and TRUE is  110. * returned only for rustable items. 111.  */  112.  boolean 113. rust_dmg(otmp, ostr, type, print, victim) 114. register struct obj *otmp; 115. register const char *ostr; 116. int type; 117. boolean print; 118. struct monst *victim; 119. {  120.  	static NEARDATA const char *action[] = { "smoulder", "rust", "rot", "corrode" }; 121. 	static NEARDATA const char *msg[] =  { "burnt", "rusted", "rotten", "corroded" }; 122. 	boolean vulnerable = FALSE; 123. 	boolean grprot = FALSE; 124. 	boolean is_primary = TRUE; 125. 	boolean vismon = (victim != &youmonst) && canseemon(victim); 126. 	int erosion; 127.  128.  	if (!otmp) return(FALSE); 129. 	switch(type) { 130. 		case 0: vulnerable = is_flammable(otmp); 131. 			break; 132. 		case 1: vulnerable = is_rustprone(otmp); 133. 			grprot = TRUE; 134. 			break; 135. 		case 2: vulnerable = is_rottable(otmp); 136. 			is_primary = FALSE; 137. 			break; 138. 		case 3: vulnerable = is_corrodeable(otmp); 139. 			grprot = TRUE; 140. 			is_primary = FALSE; 141. 			break; 142. 	}  143.  	erosion = is_primary ? otmp->oeroded : otmp->oeroded2; 144.  145.  	if (!print && (!vulnerable || otmp->oerodeproof || erosion == MAX_ERODE)) 146. 		return FALSE; 147.  148.  	if (!vulnerable) { 149. 	    if (flags.verbose) { 150. 		if (victim == &youmonst) 151. 		    Your("%s %s not affected.", ostr, vtense(ostr, "are")); 152. 		else if (vismon) 153. 		    pline("%s's %s %s not affected.", Monnam(victim), ostr,  154.  			  vtense(ostr, "are")); 155. 	    }  156.  	} else if (erosion < MAX_ERODE) { 157. 	    if (grprot && otmp->greased) { 158. 		grease_protect(otmp,ostr,victim); 159. 	    } else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) { 160. 		if (flags.verbose) { 161. 		    if (victim == &youmonst) 162. 			pline("Somehow, your %s %s not affected.",  163.  			      ostr, vtense(ostr, "are")); 164. 		    else if (vismon) 165. 			pline("Somehow, %s's %s %s not affected.",  166.  			      mon_nam(victim), ostr, vtense(ostr, "are")); 167. 		}  168.  	    } else { 169. 		if (victim == &youmonst) 170. 		    Your("%s %s%s!", ostr,  171.  			 vtense(ostr, action[type]),  172.  			 erosion+1 == MAX_ERODE ? " completely" :  173.  			    erosion ? " further" : ""); 174. 		else if (vismon) 175. 		    pline("%s's %s %s%s!", Monnam(victim), ostr,  176.  			vtense(ostr, action[type]),  177.  			erosion+1 == MAX_ERODE ? " completely" :  178.  			  erosion ? " further" : ""); 179. 		if (is_primary) 180. 		    otmp->oeroded++; 181. 		else 182. 		    otmp->oeroded2++; 183. 		update_inventory; 184. 	    }  185.  	} else { 186. 	    if (flags.verbose) { 187. 		if (victim == &youmonst) 188. 		    Your("%s %s completely %s.", ostr,  189.  			 vtense(ostr, Blind ? "feel" : "look"), 190.  			 msg[type]); 191. 		else if (vismon) 192. 		    pline("%s's %s %s completely %s.",  193.  			  Monnam(victim), ostr,  194.  			  vtense(ostr, "look"), msg[type]); 195. 	    }  196.  	}  197.  	return(TRUE); 198. }  199.   200.  void 201. grease_protect(otmp,ostr,victim) 202. register struct obj *otmp; 203. register const char *ostr; 204. struct monst *victim; 205. {  206.  	static const char txt[] = "protected by the layer of grease!"; 207. 	boolean vismon = victim && (victim != &youmonst) && canseemon(victim); 208.  209.  	if (ostr) { 210. 	    if (victim == &youmonst) 211. 		Your("%s %s %s", ostr, vtense(ostr, "are"), txt); 212. 	    else if (vismon) 213. 		pline("%s's %s %s %s", Monnam(victim),  214.  		    ostr, vtense(ostr, "are"), txt); 215. 	} else { 216. 	    if (victim == &youmonst) 217. 		Your("%s %s",aobjnam(otmp,"are"), txt); 218. 	    else if (vismon) 219. 		pline("%s's %s %s", Monnam(victim), aobjnam(otmp,"are"), txt); 220. 	}  221.  	if (!rn2(2)) { 222. 	    otmp->greased = 0; 223. 	    if (carried(otmp)) { 224. 		pline_The("grease dissolves."); 225. 		update_inventory; 226. 	    }  227.  	}  228.  }  229.   230.  struct trap * 231. maketrap(x,y,typ) 232. register int x, y, typ; 233. {  234.  	register struct trap *ttmp; 235. 	register struct rm *lev; 236. 	register boolean oldplace; 237.  238.  	if ((ttmp = t_at(x,y)) != 0) { 239. 	    if (ttmp->ttyp == MAGIC_PORTAL) return (struct trap *)0; 240. 	    oldplace = TRUE; 241. 	    if (u.utrap && (x == u.ux) && (y == u.uy) &&  242.  	      ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP) || 243. 	      (u.utraptype == TT_WEB && typ != WEB) || 244. 	      (u.utraptype == TT_PIT && typ != PIT && typ != SPIKED_PIT))) 245. 		    u.utrap = 0; 246. 	} else { 247. 	    oldplace = FALSE; 248. 	    ttmp = newtrap; 249. 	    ttmp->tx = x;  250. ttmp->ty = y; 251. ttmp->launch.x = -1;	/* force error if used before set */ 252. 	    ttmp->launch.y = -1; 253. 	}  254.  	ttmp->ttyp = typ; 255. 	switch(typ) { 256. 	    case STATUE_TRAP:	    /* create a "living" statue */ 257. 	      { struct monst *mtmp; 258. 		struct obj *otmp, *statue; 259.  260.  		statue = mkcorpstat(STATUE, (struct monst *)0,  261.  					&mons[rndmonnum], x, y, FALSE); 262. 		mtmp = makemon(&mons[statue->corpsenm], 0, 0, NO_MM_FLAGS); 263. 		if (!mtmp) break; /* should never happen */ 264. 		while(mtmp->minvent) { 265. 		    otmp = mtmp->minvent; 266. 		    otmp->owornmask = 0; 267. 		    obj_extract_self(otmp); 268. 		    (void) add_to_container(statue, otmp); 269. 		}  270.  		statue->owt = weight(statue); 271. 		mongone(mtmp); 272. 		break; 273. 	      }  274.  	    case ROLLING_BOULDER_TRAP:	/* boulder will roll towards trigger */ 275. 		(void) mkroll_launch(ttmp, x, y, BOULDER, 1L); 276. 		break; 277. 	    case HOLE: 278. 	    case PIT: 279. 	    case SPIKED_PIT: 280. 	    case TRAPDOOR: 281. 		lev = &levl[x][y]; 282. 		if (*in_rooms(x, y, SHOPBASE) &&  283.  			((typ == HOLE || typ == TRAPDOOR) || IS_DOOR(lev->typ))) 284. 		    add_damage(x, y,		/* schedule repair */  285.  			(IS_DOOR(lev->typ) && !flags.mon_moving) ? 200L : 0L); 286. 		lev->doormask = 0;	/* subsumes altarmask, icedpool... */ 287.  		if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */ 288. 		    lev->typ = ROOM; 289.  290.  		/*  291.  		 * some cases which can happen when digging 292. 		 * down while phazing thru solid areas 293. 		 */  294.  		else if (lev->typ == STONE || lev->typ == SCORR) 295. 		    lev->typ = CORR; 296. 		else if (IS_WALL(lev->typ) || lev->typ == SDOOR) 297. 		    lev->typ = level.flags.is_maze_lev ? ROOM : 298. 			       level.flags.is_cavernous_lev ? CORR : DOOR; 299.  300.  		unearth_objs(x, y); 301. 		break; 302. 	}  303.  	if (ttmp->ttyp == HOLE) ttmp->tseen = 1;  /* You can't hide a hole */ 304. 	else ttmp->tseen = 0; 305. 	ttmp->once = 0; 306. 	ttmp->madeby_u = 0; 307. 	ttmp->dst.dnum = -1; 308. 	ttmp->dst.dlevel = -1; 309. 	if (!oldplace) { 310. 	    ttmp->ntrap = ftrap; 311. 	    ftrap = ttmp; 312. 	}  313.  	return(ttmp); 314. }  315.   316.  void 317. fall_through(td) 318. boolean td;	/* td == TRUE : trap door or hole */ 319. {  320.  	d_level dtmp; 321. 	char msgbuf[BUFSZ]; 322. 	const char *dont_fall = 0; 323. 	register int newlevel = dunlev(&u.uz); 324.  325.  	/* KMH -- You can't escape the Sokoban level traps */ 326. 	if(Blind && Levitation && !In_sokoban(&u.uz)) return; 327.  328.  	do { 329. 	    newlevel++; 330. 	} while(!rn2(4) && newlevel < dunlevs_in_dungeon(&u.uz)); 331.  332.  	if(td) { 333. 	    struct trap *t=t_at(u.ux,u.uy); 334. 	    if (!In_sokoban(&u.uz)) { 335. 		if (t->ttyp == TRAPDOOR) 336. 			pline("A trap door opens up under you!"); 337. 		else 338. 			pline("There's a gaping hole under you!"); 339. 	    }  340.  	} else pline_The("%s opens up under you!", surface(u.ux,u.uy)); 341.  342.  	if (In_sokoban(&u.uz) && Can_fall_thru(&u.uz)) 343. 	    ;	/* KMH -- You can't escape the Sokoban level traps */ 344. 	else if(Levitation || u.ustuck || !Can_fall_thru(&u.uz)  345.  	   || Flying || is_clinger(youmonst.data)  346.  	   || (Inhell && !u.uevent.invoked && 347. 					newlevel == dunlevs_in_dungeon(&u.uz))  348.  		) { 349. 	    dont_fall = "don't fall in."; 350. 	} else if (youmonst.data->msize >= MZ_HUGE) { 351. 	    dont_fall = "don't fit through."; 352. 	} else if (!next_to_u) { 353. 	    dont_fall = "are jerked back by your pet!"; 354. 	}  355.  	if (dont_fall) { 356. 	    You(dont_fall); 357. 	    /* hero didn't fall through, but any objects here might */ 358. 	    impact_drop((struct obj *)0, u.ux, u.uy, 0); 359. 	    if (!td) { 360. 		display_nhwindow(WIN_MESSAGE, FALSE); 361. 		pline_The("opening under you closes up."); 362. 	    }  363.  	    return; 364. 	}  365.   366.  	if(*u.ushops) shopdig(1); 367. 	if (Is_stronghold(&u.uz)) { 368. 	    find_hell(&dtmp); 369. 	} else { 370. 	    dtmp.dnum = u.uz.dnum; 371. 	    dtmp.dlevel = newlevel; 372. 	}  373.  	if (!td) 374. 	    Sprintf(msgbuf, "The hole in the %s above you closes up.",  375.  		    ceiling(u.ux,u.uy)); 376. 	schedule_goto(&dtmp, FALSE, TRUE, 0,  377.  		      (char *)0, !td ? msgbuf : (char *)0); 378. }  379.   380.  /*  381.   * Animate the given statue. May have been via shatter attempt, trap, 382.  * or stone to flesh spell. Return a monster if successfully animated. 383.  * If the monster is animated, the object is deleted. If fail_reason 384.  * is non-null, then fill in the reason for failure (or success). 385.  *  386.   * The cause of animation is: 387.  *  388.   *	ANIMATE_NORMAL  - hero "finds" the monster 389.  *	ANIMATE_SHATTER - hero tries to destroy the statue 390.  *	ANIMATE_SPELL   - stone to flesh spell hits the statue 391.  *  392.   * Perhaps x, y is not needed if we can use get_obj_location to find 393.  * the statue's location... ??? 394.  */  395.  struct monst * 396. animate_statue(statue, x, y, cause, fail_reason) 397. struct obj *statue; 398. xchar x, y;  399. int cause; 400. int *fail_reason; 401. {  402.  	struct permonst *mptr; 403. 	struct monst *mon = 0; 404. 	struct obj *item; 405. 	coord cc; 406.  407.  	if (statue->oxlth && statue->oattached == OATTACHED_MONST) { 408. 	    cc.x = x,  cc.y = y;  409. mon = montraits(statue, &cc); 410. 	    if (mon && mon->mtame && !mon->isminion) 411. 		wary_dog(mon, TRUE); 412. 	} else { 413. 	    /*  414.  	     * Guard against someone wishing for a statue of a unique monster 415. 	     * (which is allowed in normal play) and then tossing it onto the 416. 	     * [detected or guessed] location of a statue trap. Normally the 417. 	     * uppermost statue is the one which would be activated. 418. 	     */  419.  	    mptr = &mons[statue->corpsenm]; 420. 	    if (mptr->geno & G_UNIQ) { 421. 	        if (fail_reason) *fail_reason = AS_MON_IS_UNIQUE; 422. 	        return (struct monst *)0; 423. 	    }  424.  	    mon = makemon(mptr, x, y, NO_MINVENT); 425. 	}  426.   427.  	if (!mon) { 428. 	    if (fail_reason) *fail_reason = AS_NO_MON; 429. 	    return (struct monst *)0; 430. 	}  431.   432.  	/* if statue has been named, give same name to the monster */ 433. 	if (statue->onamelth) 434. 	    mon = christen_monst(mon, ONAME(statue)); 435. 	/* transfer any statue contents to monster's inventory */ 436. 	while ((item = statue->cobj) != 0) { 437. 	    obj_extract_self(item); 438. 	    (void) add_to_minv(mon, item); 439. 	}  440.  	m_dowear(mon, TRUE); 441. 	delobj(statue); 442. 	/* mimic statue becomes seen mimic; other hiders won't be hidden */ 443. 	if (mon->m_ap_type) seemimic(mon); 444. 	else mon->mundetected = FALSE; 445. 	if ((x == u.ux && y == u.uy) || cause == ANIMATE_SPELL) 446. 	    pline_The("statue comes to life!"); 447. 	else if (cause == ANIMATE_SHATTER) 448. 	    pline("Instead of shattering, the statue suddenly comes alive!"); 449. 	else /* cause == ANIMATE_NORMAL */ 450. 	    You("find %s posing as a statue.", a_monnam(mon)); 451. 	/* avoid hiding under nothing */ 452. 	if (x == u.ux && y == u.uy &&  453.  		Upolyd && hides_under(youmonst.data) && !OBJ_AT(x, y)) 454. 	    u.uundetected = 0; 455.  456.  	if (fail_reason) *fail_reason = AS_OK; 457. 	return mon; 458. }  459.   460.  /*  461.   * You've either stepped onto a statue trap's location or you've triggered a  462. * statue trap by searching next to it or by trying to break it with a wand 463.  * or pick-axe. 464.  */  465.  struct monst * 466. activate_statue_trap(trap, x, y, shatter) 467. struct trap *trap; 468. xchar x, y;  469. boolean shatter; 470. {  471.  	struct monst *mtmp = (struct monst *)0; 472. 	struct obj *otmp = sobj_at(STATUE, x, y); 473. 	int fail_reason; 474.  475.  	/*  476.  	 * Try to animate the first valid statue. Stop the loop when we 477. * actually create something or the failure cause is not because 478. 	 * the mon was unique. 479. 	 */  480.  	deltrap(trap); 481. 	while (otmp) { 482. 	    mtmp = animate_statue(otmp, x, y,  483.  		    shatter ? ANIMATE_SHATTER : ANIMATE_NORMAL, &fail_reason); 484. 	    if (mtmp || fail_reason != AS_MON_IS_UNIQUE) break; 485.  486.  	    while ((otmp = otmp->nexthere) != 0) 487. 		if (otmp->otyp == STATUE) break; 488. 	}  489.   490.  	if (Blind) feel_location(x, y); 491. 	else newsym(x, y); 492. 	return mtmp; 493. }  494.   495.  void 496. dotrap(trap, trflags) 497. register struct trap *trap; 498. unsigned trflags; 499. {  500.  	register int ttype = trap->ttyp; 501. 	register struct obj *otmp; 502. 	boolean already_seen = trap->tseen; 503. 	boolean webmsgok = (!(trflags & NOWEBMSG)); 504. 	  505.  	nomul(0); 506.  507.  	/* KMH -- You can't escape the Sokoban level traps */ 508. 	if (In_sokoban(&u.uz) &&  509.  			(ttype == PIT || ttype == SPIKED_PIT || ttype == HOLE || 510. 			ttype == TRAPDOOR)) { 511. 	    /* The "air currents" message is still appropriate -- even when 512. 	     * the hero isn't flying or levitating -- because it conveys the 513. 	     * reason why the player cannot escape the trap with a dexterity 514. 	     * check, clinging to the ceiling, etc. 515. 	     */  516.  	    pline("Air currents pull you down into %s %s!",  517.  	    	a_your[trap->madeby_u],  518.  	    	defsyms[trap_to_defsym(ttype)].explanation); 519. 	    /* then proceed to normal trap effect */ 520. 	} else if (already_seen) { 521. 	    if ((Levitation || Flying) &&  522.  		    (ttype == PIT || ttype == SPIKED_PIT || ttype == HOLE || 523. 		    ttype == BEAR_TRAP)) { 524. 		You("%s over %s %s.",  525.  		    Levitation ? "float" : "fly",  526.  		    a_your[trap->madeby_u],  527.  		    defsyms[trap_to_defsym(ttype)].explanation); 528. 		return; 529. 	    }  530.  	    if(!Fumbling && ttype != MAGIC_PORTAL && ttype != ANTI_MAGIC &&  531.  		(!rn2(5) || 532. 	    ((ttype == PIT || ttype == SPIKED_PIT) && is_clinger(youmonst.data)))) { 533. 		You("escape %s %s.",  534.  		    (ttype == ARROW_TRAP && !trap->madeby_u) ? "an" :  535.  			a_your[trap->madeby_u],  536.  		    defsyms[trap_to_defsym(ttype)].explanation); 537. 		return; 538. 	    }  539.  	}  540.   541.  	switch(ttype) { 542. 	    case ARROW_TRAP: 543. 		seetrap(trap); 544. 		pline("An arrow shoots out at you!"); 545. 		otmp = mksobj(ARROW, TRUE, FALSE); 546. 		otmp->quan = 1L; 547. 		otmp->owt = weight(otmp); 548. 		otmp->opoisoned = 0; 549. #ifdef STEED 550. 		if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) /* nothing */; 551. 		else 552. #endif 553. 		if (thitu(8, dmgval(otmp, &youmonst), otmp, "arrow")) { 554. 		    obfree(otmp, (struct obj *)0); 555. 		} else { 556. 		    place_object(otmp, u.ux, u.uy); 557. 		    if (!Blind) otmp->dknown = 1; 558. 		    stackobj(otmp); 559. 		    newsym(u.ux, u.uy); 560. 		}  561.  		break; 562. 	    case DART_TRAP: 563. 		seetrap(trap); 564. 		pline("A little dart shoots out at you!"); 565. 		otmp = mksobj(DART, TRUE, FALSE); 566. 		otmp->quan = 1L; 567. 		otmp->owt = weight(otmp); 568. 		if (!rn2(6)) otmp->opoisoned = 1; 569. #ifdef STEED 570. 		if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) /* nothing */; 571. 		else 572. #endif 573. 		if (thitu(7, dmgval(otmp, &youmonst), otmp, "little dart")) { 574. 		    if (otmp->opoisoned) 575. 			poisoned("dart",A_CON,"poison dart",10); 576. 		    obfree(otmp, (struct obj *)0); 577. 		} else { 578. 		    place_object(otmp, u.ux, u.uy); 579. 		    if (!Blind) otmp->dknown = 1; 580. 		    stackobj(otmp); 581. 		    newsym(u.ux, u.uy); 582. 		}  583.  		break; 584. 	    case ROCKTRAP: 585. 		{  586.  		    int dmg = d(2,6); /* should be std ROCK dmg? */ 587.   588.  		    seetrap(trap); 589. 		    otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE, FALSE); 590. 		    otmp->quan = 1L; 591. 		    otmp->owt = weight(otmp); 592.  593.      pline("A trap door in the %s opens and a rock falls on your %s!",  594.  			    ceiling(u.ux,u.uy),  595.  			    body_part(HEAD)); 596.  597.  		    if (uarmh) { 598. 			if(is_metallic(uarmh)) { 599. 			    pline("Fortunately, you are wearing a hard helmet."); 600. 			    dmg = 2; 601. 			} else if (flags.verbose) { 602. 			    Your("%s does not protect you.", xname(uarmh)); 603. 			}  604.  		    }  605.   606.  		    if (!Blind) otmp->dknown = 1; 607. 		    stackobj(otmp); 608. 		    newsym(u.ux,u.uy);	/* map the rock */ 609.  610.  		    losehp(dmg, "falling rock", KILLED_BY_AN); 611. 		    exercise(A_STR, FALSE); 612. 		}  613.  		break; 614.  615.  	    case SQKY_BOARD:	    /* stepped on a squeaky board */ 616. 		if (Levitation || Flying) { 617. 		    if (!Blind) { 618. 			seetrap(trap); 619. 			if (Hallucination) 620. 				You("notice a crease in the linoleum."); 621. 			else 622. 				You("notice a loose board below you."); 623. 		    }  624.  		} else { 625. 		    seetrap(trap); 626. 		    pline("A board beneath you squeaks loudly."); 627. 		    wake_nearby; 628. 		}  629.  		break; 630.  631.  	    case BEAR_TRAP: 632. 		if(Levitation || Flying) break; 633. 		seetrap(trap); 634. 		if(amorphous(youmonst.data) || is_whirly(youmonst.data) ||  635.  						    unsolid(youmonst.data)) { 636. 		    pline("%s bear trap closes harmlessly through you.",  637.  			    A_Your[trap->madeby_u]); 638. 		    break; 639. 		}  640.  		if(  641.  #ifdef STEED  642.  		   !u.usteed &&  643.  #endif  644.  		   youmonst.data->msize <= MZ_SMALL) { 645. 		    pline("%s bear trap closes harmlessly over you.",  646.  			    A_Your[trap->madeby_u]); 647. 		    break; 648. 		}  649.  		u.utrap = rn1(4, 4); 650. 		u.utraptype = TT_BEARTRAP; 651. #ifdef STEED 652. 		if (u.usteed) { 653. 		    pline("%s bear trap closes on %s %s!",  654.  			A_Your[trap->madeby_u], s_suffix(mon_nam(u.usteed)),  655.  			mbodypart(u.usteed, FOOT)); 656. 		} else 657. #endif 658. 		{  659.  		    pline("%s bear trap closes on your %s!",  660.  			    A_Your[trap->madeby_u], body_part(FOOT)); 661. 		    if(u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR) 662. 			You("howl in anger!"); 663. 		}  664.  		exercise(A_DEX, FALSE); 665. 		break; 666.  667.  	    case SLP_GAS_TRAP: 668. 		seetrap(trap); 669. 		if(Sleep_resistance || breathless(youmonst.data)) { 670. 		    You("are enveloped in a cloud of gas!"); 671. 		    break; 672. 		}  673.  		pline("A cloud of gas puts you to sleep!"); 674. 		flags.soundok = 0; 675. 		fall_asleep(-rnd(25), TRUE); 676. 		afternmv = Hear_again; 677. #ifdef STEED 678. 		(void) steedintrap(trap, (struct obj *)0); 679. #endif 680. 		break; 681.  682.  	    case RUST_TRAP: 683. 		seetrap(trap); 684. 		if (u.umonnum == PM_IRON_GOLEM) { 685. 		    pline("%s you!", A_gush_of_water_hits); 686. 		    You("are covered with rust!"); 687. 		    rehumanize; 688. 		    break; 689. 		} else if (u.umonnum == PM_GREMLIN && rn2(3)) { 690. 		    pline("%s you!", A_gush_of_water_hits); 691. 		    (void)split_mon(&youmonst, (struct monst *)0); 692. 		    break; 693. 		}  694.   695.  	    /* Unlike monsters, traps cannot aim their rust attacks at  696. * you, so instead of looping through and taking either the 697. 	     * first rustable one or the body, we take whatever we get, 698. 	     * even if it is not rustable. 699. 	     */  700.  		switch (rn2(5)) { 701. 		    case 0: 702. 			pline("%s you on the %s!", A_gush_of_water_hits,  703.  				    body_part(HEAD)); 704. 			(void) rust_dmg(uarmh, "helmet", 1, TRUE, &youmonst); 705. 			break; 706. 		    case 1: 707. 			pline("%s your left %s!", A_gush_of_water_hits,  708.  				    body_part(ARM)); 709. 			if (rust_dmg(uarms, "shield", 1, TRUE, &youmonst)) 710. 			    break; 711. 			if (u.twoweap || (uwep && bimanual(uwep))) 712. 			    erode_obj(u.twoweap ? uswapwep : uwep, FALSE, TRUE); 713. glovecheck:		(void) rust_dmg(uarmg, "gauntlets", 1, TRUE, &youmonst); 714. 			/* Not "metal gauntlets" since it gets called 715. 			 * even if it's leather for the message 716. 			 */  717.  			break; 718. 		    case 2: 719. 			pline("%s your right %s!", A_gush_of_water_hits,  720.  				    body_part(ARM)); 721. 			erode_obj(uwep, FALSE, TRUE); 722. 			goto glovecheck; 723. 		    default: 724. 			pline("%s you!", A_gush_of_water_hits); 725. 			for (otmp=invent; otmp; otmp = otmp->nobj) 726. 				    (void) snuff_lit(otmp); 727. 			if (uarmc) 728. 			    (void) rust_dmg(uarmc, cloak_simple_name(uarmc),  729.  						1, TRUE, &youmonst); 730. 			else if (uarm) 731. 			    (void) rust_dmg(uarm, "armor", 1, TRUE, &youmonst); 732. #ifdef TOURIST 733. 			else if (uarmu) 734. 			    (void) rust_dmg(uarmu, "shirt", 1, TRUE, &youmonst); 735. #endif 736. 		}  737.  		update_inventory; 738. 		break; 739.  740.  	    case FIRE_TRAP: 741. 		seetrap(trap); 742. 		dofiretrap((struct obj *)0); 743. 		break; 744.  745.  	    case PIT: 746. 	    case SPIKED_PIT: 747. 		/* KMH -- You can't escape the Sokoban level traps */ 748. 		if (!In_sokoban(&u.uz) && (Levitation || Flying)) break; 749. 		seetrap(trap); 750. 		if (!In_sokoban(&u.uz) && is_clinger(youmonst.data)) { 751. 		    if(trap->tseen) { 752. 			You("see %s %spit below you.", a_your[trap->madeby_u],  753.  			    ttype == SPIKED_PIT ? "spiked " : ""); 754. 		    } else { 755. 			pline("%s pit %sopens up under you!",  756.  			    A_Your[trap->madeby_u],  757.  			    ttype == SPIKED_PIT ? "full of spikes " : ""); 758. 			You("don't fall in!"); 759. 		    }  760.  		    break; 761. 		}  762.  		if (!In_sokoban(&u.uz)) { 763. 		   char verbbuf[BUFSZ]; 764. #ifdef STEED 765. 		   if (u.usteed) 766. 		   	Sprintf(verbbuf,"lead %s",  767.  				x_monnam(u.usteed, 768. 					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 769. 				 	 "poor", SUPPRESS_SADDLE, FALSE)); 770. 		   else 771. #endif 772. 		    Strcpy(verbbuf,"fall"); 773. 		   You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]); 774. 		}  775.  		/* wumpus reference */ 776. 		if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once &&  777.  			In_quest(&u.uz) && Is_qlocate(&u.uz)) { 778. 		    pline("Fortunately it has a bottom after all..."); 779. 		    trap->once = 1; 780. 		} else if (u.umonnum == PM_PIT_VIPER ||  781.  			u.umonnum == PM_PIT_FIEND) 782. 		    pline("How pitiful.  Isn't that the pits?"); 783. 		if (ttype == SPIKED_PIT) { 784. 		    char *predicament = "on a set of sharp iron spikes"; 785. #ifdef STEED 786. 		    if (u.usteed) { 787. 			pline("%s lands %s!",  788.  				upstart(x_monnam(u.usteed,  789.  					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE,  790.  				 	 "poor", SUPPRESS_SADDLE, FALSE)), predicament); 791. 		    } else 792. #endif 793. 		    You("land %s!", predicament); 794. 		}  795.  		if (!Passes_walls) 796. 		    u.utrap = rn1(6,2); 797. 		u.utraptype = TT_PIT; 798. #ifdef STEED 799. 		if (!steedintrap(trap, (struct obj *)0)) { 800. #endif 801. 		if (ttype == SPIKED_PIT) { 802. 		    losehp(rnd(10),"fell into a pit of iron spikes",  803.  			NO_KILLER_PREFIX); 804. 		    if (!rn2(6)) 805. 			poisoned("spikes", A_STR, "fall onto poison spikes", 8); 806. 		} else 807. 		    losehp(rnd(6),"fell into a pit", NO_KILLER_PREFIX); 808. 		if (Punished && !carried(uball)) { 809. 		    unplacebc; 810. 		    ballfall; 811. 		    placebc; 812. 		}  813.  		selftouch("Falling, you"); 814. 		vision_full_recalc = 1;	/* vision limits change */ 815. 		exercise(A_STR, FALSE); 816. 		exercise(A_DEX, FALSE); 817. #ifdef STEED 818. 		}  819.  #endif 820. 		break; 821. 	    case HOLE: 822. 	    case TRAPDOOR: 823. 		seetrap(trap); 824. 		if (!Can_fall_thru(&u.uz)) { 825. 		    impossible("dotrap: %ss cannot exist on this level.",  826.  			       defsyms[trap_to_defsym(ttype)].explanation); 827. 		    break;		/* don't activate it after all */ 828. 		}  829.  		fall_through(TRUE); 830. 		break; 831.  832.  	    case TELEP_TRAP: 833. 		seetrap(trap); 834. 		tele_trap(trap); 835. 		break; 836. 	    case LEVEL_TELEP: 837. 		seetrap(trap); 838. 		level_tele_trap(trap); 839. 		break; 840.  841.  	    case WEB: /* Our luckless player has stumbled into a web. */ 842.  		seetrap(trap); 843. 		if (amorphous(youmonst.data) || is_whirly(youmonst.data) ||  844.  						    unsolid(youmonst.data)) { 845. 		    if (acidic(youmonst.data) || u.umonnum == PM_GELATINOUS_CUBE ||  846.  			u.umonnum == PM_FIRE_ELEMENTAL) { 847. 			if (webmsgok) 848. 			    You("%s %s spider web!",  849.  				(u.umonnum == PM_FIRE_ELEMENTAL) ? "burn" : "dissolve",  850.  				a_your[trap->madeby_u]); 851. 			deltrap(trap); 852. 			newsym(u.ux,u.uy); 853. 			break; 854. 		    }  855.  		    if (webmsgok) You("flow through %s spider web.",  856.  			    a_your[trap->madeby_u]); 857. 		    break; 858. 		}  859.  		if (webmaker(youmonst.data)) { 860. 		    if (webmsgok) 861. 		    	pline(trap->madeby_u ? "You take a walk on your web."  862.  					 : "There is a spider web here."); 863. 		    break; 864. 		}  865.  		if (webmsgok) { 866. 		   char verbbuf[BUFSZ]; 867. 		   verbbuf[0] = '\0'; 868. #ifdef STEED 869. 		   if (u.usteed) 870. 		   	Sprintf(verbbuf,"lead %s",  871.  				x_monnam(u.usteed, 872. 					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 873. 				 	 "poor", SUPPRESS_SADDLE, FALSE)); 874. 		   else 875. #endif 876. 			  877.  		    Sprintf(verbbuf, "%s", Levitation ? (const char *)"float" :  878.  		      		locomotion(youmonst.data, "stumble")); 879. 		   You("%s into %s spider web!", verbbuf, a_your[trap->madeby_u]); 880. 		}  881.  		u.utraptype = TT_WEB; 882.  883.  		/* Time stuck in the web depends on your strength. */ 884.  		{  885.  		    register int str = ACURR(A_STR); 886.  887.  		    if (str <= 3) u.utrap = rn1(6,6); 888. 		    else if (str < 6) u.utrap = rn1(6,4); 889. 		    else if (str < 9) u.utrap = rn1(4,4); 890. 		    else if (str < 12) u.utrap = rn1(4,2); 891. 		    else if (str < 15) u.utrap = rn1(2,2); 892. 		    else if (str < 18) u.utrap = rnd(2); 893. 		    else if (str < 69) u.utrap = 1; 894. 		    else { 895. 			u.utrap = 0; 896. 			if (webmsgok) 897. 				You("tear through %s web!", a_your[trap->madeby_u]); 898. 			deltrap(trap); 899. 			newsym(u.ux,u.uy);	/* get rid of trap symbol */ 900. 		    }  901.  		}  902.  		break; 903.  904.  	    case STATUE_TRAP: 905. 		(void) activate_statue_trap(trap, u.ux, u.uy, FALSE); 906. 		break; 907.  908.  	    case MAGIC_TRAP:	    /* A magic trap. */ 909.  		seetrap(trap); 910. 		if (!rn2(30)) { 911. 		    deltrap(trap); 912. 		    newsym(u.ux,u.uy);	/* update position */ 913. 		    You("are caught in a magical explosion!"); 914. 		    losehp(rnd(10), "magical explosion", KILLED_BY_AN); 915. 		    Your("body absorbs some of the magical energy!"); 916. 		    u.uen = (u.uenmax += 2); 917. 		} else domagictrap; 918. #ifdef STEED 919. 		(void) steedintrap(trap, (struct obj *)0); 920. #endif 921. 		break; 922.  923.  	    case ANTI_MAGIC: 924. 		seetrap(trap); 925. 		if(Antimagic) { 926. 		    shieldeff(u.ux, u.uy); 927. 		    You_feel("momentarily lethargic."); 928. 		} else drain_en(rnd(u.ulevel) + 1); 929. 		break; 930.  931.  	    case POLY_TRAP: { 932. 	        char verbbuf[BUFSZ]; 933. 		seetrap(trap); 934. #ifdef STEED 935. 		if (u.usteed) 936. 			Sprintf(verbbuf, "lead %s",  937.  				x_monnam(u.usteed, 938. 					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 939. 				 	 (char *)0, SUPPRESS_SADDLE, FALSE)); 940. 		else 941. #endif 942. 		 Sprintf(verbbuf,"%s",  943.  		    Levitation ? (const char *)"float" :  944.  		    locomotion(youmonst.data, "step")); 945. 		You("%s onto a polymorph trap!", verbbuf); 946. 		if(Antimagic || Unchanging) { 947. 		    shieldeff(u.ux, u.uy); 948. 		    You_feel("momentarily different."); 949. 		    /* Trap did nothing; don't remove it --KAA */ 950. 		} else { 951. #ifdef STEED 952. 		    (void) steedintrap(trap, (struct obj *)0); 953. #endif 954. 		    deltrap(trap);	/* delete trap before polymorph */ 955. 		    newsym(u.ux,u.uy);	/* get rid of trap symbol */ 956. 		    You_feel("a change coming over you."); 957. 		    polyself(FALSE); 958. 		}  959.  		break; 960. 	    }  961.  	    case LANDMINE: 962. 		if (Levitation || Flying) { 963. 		    if (!already_seen && rn2(3)) break; 964. 		    seetrap(trap); 965. 		    pline("%s %s in a pile of soil below you.",  966.  			    already_seen ? "There is" : "You discover",  967.  			    trap->madeby_u ? "the trigger of your mine" :  968.  					     "a trigger"); 969. 		    if (already_seen && rn2(3)) break; 970. 		    pline("KAABLAMM!!!  The air currents set %s%s off!",  971.  			    already_seen ? a_your[trap->madeby_u] : "",  972.  			    already_seen ? " land mine" : "it"); 973. 		} else { 974. #ifdef STEED 975. 		    /* prevent landmine from killing steed, throwing you to  976. * the ground, and you being affected again by the same 977. 		     * mine because it hasn't been deleted yet 978. 		     */  979.  		    static boolean recursive_mine = FALSE; 980.  981.  		    if (recursive_mine) break; 982. #endif 983. 		    seetrap(trap); 984. 		    pline("KAABLAMM!!!  You triggered %s land mine!",  985.  					    a_your[trap->madeby_u]); 986. #ifdef STEED 987. 		    recursive_mine = TRUE; 988. 		    (void) steedintrap(trap, (struct obj *)0); 989. 		    recursive_mine = FALSE; 990. #endif 991. 		    set_wounded_legs(LEFT_SIDE, rn1(35, 41)); 992. 		    set_wounded_legs(RIGHT_SIDE, rn1(35, 41)); 993. 		    exercise(A_DEX, FALSE); 994. 		}  995.  		blow_up_landmine(trap); 996. 		newsym(u.ux,u.uy);		/* update trap symbol */ 997. 		losehp(rnd(16), "land mine", KILLED_BY_AN); 998. 		/* fall recursively into the pit... */ 999.  		if ((trap = t_at(u.ux, u.uy)) != 0) dotrap(trap, 0); 1000. 		fill_pit(u.ux, u.uy); 1001. 		break; 1002. 1003. 	    case ROLLING_BOULDER_TRAP: 1004. 		seetrap(trap); 1005. 		pline("Click! You trigger a rolling boulder trap!"); 1006. 		if(!launch_obj(BOULDER, trap->launch.x, trap->launch.y, 1007. trap->launch2.x,trap->launch2.y, ROLL)) { 1008. 		   deltrap(trap); 1009. 		   newsym(u.ux,u.uy);	/* get rid of trap symbol */ 1010. 		   pline("Fortunately for you, no boulder was released."); 1011. 		} 1012. 		break; 1013. 1014. 	    case MAGIC_PORTAL: 1015. 		seetrap(trap); 1016. 		domagicportal(trap); 1017. 		break; 1018. 1019. 	    default: 1020. 		seetrap(trap); 1021. 		impossible("You hit a trap of type %u", trap->ttyp); 1022. 	} 1023. }  1024.  1025. #ifdef STEED 1026. STATIC_OVL int 1027. steedintrap(trap, otmp) 1028. struct trap *trap; 1029. struct obj *otmp; 1030. { 1031. 	struct monst *mtmp = u.usteed; 1032. 	struct permonst *mptr; 1033. 	int tt; 1034. 	boolean in_sight; 1035. 	boolean trapkilled = FALSE; 1036. 	boolean steedhit = FALSE; 1037. 1038. 	if (!u.usteed || !trap) return 0; 1039. 	mptr = mtmp->data; 1040. 	tt = trap->ttyp; 1041. 	mtmp->mx = u.ux; 1042. 	mtmp->my = u.uy; 1043. 1044. 	in_sight = !Blind; 1045. 	switch (tt) { 1046. 		case ARROW_TRAP: 1047. 			if(!otmp) { 1048. 				impossible("steed hit by non-existant arrow?"); 1049. 				return 0; 1050. 			} 1051. 			if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE; 1052. 			steedhit = TRUE; 1053. 			break; 1054. 		case DART_TRAP: 1055. 			if(!otmp) { 1056. 				impossible("steed hit by non-existant dart?"); 1057. 				return 0; 1058. 			} 1059. 			if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE; 1060. 			steedhit = TRUE; 1061. 			break; 1062. 		case SLP_GAS_TRAP: 1063. 		   if (!resists_sleep(mtmp) && !breathless(mptr) &&  1064. 				!mtmp->msleeping && mtmp->mcanmove) { 1065. 			   mtmp->mcanmove = 0; 1066. 			   mtmp->mfrozen = rnd(25); 1067. 			   if (in_sight) { 1068. 				pline("%s suddenly falls asleep!", 1069. 				      Monnam(mtmp)); 1070. 			   }  1071. 			}  1072. 			steedhit = TRUE; 1073. 			break; 1074. 		case LANDMINE: 1075. 			if (thitm(0, mtmp, (struct obj *)0, rnd(16))) 1076. 			   trapkilled = TRUE; 1077. 			steedhit = TRUE; 1078. 			break; 1079. 		case PIT: 1080. 		case SPIKED_PIT: 1081. 			if (mtmp->mhp <= 0 || 1082. 				thitm(0, mtmp, (struct obj *)0, 1083. 				     rnd((tt == PIT) ? 6 : 10))) 1084. 			   trapkilled = TRUE; 1085. 			steedhit = TRUE; 1086. 			break; 1087. 		case POLY_TRAP: 1088. 		   if (!resists_magm(mtmp)) { 1089. 			if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) { 1090. 			(void) newcham(mtmp, (struct permonst *)0, FALSE); 1091. 			if (!can_saddle(mtmp) || !can_ride(mtmp)) { 1092. 				dismount_steed(DISMOUNT_POLY); 1093. 			} else { 1094. 				You("have to adjust yourself in the saddle on %s.", 1095. 					x_monnam(mtmp, 1096. 					 mtmp->mnamelth ? ARTICLE_NONE : ARTICLE_A, 1097. 				 	 (char *)0, SUPPRESS_SADDLE, FALSE)); 1098. 			} 1099. 				  1100. 		    }  1101. 		    steedhit = TRUE; 1102. 		   break; 1103. 		default: 1104. 			return 0; 1105. 	   }  1106. 	}  1107. 	if(trapkilled) { 1108. 		dismount_steed(DISMOUNT_POLY); 1109. 		return 2; 1110. 	} 1111. 	else if(steedhit) return 1; 1112. 	else return 0; 1113. } 1114. #endif /*STEED*/ 1115. 1116. /* some actions common to both player and monsters for triggered landmine */ 1117. void 1118. blow_up_landmine(trap) 1119. struct trap *trap; 1120. { 1121. 	scatter(trap->tx, trap->ty, 4,  1122. 		MAY_DESTROY | MAY_HIT | MAY_FRACTURE | VIS_EFFECTS,  1123. 		(struct obj *)0); 1124. 	del_engr_at(trap->tx, trap->ty); 1125. 	wake_nearto(trap->tx, trap->ty, 400); 1126. 	if (IS_DOOR(levl[trap->tx][trap->ty].typ)) 1127. 	   levl[trap->tx][trap->ty].doormask = D_BROKEN; 1128. 	/* TODO: destroy drawbridge if present */ 1129. 	/* caller may subsequently fill pit, e.g. with a boulder */ 1130. 	trap->ttyp = PIT;		/* explosion creates a pit */ 1131. 	trap->madeby_u = FALSE;		/* resulting pit isn't yours */ 1132. } 1133.  1134. #endif /* OVLB */ 1135. #ifdef OVL3 1136. 1137. /*  1138.  * Move obj from (x1,y1) to (x2,y2) 1139. *  1140.  * Return 0 if no object was launched. 1141. *        1 if an object was launched and placed somewhere. 1142. *        2 if an object was launched, but used up. 1143. */  1144. int 1145. launch_obj(otyp, x1, y1, x2, y2, style) 1146. short otyp; 1147. register int x1,y1,x2,y2; 1148. int style; 1149. { 1150. 	register struct monst *mtmp; 1151. 	register struct obj *otmp, *otmp2; 1152. 	register int dx,dy; 1153. 	struct obj *singleobj; 1154. 	boolean used_up = FALSE; 1155. 	boolean otherside = FALSE; 1156. 	int dist; 1157. 	int tmp; 1158. 	int delaycnt = 0; 1159. 1160. 	otmp = sobj_at(otyp, x1, y1); 1161. 	/* Try the other side too, for rolling boulder traps */ 1162. 	if (!otmp && otyp == BOULDER) { 1163. 		otherside = TRUE; 1164. 		otmp = sobj_at(otyp, x2, y2); 1165. 	} 1166. 	if (!otmp) return 0; 1167. 	if (otherside) {	/* swap 'em */ 1168. 		int tx, ty; 1169. 1170. 		tx = x1; ty = y1; 1171. 		x1 = x2; y1 = y2; 1172. 		x2 = tx; y2 = ty; 1173. 	} 1174.  1175. 	if (otmp->quan == 1L) { 1176. 	   obj_extract_self(otmp); 1177. 	   singleobj = otmp; 1178. 	   otmp = (struct obj *) 0; 1179. 	} else { 1180. 	   singleobj = splitobj(otmp, 1L); 1181. 	   obj_extract_self(singleobj); 1182. 	} 1183. 	newsym(x1,y1); 1184. 	/* in case you're using a pick-axe to chop the boulder that's being 1185. 	  launched (perhaps a monster triggered it), destroy context so that 1186. 	  next dig attempt never thinks you're resuming previous effort */ 1187. 	if ((otyp == BOULDER || otyp == STATUE) && 1188. 	    singleobj->ox == digging.pos.x && singleobj->oy == digging.pos.y)  1189. (void) memset((genericptr_t)&digging, 0, sizeof digging); 1190. 1191. 	dist = distmin(x1,y1,x2,y2); 1192. 	bhitpos.x = x1; 1193. 	bhitpos.y = y1; 1194. 	dx = sgn(x2 - x1); 1195. 	dy = sgn(y2 - y1); 1196. 	switch (style) { 1197. 	   case ROLL: 1198. 			delaycnt = 2; 1199. 			/* fall through */ 1200. 	   default: 1201. 			if (!delaycnt) delaycnt = 1; 1202. 			if (!cansee(bhitpos.x,bhitpos.y)) curs_on_u; 1203. 			tmp_at(DISP_FLASH, obj_to_glyph(singleobj)); 1204. 			tmp_at(bhitpos.x, bhitpos.y); 1205. 	} 1206.  1207. 	/* Set the object in motion */ 1208. 	while(dist-- > 0 && !used_up) { 1209. 		struct trap *t; 1210. 		tmp_at(bhitpos.x, bhitpos.y); 1211. 		tmp = delaycnt; 1212. 1213. 		/* dstage@u.washington.edu -- Delay only if hero sees it */ 1214. 		if (cansee(bhitpos.x, bhitpos.y)) 1215. 			while (tmp-- > 0) delay_output; 1216. 1217. 		bhitpos.x += dx; 1218. 		bhitpos.y += dy; 1219. 		t = t_at(bhitpos.x, bhitpos.y); 1220. 		 1221. 		if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) { 1222. 			if (otyp == BOULDER && throws_rocks(mtmp->data)) { 1223. 			   if (rn2(3)) { 1224. 				pline("%s snatches the boulder.", 1225. 					Monnam(mtmp)); 1226. 				(void) mpickobj(mtmp, singleobj); 1227. 				used_up = TRUE; 1228. 				break; 1229. 			   }  1230. 			}  1231. 			if (ohitmon(mtmp,singleobj, 1232. 					(style==ROLL) ? -1 : dist, FALSE)) { 1233. 				used_up = TRUE; 1234. 				break; 1235. 			} 1236. 		} else if (bhitpos.x == u.ux && bhitpos.y == u.uy) { 1237. 			if (multi) nomul(0); 1238. 			if (thitu(9 + singleobj->spe, 1239. 				 dmgval(singleobj, &youmonst), 1240. 				 singleobj, (char *)0)) 1241. 			   stop_occupation; 1242. 		} 1243. 		if (style == ROLL) { 1244. 		   if (down_gate(bhitpos.x, bhitpos.y) != -1) { 1245. 		      if (ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)){ 1246. 				used_up = TRUE; 1247. 				break; 1248. 			} 1249. 		    }  1250. 		    if (t && otyp == BOULDER) { 1251. 			switch(t->ttyp) { 1252. 			case LANDMINE: 1253. 			   if (rn2(10) > 2) { 1254. 			 	pline(  1255. 				  "KAABLAMM!!!%s",  1256. 				  cansee(bhitpos.x, bhitpos.y) ?  1257. 					" The rolling boulder triggers a land mine." : ""); 1258. 				deltrap(t); 1259. 				del_engr_at(bhitpos.x,bhitpos.y); 1260. 				place_object(singleobj, bhitpos.x, bhitpos.y); 1261. 				fracture_rock(singleobj); 1262. 				scatter(bhitpos.x,bhitpos.y, 4, 1263. 					MAY_DESTROY|MAY_HIT|MAY_FRACTURE|VIS_EFFECTS,  1264. 					(struct obj *)0); 1265. 				if (cansee(bhitpos.x,bhitpos.y)) 1266. 					newsym(bhitpos.x,bhitpos.y); 1267. 			       used_up = TRUE; 1268. 			   }  1269. 			    break; 1270. 			case LEVEL_TELEP: 1271. 			case TELEP_TRAP: 1272. 			   if (cansee(bhitpos.x, bhitpos.y)) 1273. 			   	pline("Suddenly the rolling boulder disappears!"); 1274. 			   else 1275. 			   	You_hear("a rumbling stop abruptly."); 1276. 			   if (t->ttyp == TELEP_TRAP) 1277. 				rloco(singleobj); 1278. 			   else { 1279. 				int newlev = random_teleport_level; 1280. 				d_level dest; 1281. 1282. 				if (newlev == depth(&u.uz) || In_endgame(&u.uz)) 1283. 				   continue; 1284. 				add_to_migration(singleobj); 1285. 				get_level(&dest, newlev); 1286. 				singleobj->ox = dest.dnum; 1287. 				singleobj->oy = dest.dlevel; 1288. 				singleobj->owornmask = (long)MIGR_RANDOM; 1289. 			   }  1290. 		    	    seetrap(t); 1291. 			   used_up = TRUE; 1292. 			   break; 1293. 			} 1294. 			if (used_up) break; 1295. 		   }  1296. 		    if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) { 1297. 			used_up = TRUE; 1298. 			break; 1299. 		   }  1300. 		    if (otyp == BOULDER &&  1301. 		       (otmp2 = sobj_at(BOULDER, bhitpos.x, bhitpos.y)) != 0) { 1302. 			char *bmsg = 1303. 				" as one boulder sets another in motion"; 1304. 		   	You_hear("a loud crash%s!",  1305. 				cansee(bhitpos.x, bhitpos.y) ? bmsg : ""); 1306. 			obj_extract_self(otmp2); 1307. 			place_object(singleobj, bhitpos.x, bhitpos.y); 1308. 			singleobj = otmp2; 1309. 			otmp2 = (struct obj *)0; 1310. 			wake_nearto(bhitpos.x, bhitpos.y, 10*10); 1311. 		   }  1312. 		}  1313. 		if (otyp == BOULDER && closed_door(bhitpos.x,bhitpos.y)) { 1314. 			if (cansee(bhitpos.x, bhitpos.y)) 1315. 				pline_The("boulder crashes through a door."); 1316. 			levl[bhitpos.x][bhitpos.y].doormask = D_BROKEN; 1317. 			if (dist) unblock_point(bhitpos.x, bhitpos.y); 1318. 		} 1319. 	}  1320. 	tmp_at(DISP_END, 0); 1321. 	if (!used_up) { 1322. 		place_object(singleobj, x2,y2); 1323. 		newsym(x2,y2); 1324. 		return 1; 1325. 	} else 1326. 		return 2; 1327. } 1328. #endif /* OVL3 */ 1329. #ifdef OVLB 1330. 1331. void 1332. seetrap(trap) 1333. 	register struct trap *trap; 1334. { 1335. 	if(!trap->tseen) { 1336. 	   trap->tseen = 1; 1337. 	   newsym(trap->tx, trap->ty); 1338. 	} 1339. }  1340.  1341. #endif /* OVLB */ 1342. #ifdef OVL3 1343. 1344. STATIC_OVL int 1345. mkroll_launch(ttmp, x, y, otyp, ocount) 1346. struct trap *ttmp; 1347. xchar x,y; 1348. short otyp; 1349. long ocount; 1350. { 1351. 	struct obj *otmp; 1352. 	register int tmp; 1353. 	schar dx,dy; 1354. 	int distance; 1355. 	coord cc; 1356. 	coord bcc; 1357. 	int trycount = 0; 1358. 	boolean success = FALSE; 1359. 	int mindist = 4; 1360. 1361. 	if (ttmp->ttyp == ROLLING_BOULDER_TRAP) mindist = 2; 1362. 	distance = rn1(5,4);   /* 4..8 away */ 1363. 	tmp = rn2(8);		/* randomly pick a direction to try first */ 1364. 	while (distance >= mindist) { 1365. 		dx = xdir[tmp]; 1366. 		dy = ydir[tmp]; 1367. 		cc.x = x; cc.y = y; 1368. /* Prevent boulder from being placed on water */ 1369. 		if (ttmp->ttyp == ROLLING_BOULDER_TRAP 1370. 				&& is_pool(x+distance*dx,y+distance*dy)) 1371. 			success = FALSE; 1372. 		else success = isclearpath(&cc, distance, dx, dy); 1373. 		if (ttmp->ttyp == ROLLING_BOULDER_TRAP) { 1374. 			boolean success_otherway; 1375. 			bcc.x = x; bcc.y = y; 1376. success_otherway = isclearpath(&bcc, distance, 1377. 						-(dx), -(dy)); 1378. 			if (!success_otherway) success = FALSE; 1379. 		} 1380. 		if (success) break; 1381. 		if (++tmp > 7) tmp = 0; 1382. 		if ((++trycount % 8) == 0) --distance; 1383. 	} 1384. 	if (!success) { 1385. 	   /* create the trap without any ammo, launch pt at trap location */ 1386. 		cc.x = bcc.x = x; 1387. cc.y = bcc.y = y; 1388. } else { 1389. 		otmp = mksobj(otyp, TRUE, FALSE); 1390. 		otmp->quan = ocount; 1391. 		otmp->owt = weight(otmp); 1392. 		place_object(otmp, cc.x, cc.y); 1393. 		stackobj(otmp); 1394. 	} 1395. 	ttmp->launch.x = cc.x;  1396. ttmp->launch.y = cc.y; 1397. if (ttmp->ttyp == ROLLING_BOULDER_TRAP) { 1398. 		ttmp->launch2.x = bcc.x; 1399. ttmp->launch2.y = bcc.y; 1400. } else 1401. 		ttmp->launch_otyp = otyp; 1402. 	newsym(ttmp->launch.x, ttmp->launch.y); 1403. 	return 1; 1404. } 1405.  1406. STATIC_OVL boolean 1407. isclearpath(cc,distance,dx,dy) 1408. coord *cc; 1409. int distance; 1410. schar dx,dy; 1411. { 1412. 	uchar typ; 1413. 	xchar x, y; 1414. 1415. 	x = cc->x; 1416. 	y = cc->y; 1417. 	while (distance-- > 0) { 1418. 		x += dx; 1419. 		y += dy; 1420. 		typ = levl[x][y].typ; 1421. 		if (!isok(x,y) || !ZAP_POS(typ) || closed_door(x,y)) 1422. 			return FALSE; 1423. 	} 1424. 	cc->x = x;  1425. cc->y = y; 1426. return TRUE; 1427. } 1428. #endif /* OVL3 */ 1429. #ifdef OVL1 1430. 1431. int 1432. mintrap(mtmp) 1433. register struct monst *mtmp; 1434. { 1435. 	register struct trap *trap = t_at(mtmp->mx, mtmp->my); 1436. 	boolean trapkilled = FALSE; 1437. 	struct permonst *mptr = mtmp->data; 1438. 	struct obj *otmp; 1439. 1440. 	if (!trap) { 1441. 	   mtmp->mtrapped = 0;	/* perhaps teleported? */ 1442. 	} else if (mtmp->mtrapped) {	/* is currently in the trap */ 1443. 	   if (!trap->tseen &&  1444. 		cansee(mtmp->mx, mtmp->my) && canseemon(mtmp) &&  1445. 		(trap->ttyp == SPIKED_PIT || trap->ttyp == BEAR_TRAP || 1446. 		 trap->ttyp == HOLE || trap->ttyp == PIT || 1447. 		 trap->ttyp == WEB)) { 1448. 		/* If you come upon an obviously trapped monster, then 1449. 		 * you must be able to see the trap it's in too. 1450. 		 */ 1451. 		seetrap(trap); 1452. 	   }  1453. 		  1454. 	    if (!rn2(40)) { 1455. 		if (sobj_at(BOULDER, mtmp->mx, mtmp->my) && 1456. 			(trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) { 1457. 		   if (!rn2(2)) { 1458. 			mtmp->mtrapped = 0; 1459. 			if (canseemon(mtmp)) 1460. 			   pline("%s pulls free...", Monnam(mtmp)); 1461. 			fill_pit(mtmp->mx, mtmp->my); 1462. 		   }  1463. 		} else { 1464. 		   mtmp->mtrapped = 0; 1465. 		} 1466. 	    } else if (metallivorous(mptr)) { 1467. 		if (trap->ttyp == BEAR_TRAP) { 1468. 		   if (canseemon(mtmp)) 1469. 			pline("%s eats a bear trap!", Monnam(mtmp)); 1470. 		   deltrap(trap); 1471. 		   mtmp->meating = 5; 1472. 		   mtmp->mtrapped = 0; 1473. 		} else if (trap->ttyp == SPIKED_PIT) { 1474. 		   if (canseemon(mtmp)) 1475. 			pline("%s munches on some spikes!", Monnam(mtmp)); 1476. 		   trap->ttyp = PIT; 1477. 		   mtmp->meating = 5; 1478. 		} 1479. 	    }  1480. 	} else { 1481. 	   register int tt = trap->ttyp; 1482. 	   boolean in_sight, tear_web, see_it, 1483. 		   inescapable = ((tt == HOLE || tt == PIT) &&  1484. 				   In_sokoban(&u.uz) && !trap->madeby_u); 1485. 	   const char *fallverb; 1486. 1487. 	    if (!inescapable &&  1488. 		    ((mtmp->mtrapseen & (1 << (tt-1))) != 0 || 1489. 			(tt == HOLE && !mindless(mtmp->data)))) { 1490. 		/* it has been in such a trap - perhaps it escapes */ 1491. 		if(rn2(4)) return(0); 1492. 	   } else { 1493. 		mtmp->mtrapseen |= (1 << (tt-1)); 1494. 	   }  1495. 	    /* Monster is aggravated by being trapped by you. 1496. 	      Recognizing who made the trap isn't completely 1497. 	      unreasonable; everybody has their own style. */ 1498. 	    if (trap->madeby_u && rnl(5)) setmangry(mtmp); 1499. 1500. 	    /* bug? `in_sight' ought to be split to distinguish between 1501. 	      trap_in_sight and can_see_victim to handle invisible monsters */ 1502. 	   in_sight = canseemon(mtmp); 1503. 	   switch (tt) { 1504. 		case ARROW_TRAP: 1505. 			otmp = mksobj(ARROW, TRUE, FALSE); 1506. 			otmp->quan = 1L; 1507. 			otmp->owt = weight(otmp); 1508. 			otmp->opoisoned = 0; 1509. 			if (in_sight) seetrap(trap); 1510. 			if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE; 1511. 			break; 1512. 		case DART_TRAP: 1513. 			otmp = mksobj(DART, TRUE, FALSE); 1514. 			otmp->quan = 1L; 1515. 			otmp->owt = weight(otmp); 1516. 			if (!rn2(6)) otmp->opoisoned = 1; 1517. 			if (in_sight) seetrap(trap); 1518. 			if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE; 1519. 			break; 1520. 		case ROCKTRAP: 1521. 			otmp = mksobj(ROCK, TRUE, FALSE); 1522. 			otmp->quan = 1L; 1523. 			otmp->owt = weight(otmp); 1524. 			if (in_sight) seetrap(trap); 1525. 			if (thitm(0, mtmp, otmp, d(2, 6))) 1526. 			   trapkilled = TRUE; 1527. 			break; 1528. 1529. 		case SQKY_BOARD: 1530. 			if(is_flyer(mptr)) break; 1531. 			/* stepped on a squeaky board */ 1532. 			if (in_sight) { 1533. 			   pline("A board beneath %s squeaks loudly.", mon_nam(mtmp)); 1534. 			   seetrap(trap); 1535. 			} else 1536. 			  You_hear("a distant squeak."); 1537. 			/* wake up nearby monsters */ 1538. 			wake_nearto(mtmp->mx, mtmp->my, 40); 1539. 			break; 1540. 1541. 		case BEAR_TRAP: 1542. 			if(mptr->msize > MZ_SMALL && 1543. 				!amorphous(mptr) && !is_flyer(mptr) &&  1544. 				!is_whirly(mptr) && !unsolid(mptr)) { 1545. 			   mtmp->mtrapped = 1; 1546. 			   if(in_sight) { 1547. 				pline("%s is caught in %s bear trap!", 1548. 				      Monnam(mtmp), a_your[trap->madeby_u]); 1549. 				seetrap(trap); 1550. 			   } else { 1551. 				if((mptr == &mons[PM_OWLBEAR] 1552. 				   || mptr == &mons[PM_BUGBEAR])  1553. 				   && flags.soundok) 1554. 				   You_hear("the roaring of an angry bear!"); 1555. 			   }  1556. 			}  1557. 			break; 1558. 1559. 		case SLP_GAS_TRAP: 1560. 		   if (!resists_sleep(mtmp) && !breathless(mptr) &&  1561. 				!mtmp->msleeping && mtmp->mcanmove) { 1562. 			   mtmp->mcanmove = 0; 1563. 			   mtmp->mfrozen = rnd(25); 1564. 			   if (in_sight) { 1565. 				pline("%s suddenly falls asleep!", 1566. 				      Monnam(mtmp)); 1567. 				seetrap(trap); 1568. 			   }  1569. 			}  1570. 			break; 1571. 1572. 		case RUST_TRAP: 1573. 		   {  1574. 			struct obj *target; 1575. 1576. 			if (in_sight) 1577. 			   seetrap(trap); 1578. 			switch (rn2(5)) { 1579. 			case 0: 1580. 			   if (in_sight) 1581. 				pline("%s %s on the %s!", A_gush_of_water_hits, 1582. 				    mon_nam(mtmp), mbodypart(mtmp, HEAD)); 1583. 			   target = which_armor(mtmp, W_ARMH); 1584. 			   (void) rust_dmg(target, "helmet", 1, TRUE, mtmp); 1585. 			   break; 1586. 			case 1: 1587. 			   if (in_sight) 1588. 				pline("%s %s's left %s!", A_gush_of_water_hits, 1589. 				    mon_nam(mtmp), mbodypart(mtmp, ARM)); 1590. 			   target = which_armor(mtmp, W_ARMS); 1591. 			   if (rust_dmg(target, "shield", 1, TRUE, mtmp)) 1592. 				break; 1593. 			   target = MON_WEP(mtmp); 1594. 			   if (target && bimanual(target)) 1595. 				erode_obj(target, FALSE, TRUE); 1596. glovecheck:		   target = which_armor(mtmp, W_ARMG); 1597. 			   (void) rust_dmg(target, "gauntlets", 1, TRUE, mtmp); 1598. 			   break; 1599. 			case 2: 1600. 			   if (in_sight) 1601. 				pline("%s %s's right %s!", A_gush_of_water_hits, 1602. 				    mon_nam(mtmp), mbodypart(mtmp, ARM)); 1603. 			   erode_obj(MON_WEP(mtmp), FALSE, TRUE); 1604. 			   goto glovecheck; 1605. 			default: 1606. 			   if (in_sight) 1607. 				pline("%s %s!", A_gush_of_water_hits, 1608. 				    mon_nam(mtmp)); 1609. 			   for (otmp=mtmp->minvent; otmp; otmp = otmp->nobj) 1610. 				(void) snuff_lit(otmp); 1611. 			   target = which_armor(mtmp, W_ARMC); 1612. 			   if (target) 1613. 				(void) rust_dmg(target, cloak_simple_name(target), 1614. 						 1, TRUE, mtmp); 1615. 			   else { 1616. 				target = which_armor(mtmp, W_ARM); 1617. 				if (target) 1618. 				   (void) rust_dmg(target, "armor", 1, TRUE, mtmp); 1619. #ifdef TOURIST 1620. 				else { 1621. 				   target = which_armor(mtmp, W_ARMU); 1622. 				   (void) rust_dmg(target, "shirt", 1, TRUE, mtmp); 1623. 				} 1624. #endif 1625. 			   }  1626. 			}  1627. 			if (mptr == &mons[PM_IRON_GOLEM]) { 1628. 				if (in_sight) 1629. 				   pline("%s falls to pieces!", Monnam(mtmp)); 1630. 				else if(mtmp->mtame) 1631. 				   pline("May %s rust in peace.",  1632. 								mon_nam(mtmp)); 1633. 				mondied(mtmp); 1634. 				if (mtmp->mhp <= 0) 1635. 					trapkilled = TRUE; 1636. 			} else if (mptr == &mons[PM_GREMLIN] && rn2(3)) { 1637. 				(void)split_mon(mtmp, (struct monst *)0); 1638. 			} 1639. 			break; 1640. 		   }  1641. 		case FIRE_TRAP: 1642. mfiretrap: 1643. 			see_it = cansee(mtmp->mx, mtmp->my); 1644. 			if (in_sight) 1645. 			   pline("A %s erupts from the %s under %s!",  1646. 				  tower_of_flame,  1647. 				  surface(mtmp->mx,mtmp->my), mon_nam(mtmp)); 1648. 			else if (see_it) /* evidently `mtmp' is invisible */ 1649. 			   You("see a %s erupt from the %s!",  1650. 				tower_of_flame, surface(mtmp->mx,mtmp->my)); 1651. 1652. 			if (resists_fire(mtmp)) { 1653. 			   if (in_sight) { 1654. 				shieldeff(mtmp->mx,mtmp->my); 1655. 				pline("%s is uninjured.", Monnam(mtmp)); 1656. 			   }  1657. 			} else { 1658. 			   int num = d(2,4); 1659. 1660. 			    if (thitm(0, mtmp, (struct obj *)0, num)) 1661. 				trapkilled = TRUE; 1662. 			   else 1663. 				/* we know mhp is at least `num' below mhpmax, 1664. 				  so no (mhp > mhpmax) check is needed here */ 1665. 				mtmp->mhpmax -= rn2(num + 1); 1666. 			} 1667. 			if (burnarmor(mtmp) || rn2(3)) { 1668. 			   (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); 1669. 			   (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); 1670. 			   (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); 1671. 			} 1672. 			if (burn_floor_paper(mtmp->mx, mtmp->my, see_it, FALSE) &&  1673. 				!see_it && distu(mtmp->mx, mtmp->my) <= 3*3) 1674. 			   You("smell smoke."); 1675. 			if (is_ice(mtmp->mx,mtmp->my)) 1676. 			   melt_ice(mtmp->mx,mtmp->my); 1677. 			if (see_it) seetrap(trap); 1678. 			break; 1679. 1680. 		case PIT: 1681. 		case SPIKED_PIT: 1682. 			fallverb = "falls"; 1683. 			if (is_flyer(mptr) || is_floater(mptr) || 1684. 				(mtmp->wormno && count_wsegs(mtmp) > 5) ||  1685. 				is_clinger(mptr)) { 1686. 			   if (!inescapable) break;	/* avoids trap */ 1687. 			   fallverb = "is dragged";	/* sokoban pit */ 1688. 			} 1689. 			if (!passes_walls(mptr)) 1690. 			   mtmp->mtrapped = 1; 1691. 			if (in_sight) { 1692. 			   pline("%s %s into %s pit!",  1693. 				  Monnam(mtmp), fallverb,  1694. 				  a_your[trap->madeby_u]); 1695. 			   if (mptr == &mons[PM_PIT_VIPER] || mptr == &mons[PM_PIT_FIEND]) 1696. 				pline("How pitiful. Isn't that the pits?"); 1697. 			   seetrap(trap); 1698. 			} 1699. 			mselftouch(mtmp, "Falling, ", FALSE); 1700. 			if (mtmp->mhp <= 0 || 1701. 				thitm(0, mtmp, (struct obj *)0, 1702. 				     rnd((tt == PIT) ? 6 : 10))) 1703. 			   trapkilled = TRUE; 1704. 			break; 1705. 		case HOLE: 1706. 		case TRAPDOOR: 1707. 			if (!Can_fall_thru(&u.uz)) { 1708. 			 impossible("mintrap: %ss cannot exist on this level.", 1709. 				    defsyms[trap_to_defsym(tt)].explanation); 1710. 			   break;	/* don't activate it after all */ 1711. 			} 1712. 			if (is_flyer(mptr) || is_floater(mptr) ||  1713. 				mptr == &mons[PM_WUMPUS] ||  1714. 				(mtmp->wormno && count_wsegs(mtmp) > 5) ||  1715. 				mptr->msize >= MZ_HUGE) { 1716. 			   if (inescapable) {	/* sokoban hole */ 1717. 				if (in_sight) { 1718. 				   pline("%s seems to be yanked down!",  1719. 					  Monnam(mtmp)); 1720. 				   /* suppress message in mlevel_tele_trap */ 1721. 				   in_sight = FALSE; 1722. 				   seetrap(trap); 1723. 				} 1724. 			    } else 1725. 				break; 1726. 			} 1727. 			/* Fall through */ 1728. 		case LEVEL_TELEP: 1729. 		case MAGIC_PORTAL: 1730. 			{ 1731. 			    int mlev_res; 1732. 			   mlev_res = mlevel_tele_trap(mtmp, trap,  1733. 							inescapable, in_sight); 1734. 			   if (mlev_res) return(mlev_res); 1735. 			} 1736. 			break; 1737. 1738. 		case TELEP_TRAP: 1739. 			mtele_trap(mtmp, trap, in_sight); 1740. 			break; 1741. 1742. 		case WEB: 1743. 			/* Monster in a web. */ 1744. 			if (webmaker(mptr)) break; 1745. 			if (amorphous(mptr) || is_whirly(mptr) || unsolid(mptr)){ 1746. 			   if(acidic(mptr) ||  1747. 			       mptr == &mons[PM_GELATINOUS_CUBE] ||  1748. 			       mptr == &mons[PM_FIRE_ELEMENTAL]) { 1749. 				if (in_sight) 1750. 				   pline("%s %s %s spider web!",  1751. 					  Monnam(mtmp),  1752. 					  (mptr == &mons[PM_FIRE_ELEMENTAL]) ?  1753. 					    "burns" : "dissolves",  1754. 					  a_your[trap->madeby_u]); 1755. 				deltrap(trap); 1756. 				newsym(mtmp->mx, mtmp->my); 1757. 				break; 1758. 			   }  1759. 			    if (in_sight) { 1760. 				pline("%s flows through %s spider web.", 1761. 				      Monnam(mtmp),  1762. 				      a_your[trap->madeby_u]); 1763. 				seetrap(trap); 1764. 			   }  1765. 			    break; 1766. 			} 1767. 			tear_web = FALSE; 1768. 			switch (monsndx(mptr)) { 1769. 			   case PM_OWLBEAR: /* Eric Backus */ 1770. 			   case PM_BUGBEAR: 1771. 				if (!in_sight) { 1772. 				   You_hear("the roaring of a confused bear!"); 1773. 				   mtmp->mtrapped = 1; 1774. 				   break; 1775. 				} 1776. 				/* fall though */ 1777. 			   default: 1778. 				if (mptr->mlet == S_GIANT || 1779. 				    (mptr->mlet == S_DRAGON && 1780. 					extra_nasty(mptr)) || /* excl. babies */ 1781. 				    (mtmp->wormno && count_wsegs(mtmp) > 5)) { 1782. 				   tear_web = TRUE; 1783. 				} else if (in_sight) { 1784. 				   pline("%s is caught in %s spider web.",  1785. 					  Monnam(mtmp),  1786. 					  a_your[trap->madeby_u]); 1787. 				   seetrap(trap); 1788. 				} 1789. 				mtmp->mtrapped = tear_web ? 0 : 1; 1790. 				break; 1791. 			   /* this list is fairly arbitrary; it deliberately 1792. 			      excludes wumpus & giant/ettin zombies/mummies */ 1793. 			   case PM_TITANOTHERE: 1794. 			   case PM_BALUCHITHERIUM: 1795. 			   case PM_PURPLE_WORM: 1796. 			   case PM_JABBERWOCK: 1797. 			   case PM_IRON_GOLEM: 1798. 			   case PM_BALROG: 1799. 			   case PM_KRAKEN: 1800. 			   case PM_MASTODON: 1801. 				tear_web = TRUE; 1802. 				break; 1803. 			} 1804. 			if (tear_web) { 1805. 			   if (in_sight) 1806. 				pline("%s tears through %s spider web!", 1807. 				      Monnam(mtmp), a_your[trap->madeby_u]); 1808. 			   deltrap(trap); 1809. 			   newsym(mtmp->mx, mtmp->my); 1810. 			} 1811. 			break; 1812. 1813. 		case STATUE_TRAP: 1814. 			break; 1815. 1816. 		case MAGIC_TRAP: 1817. 			/* A magic trap. Monsters usually immune. */ 1818. 			if (!rn2(21)) goto mfiretrap; 1819. 			break; 1820. 		case ANTI_MAGIC: 1821. 			break; 1822. 1823. 		case LANDMINE: 1824. 			if(rn2(3)) 1825. 				break; /* monsters usually don't set it off */ 1826. 			if(is_flyer(mptr)) { 1827. 				boolean already_seen = trap->tseen; 1828. 				if (in_sight && !already_seen) { 1829. 	pline("A trigger appears in a pile of soil below %s.", mon_nam(mtmp)); 1830. 					seetrap(trap); 1831. 				} 1832. 				if (rn2(3)) break; 1833. 				if (in_sight) { 1834. 					newsym(mtmp->mx, mtmp->my); 1835. 					pline_The("air currents set %s off!", 1836. 					  already_seen ? "a land mine" : "it"); 1837. 				} 1838. 			} else if(in_sight) { 1839. 			   newsym(mtmp->mx, mtmp->my); 1840. 			   pline("KAABLAMM!!!  %s triggers %s land mine!",  1841. 				Monnam(mtmp), a_your[trap->madeby_u]); 1842. 			} 1843. 			if (!in_sight) 1844. 				pline("Kaablamm! You hear an explosion in the distance!"); 1845. 			blow_up_landmine(trap); 1846. 			if(thitm(0, mtmp, (struct obj *)0, rnd(16))) 1847. 				trapkilled = TRUE; 1848. 			else { 1849. 				/* monsters recursively fall into new pit */ 1850. 				if (mintrap(mtmp) == 2) trapkilled=TRUE; 1851. 			} 1852. 			/* a boulder may fill the new pit, crushing monster */ 1853. 			fill_pit(trap->tx, trap->ty); 1854. 			if (mtmp->mhp <= 0) trapkilled = TRUE; 1855. 			if (unconscious) { 1856. 				multi = -1; 1857. 				nomovemsg="The explosion awakens you!"; 1858. 			} 1859. 			break; 1860. 1861. 		case POLY_TRAP: 1862. 		   if (resists_magm(mtmp)) { 1863. 			shieldeff(mtmp->mx, mtmp->my); 1864. 		   } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) { 1865. 			(void) newcham(mtmp, (struct permonst *)0, FALSE); 1866. 			if (in_sight) seetrap(trap); 1867. 		   }  1868. 		    break; 1869. 1870. 		case ROLLING_BOULDER_TRAP: 1871. 		   if (!is_flyer(mptr)) { 1872. 		       newsym(mtmp->mx,mtmp->my); 1873. 			if (in_sight) 1874. 			 pline("Click! %s triggers %s.", Monnam(mtmp),  1875. 				  trap->tseen ?  1876. 				  "a rolling boulder trap" :  1877. 				  something); 1878. 			if (launch_obj(BOULDER, trap->launch.x, trap->launch.y, 1879. trap->launch2.x, trap->launch2.y, ROLL)) { 1880. 			 if (in_sight) trap->tseen = TRUE; 1881. 			 else You_hear(Hallucination ?  1882. 					"someone bowling." :  1883. 					"rumbling in the distance."); 1884. 			 if (mtmp->mhp <= 0) trapkilled = TRUE; 1885. 			} else { 1886. 			 deltrap(trap); 1887. 			 newsym(mtmp->mx,mtmp->my); 1888. 			} 1889. 		      }  1890. 		    break; 1891. 1892. 		default: 1893. 			impossible("Some monster encountered a strange trap of type %d.", tt); 1894. 	   }  1895. 	}  1896. 	if(trapkilled) return 2; 1897. 	return mtmp->mtrapped; 1898. } 1899.  1900. #endif /* OVL1 */ 1901. #ifdef OVLB 1902. 1903. /* Combine cockatrice checks into single functions to avoid repeating code. */ 1904. void 1905. instapetrify(str) 1906. const char *str; 1907. { 1908. 	if (Stone_resistance) return; 1909. 	if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) 1910. 	   return; 1911. 	You("turn to stone..."); 1912. 	killer_format = KILLED_BY; 1913. 	killer = str; 1914. 	done(STONING); 1915. } 1916.  1917. void 1918. minstapetrify(mon,byplayer) 1919. struct monst *mon; 1920. boolean byplayer; 1921. { 1922. 	if (resists_ston(mon)) return; 1923. 	if (cansee(mon->mx, mon->my)) 1924. 		pline("%s turns to stone.", Monnam(mon)); 1925. 	if (poly_when_stoned(mon->data)) { 1926. 		mon_to_stone(mon); 1927. 		return; 1928. 	} 1929. 	if (byplayer) { 1930. 		stoned = TRUE; 1931. 		xkilled(mon,0); 1932. 	} else monstone(mon); 1933. } 1934.  1935. void 1936. selftouch(arg) 1937. const char *arg; 1938. { 1939. 	char kbuf[BUFSZ]; 1940. 1941. 	if(uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm])  1942. 			&& !Stone_resistance) { 1943. 		pline("%s touch the %s corpse.", arg, 1944. 		        mons[uwep->corpsenm].mname); 1945. 		Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname)); 1946. 		instapetrify(kbuf); 1947. 	} 1948. 	/* Or your secondary weapon, if wielded */ 1949. 	if(u.twoweap && uswapwep && uswapwep->otyp == CORPSE && 1950. 			touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance){ 1951. 		pline("%s touch the %s corpse.", arg, 1952. 		        mons[uswapwep->corpsenm].mname); 1953. 		Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname)); 1954. 		instapetrify(kbuf); 1955. 	} 1956. }  1957.  1958. void 1959. mselftouch(mon,arg,byplayer) 1960. struct monst *mon; 1961. const char *arg; 1962. boolean byplayer; 1963. { 1964. 	struct obj *mwep = MON_WEP(mon); 1965. 1966. 	if (mwep && mwep->otyp == CORPSE && touch_petrifies(&mons[mwep->corpsenm])) { 1967. 		if (cansee(mon->mx, mon->my)) { 1968. 			pline("%s%s touches the %s corpse.", 1969. 			    arg ? arg : "", arg ? mon_nam(mon) : Monnam(mon),  1970. 			    mons[mwep->corpsenm].mname); 1971. 		} 1972. 		minstapetrify(mon, byplayer); 1973. 	} 1974. }  1975.  1976. void 1977. float_up 1978. { 1979. 	if(u.utrap) { 1980. 		if(u.utraptype == TT_PIT) { 1981. 			u.utrap = 0; 1982. 			You("float up, out of the pit!"); 1983. 			vision_full_recalc = 1;	/* vision limits change */ 1984. 			fill_pit(u.ux, u.uy); 1985. 		} else if (u.utraptype == TT_INFLOOR) { 1986. 			Your("body pulls upward, but your %s are still stuck.", 1987. 			     makeplural(body_part(LEG))); 1988. 		} else { 1989. 			You("float up, only your %s is still stuck.", 1990. 				body_part(LEG)); 1991. 		} 1992. 	}  1993. 	else if(Is_waterlevel(&u.uz)) 1994. 		pline("It feels as though you've lost some weight."); 1995. 	else if(u.uinwater) 1996. 		spoteffects(TRUE); 1997. 	else if(u.uswallow) 1998. 		You(is_animal(u.ustuck->data) ? 1999. 			"float away from the %s."  :  2000. 			"spiral up into %s.",  2001. 		    is_animal(u.ustuck->data) ?  2002. 			surface(u.ux, u.uy) :  2003. 			mon_nam(u.ustuck)); 2004. 	else if (Hallucination) 2005. 		pline("Up, up, and awaaaay! You're walking on air!"); 2006. 	else if(Is_airlevel(&u.uz)) 2007. 		You("gain control over your movements."); 2008. 	else 2009. 		You("start to float in the air!"); 2010. #ifdef STEED 2011. 	if (u.usteed && !is_floater(u.usteed->data) && 2012. 						!is_flyer(u.usteed->data)) { 2013. 	   if (Lev_at_will) 2014. 	   	pline("%s magically floats up!", Monnam(u.usteed)); 2015. 	   else { 2016. 	   	You("cannot stay on %s.", mon_nam(u.usteed)); 2017. 	   	dismount_steed(DISMOUNT_GENERIC); 2018. 	   }  2019. 	}  2020. #endif 2021. 	return; 2022. } 2023.  2024. void 2025. fill_pit(x, y) 2026. int x, y; 2027. { 2028. 	struct obj *otmp; 2029. 	struct trap *t; 2030. 2031. 	if ((t = t_at(x, y)) &&  2032. 	    ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT)) &&  2033. 	    (otmp = sobj_at(BOULDER, x, y))) { 2034. 		obj_extract_self(otmp); 2035. 		(void) flooreffects(otmp, x, y, "settle"); 2036. 	} 2037. }  2038.  2039. int 2040. float_down(hmask, emask) 2041. long hmask, emask;    /* might cancel timeout */ 2042. { 2043. 	register struct trap *trap = (struct trap *)0; 2044. 	d_level current_dungeon_level; 2045. 	boolean no_msg = FALSE; 2046. 2047. 	HLevitation &= ~hmask; 2048. 	ELevitation &= ~emask; 2049. 	if(Levitation) return(0); /* maybe another ring/potion/boots */ 2050. 2051. 	if (Punished && !carried(uball) &&  2052. 	    (is_pool(uball->ox, uball->oy) || 2053. 	    ((trap = t_at(uball->ox, uball->oy)) &&  2054. 	      ((trap->ttyp == PIT) || (trap->ttyp == SPIKED_PIT) || 2055. 	      (trap->ttyp == TRAPDOOR) || (trap->ttyp == HOLE))))) { 2056. 			u.ux0 = u.ux; 2057. 			u.uy0 = u.uy; 2058. 			u.ux = uball->ox; 2059. 			u.uy = uball->oy; 2060. 			movobj(uchain, uball->ox, uball->oy); 2061. 			newsym(u.ux0, u.uy0); 2062. 			vision_full_recalc = 1;	/* in case the hero moved. */ 2063. 	}  2064. 	/* check for falling into pool - added by GAN 10/20/86 */ 2065. 	if(!Flying) { 2066. 		/* kludge alert: 2067. 		 * drown and lava_effects print various messages almost 2068. 		 * every time they're called which conflict with the "fall 2069. 		 * into" message below. Thus, we want to avoid printing 2070. 		 * confusing, duplicate or out-of-order messages. 2071. 		 * Use knowledge of the two routines as a hack -- this 2072. 		 * should really be handled differently -dlc 2073. 		 */ 2074. 		if(is_pool(u.ux,u.uy) && !Wwalking && !Swimming && !u.uinwater) 2075. 			no_msg = drown; 2076. 2077. 		if(is_lava(u.ux,u.uy)) { 2078. 			(void) lava_effects; 2079. 			no_msg = TRUE; 2080. 		} 2081. 	}  2082. 	if (!trap) { 2083. 	   trap = t_at(u.ux,u.uy); 2084. 	   if(Is_airlevel(&u.uz)) 2085. 		You("begin to tumble in place."); 2086. 	   else if (Is_waterlevel(&u.uz) && !no_msg) 2087. 		You_feel("heavier."); 2088. 	   /* u.uinwater msgs already in spoteffects/drown */ 2089. 	   else if (!u.uinwater && !no_msg) { 2090. #ifdef STEED 2091. 		if (!(emask & W_SADDLE)) 2092. #endif 2093. 		{ 2094. 		    boolean sokoban_trap = (In_sokoban(&u.uz) && trap); 2095. 		   if (Hallucination) 2096. 			pline("Bummer! You've %s.",  2097. 			      is_pool(u.ux,u.uy) ?  2098. 			      "splashed down" : sokoban_trap ? "crashed" :  2099. 			      "hit the ground"); 2100. 		   else { 2101. 			if (!sokoban_trap) 2102. 			   You("float gently to the %s.",  2103. 				surface(u.ux, u.uy)); 2104. 			else { 2105. 			   /* Justification elsewhere for Sokoban traps 2106. 			    * is based on air currents. This is 2107. * consistent with that. 2108. 			    * The unexpected additional force of the 2109. 			    * air currents once leviation 2110. 			    * ceases knocks you off your feet. 2111. 			    */  2112. 			    You("fall over."); 2113. 			   losehp(rnd(2), "dangerous winds", KILLED_BY); 2114. #ifdef STEED 2115. 			   if (u.usteed) dismount_steed(DISMOUNT_FELL); 2116. #endif 2117. 			   selftouch("As you fall, you"); 2118. 			} 2119. 		    }  2120. 		}  2121. 	    }  2122. 	}  2123.  2124. 	/* can't rely on u.uz0 for detecting trap door-induced level change; 2125. 	  it gets changed to reflect the new level before we can check it */ 2126. 	assign_level(&current_dungeon_level, &u.uz); 2127. 2128. 	if(trap) 2129. 		switch(trap->ttyp) { 2130. 		case STATUE_TRAP: 2131. 			break; 2132. 		case HOLE: 2133. 		case TRAPDOOR: 2134. 			if(!Can_fall_thru(&u.uz) || u.ustuck) 2135. 				break; 2136. 			/* fall into next case */ 2137. 		default: 2138. 			if (!u.utrap) /* not already in the trap */ 2139. 				dotrap(trap, 0); 2140. 	} 2141.  2142. 	if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !u.uswallow &&  2143. 		/* falling through trap door calls goto_level,  2144. 		   and goto_level does its own pickup call */  2145. 		on_level(&u.uz, &current_dungeon_level)) 2146. 	   (void) pickup(1); 2147. 	return 1; 2148. } 2149.  2150. STATIC_OVL void 2151. dofiretrap(box) 2152. struct obj *box;	/* null for floor trap */ 2153. { 2154. 	boolean see_it = !Blind; 2155. 	int num; 2156. 2157. /* Bug: for box case, the equivalent of burn_floor_paper ought 2158. * to be done upon its contents. 2159. */  2160.  2161. 	if ((box && !carried(box)) ? is_pool(box->ox, box->oy) : Underwater) { 2162. 	   pline("A cascade of steamy bubbles erupts from %s!",  2163. 		    the(box ? xname(box) : surface(u.ux,u.uy))); 2164. 	   if (Fire_resistance) You("are uninjured."); 2165. 	   else losehp(rnd(3), "boiling water", KILLED_BY); 2166. 	   return; 2167. 	} 2168. 	pline("A %s %s from %s!", tower_of_flame,  2169. 	      box ? "bursts" : "erupts",  2170. 	      the(box ? xname(box) : surface(u.ux,u.uy))); 2171. 	if (Fire_resistance) { 2172. 	   shieldeff(u.ux, u.uy); 2173. 	   num = rn2(2); 2174. 	} else { 2175. 	   num = d(2,4); 2176. 	   if (u.uhpmax > u.ulevel) 2177. 		u.uhpmax -= rn2(min(u.uhpmax,num + 1)), flags.botl = 1; 2178. 	} 2179. 	if (!num) 2180. 	   You("are uninjured."); 2181. 	else 2182. 	   losehp(num, tower_of_flame, KILLED_BY_AN); 2183. 	burn_away_slime; 2184. 2185. 	if (burnarmor(&youmonst) || rn2(3)) { 2186. 	   destroy_item(SCROLL_CLASS, AD_FIRE); 2187. 	   destroy_item(SPBOOK_CLASS, AD_FIRE); 2188. 	   destroy_item(POTION_CLASS, AD_FIRE); 2189. 	} 2190. 	if (!box && burn_floor_paper(u.ux, u.uy, see_it, TRUE) && !see_it) 2191. 	   You("smell paper burning."); 2192. 	if (is_ice(u.ux, u.uy)) 2193. 	   melt_ice(u.ux, u.uy); 2194. } 2195.  2196. STATIC_OVL void 2197. domagictrap 2198. { 2199. 	register int fate = rnd(20); 2200. 2201. 	/* What happened to the poor sucker? */ 2202.  2203. 	if (fate < 10) { 2204. 	 /* Most of the time, it creates some monsters. */ 2205. 	  register int cnt = rnd(4); 2206. 2207. 	  if (!resists_blnd(&youmonst)) { 2208. 		You("are momentarily blinded by a flash of light!"); 2209. 		make_blinded((long)rn1(5,10),FALSE); 2210. 		if (!Blind) Your(vision_clears); 2211. 	 } else if (!Blind) { 2212. 		You("see a flash of light!"); 2213. 	 }  else 2214. 		You_hear("a deafening roar!"); 2215. 	 while(cnt--) 2216. 		(void) makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS); 2217. 	} 2218. 	else 2219. 	 switch (fate) { 2220. 2221. 	     case 10: 2222. 	    case 11: 2223. 		     /* sometimes nothing happens */ 2224. 			break; 2225. 	    case 12: /* a flash of fire */ 2226. 			dofiretrap((struct obj *)0); 2227. 			break; 2228. 2229. 	     /* odd feelings */ 2230. 	    case 13:	pline("A shiver runs up and down your %s!",  2231. 			      body_part(SPINE)); 2232. 			break; 2233. 	    case 14:	You_hear(Hallucination ?  2234. 				"the moon howling at you." :  2235. 				"distant howling."); 2236. 			break; 2237. 	    case 15:	if (on_level(&u.uz, &qstart_level)) 2238. 			   You_feel("%slike the prodigal son.",  2239. 			      (flags.female || (Upolyd && is_neuter(youmonst.data))) ?  2240. 				     "oddly " : ""); 2241. 			else 2242. 			   You("suddenly yearn for %s.",  2243. 				Hallucination ? "Cleveland" :  2244. 			    (In_quest(&u.uz) || at_dgn_entrance("The Quest")) ?  2245. 						"your nearby homeland" :  2246. 						"your distant homeland"); 2247. 			break; 2248. 	    case 16:   Your("pack shakes violently!"); 2249. 			break; 2250. 	    case 17:	You(Hallucination ?  2251. 				"smell hamburgers." :  2252. 				"smell charred flesh."); 2253. 			break; 2254. 	    case 18:	You_feel("tired."); 2255. 			break; 2256. 2257. 	     /* very occasionally something nice happens. */ 2258.  2259. 	     case 19: 2260. 		   /* tame nearby monsters */ 2261. 		  {   register int i,j; 2262. 		      register struct monst *mtmp; 2263. 2264. 		       (void) adjattrib(A_CHA,1,FALSE); 2265. 		      for(i = -1; i <= 1; i++) for(j = -1; j <= 1; j++) { 2266. 			  if(!isok(u.ux+i, u.uy+j)) continue; 2267. 			  mtmp = m_at(u.ux+i, u.uy+j); 2268. 			  if(mtmp) 2269. 			      (void) tamedog(mtmp, (struct obj *)0); 2270. 		      }  2271. 		       break; 2272. 		  }  2273.  2274. 	     case 20: 2275. 		   /* uncurse stuff */ 2276. 		  {	struct obj pseudo; 2277. 			long save_conf = HConfusion; 2278. 2279. 			pseudo = zeroobj;   /* neither cursed nor blessed */ 2280. 			pseudo.otyp = SCR_REMOVE_CURSE; 2281. 			HConfusion = 0L; 2282. 			(void) seffects(&pseudo); 2283. 			HConfusion = save_conf; 2284. 			break; 2285. 		  }  2286. 	     default: break; 2287. 	 }  2288. }  2289.  2290. /*  2291.  * Scrolls, spellbooks, potions, and flammable items 2292. * may get affected by the fire. 2293. *  2294.  * Return number of objects destroyed. --ALI 2295. */  2296. int 2297. fire_damage(chain, force, here, x, y) 2298. struct obj *chain; 2299. boolean force, here; 2300. xchar x, y; 2301. { 2302.     int chance; 2303.    struct obj *obj, *otmp, *nobj, *ncobj; 2304.    int retval = 0; 2305.    int in_sight = !Blind && couldsee(x, y);	/* Don't care if it's lit */ 2306.    int dindx; 2307. 2308.     for (obj = chain; obj; obj = nobj) { 2309. 	nobj = here ? obj->nexthere : obj->nobj; 2310. 2311. 	/* object might light in a controlled manner */ 2312. 	if (catch_lit(obj)) 2313. 	   continue; 2314. 2315. 	if (Is_container(obj)) { 2316. 	   switch (obj->otyp) { 2317. 	   case ICE_BOX: 2318. 		continue;		/* Immune */ 2319. 		/*NOTREACHED*/ 2320. 		break; 2321. 	   case CHEST: 2322. 		chance = 40; 2323. 		break; 2324. 	   case LARGE_BOX: 2325. 		chance = 30; 2326. 		break; 2327. 	   default: 2328. 		chance = 20; 2329. 		break; 2330. 	   }  2331. 	    if (!force && (Luck + 5) > rn2(chance)) 2332. 		continue; 2333. 	   /* Container is burnt up - dump contents out */ 2334. 	   if (in_sight) pline("%s catches fire and burns.", Yname2(obj)); 2335. 	   if (Has_contents(obj)) { 2336. 		if (in_sight) pline("Its contents fall out."); 2337. 		for (otmp = obj->cobj; otmp; otmp = ncobj) { 2338. 		   ncobj = otmp->nobj; 2339. 		   obj_extract_self(otmp); 2340. 		   if (!flooreffects(otmp, x, y, "")) 2341. 			place_object(otmp, x, y); 2342. 		} 2343. 	    }  2344. 	    delobj(obj); 2345. 	   retval++; 2346. 	} else if (!force && (Luck + 5) > rn2(20)) { 2347. 	   /*  chance per item of sustaining damage: 2348. 	    *	max luck (full moon):	 5% 2349. 	    *	max luck (elsewhen):	10% 2350. 	    *	avg luck (Luck==0):	75% 2351. 	    *	awful luck (Luck<-4):  100% 2352. 	    */  2353. 	    continue; 2354. 	} else if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS) { 2355. 	   if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL) 2356. 		continue; 2357. 	   if (obj->otyp == SPE_BOOK_OF_THE_DEAD) { 2358. 		if (in_sight) pline("Smoke rises from %s.", the(xname(obj))); 2359. 		continue; 2360. 	   }  2361. 	    dindx = (obj->oclass == SCROLL_CLASS) ? 2 : 3; 2362. 	    if (in_sight) 2363. 		pline("%s %s.", Yname2(obj), (obj->quan > 1) ? 2364. 		      destroy_strings[dindx*3 + 1] : destroy_strings[dindx*3]); 2365. 	   delobj(obj); 2366. 	   retval++; 2367. 	} else if (obj->oclass == POTION_CLASS) { 2368. 	   dindx = 1; 2369. 	   if (in_sight) 2370. 		pline("%s %s.", Yname2(obj), (obj->quan > 1) ? 2371. 		      destroy_strings[dindx*3 + 1] : destroy_strings[dindx*3]); 2372. 	   delobj(obj); 2373. 	   retval++; 2374. 	} else if (is_flammable(obj) && obj->oeroded < MAX_ERODE && 2375. 		   !(obj->oerodeproof || (obj->blessed && !rnl(4)))) { 2376. 	   if (in_sight) { 2377. 		pline("%s %s%s.", Yname2(obj), otense(obj, "burn"), 2378. 		      obj->oeroded+1 == MAX_ERODE ? " completely" :  2379. 		      obj->oeroded ? " further" : ""); 2380. 	   }  2381. 	    obj->oeroded++; 2382. 	} 2383.     }  2384.  2385.     if (retval && !in_sight) 2386. 	You("smell smoke."); 2387.    return retval; 2388. } 2389.  2390. void 2391. water_damage(obj, force, here) 2392. register struct obj *obj; 2393. register boolean force, here; 2394. { 2395. 	/* Scrolls, spellbooks, potions, weapons and 2396. 	  pieces of armor may get affected by the water */ 2397. 	for (obj; obj = (here ? obj->nexthere : obj->nobj)) { 2398. 2399. 		(void) snuff_lit(obj); 2400. 2401. 		if(obj->otyp == CAN_OF_GREASE && obj->spe > 0) { 2402. 			continue; 2403. 		} else if(obj->greased) { 2404. 			if (force || !rn2(2)) obj->greased = 0; 2405. 		} else if(Is_container(obj) && !Is_box(obj) && 2406. 			(obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) { 2407. 			water_damage(obj->cobj, force, FALSE); 2408. 		} else if (!force && (Luck + 5) > rn2(20)) { 2409. 			/* chance per item of sustaining damage: 2410. 			 *	max luck (full moon):	 5% 2411. 			 *	max luck (elsewhen):	10% 2412. 			 *	avg luck (Luck==0):	75% 2413. 			 *	awful luck (Luck<-4): 100% 2414. 			 */ 2415. 			continue; 2416. 		} else if (obj->oclass == SCROLL_CLASS) { 2417. #ifdef MAIL 2418. 		   if (obj->otyp != SCR_MAIL) 2419. #endif 2420. 		   {  2421. 			obj->otyp = SCR_BLANK_PAPER; 2422. 			obj->spe = 0; 2423. 		   }  2424. 		} else if (obj->oclass == SPBOOK_CLASS) { 2425. 			if (obj->otyp == SPE_BOOK_OF_THE_DEAD) 2426. 				pline("Steam rises from %s.", the(xname(obj))); 2427. 			else obj->otyp = SPE_BLANK_PAPER; 2428. 		} else if (obj->oclass == POTION_CLASS) { 2429. 			if (obj->odiluted) { 2430. 				obj->otyp = POT_WATER; 2431. 				obj->blessed = obj->cursed = 0; 2432. 				obj->odiluted = 0; 2433. 			} else if (obj->otyp != POT_WATER) 2434. 				obj->odiluted++; 2435. 		} else if (is_rustprone(obj) && obj->oeroded < MAX_ERODE && 2436. 			  !(obj->oerodeproof || (obj->blessed && !rnl(4)))) { 2437. 			/* all metal stuff and armor except (body armor 2438. 			   protected by oilskin cloak) */ 2439. 			if(obj->oclass != ARMOR_CLASS || obj != uarm || 2440. 			   !uarmc || uarmc->otyp != OILSKIN_CLOAK ||  2441. 			   (uarmc->cursed && !rn2(3))) 2442. 				obj->oeroded++; 2443. 		} 2444. 	}  2445. }  2446.  2447. /*  2448.  * This function is potentially expensive - rolling 2449. * inventory list multiple times. Luckily it's seldom needed. 2450. * Returns TRUE if disrobing made player unencumbered enough to  2451. * crawl out of the current predicament. 2452. */  2453. STATIC_OVL boolean 2454. emergency_disrobe(lostsome) 2455. boolean *lostsome; 2456. { 2457. 	int invc = inv_cnt; 2458. 2459.  2460. 	while (near_capacity > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) { 2461. 		register struct obj *obj, *otmp = (struct obj *)0; 2462. 		register int i; 2463. 2464. 		/* Pick a random object */ 2465. 		if (invc > 0) { 2466. 			i = rn2(invc); 2467. 		for (obj = invent; obj; obj = obj->nobj) { 2468. 			/* 2469. 			 * Undroppables are: body armor, boots, gloves, 2470. 			 * amulets, and rings because of the time and effort 2471. 			 * in removing them + loadstone and other cursed stuff 2472. 			 * for obvious reasons. 2473. 			 */ 2474. 			if (!((obj->otyp == LOADSTONE && obj->cursed) || 2475. 			     obj == uamul || obj == uleft || obj == uright || 2476. 			     obj == ublindf || obj == uarm || obj == uarmc || 2477. 			     obj == uarmg || obj == uarmf || 2478. #ifdef TOURIST 2479. 			     obj == uarmu || 2480. #endif 2481. 			     (obj->cursed && (obj == uarmh || obj == uarms)) || 2482. 			     welded(obj))) 2483. 				otmp = obj; 2484. 			/* reached the mark and found some stuff to drop? */ 2485. 			if (--i < 0 && otmp) break; 2486. 2487. 			/* else continue */ 2488. 		} 2489. 		}  2490. #ifndef GOLDOBJ 2491. 		if (!otmp) { 2492. 			/* Nothing available left to drop; try gold */ 2493. 			if (u.ugold) { 2494. 				pline("In desperation, you drop your purse."); 2495. 				/* Hack: gold is not in the inventory, so make a gold object 2496. 				 * and put it at the head of the inventory list. 2497. 				 */ 2498. 				obj = mkgoldobj(u.ugold);    /* removes from u.ugold */ 2499. 				u.ugold = obj->quan;        /* put the gold back */ 2500. 				assigninvlet(obj);          /* might end up as NOINVSYM */ 2501. 				obj->nobj = invent; 2502. 				invent = obj; 2503. 				*lostsome = TRUE; 2504. 				dropx(obj); 2505. 				continue;                   /* Try again */ 2506. 			} 2507. 			/* We can't even drop gold! */ 2508. 			return (FALSE); 2509. 		} 2510. #else 2511. 		if (!otmp) return (FALSE); /* nothing to drop! */	 2512. #endif 2513. 		if (otmp->owornmask && otmp != uball) remove_worn_item(otmp); 2514. 		*lostsome = TRUE; 2515. 		dropx(otmp); 2516. 		invc--; 2517. 	} 2518. 	return(TRUE); 2519. } 2520.  2521. /*  2522.  *  return(TRUE) == player relocated 2523. */  2524. boolean 2525. drown 2526. { 2527. 	boolean inpool_ok = FALSE, crawl_ok; 2528. 	int i, x, y; 2529. 2530. 	/* happily wading in the same contiguous pool */ 2531. 	if (u.uinwater && is_pool(u.ux-u.dx,u.uy-u.dy) && 2532. 	    (Swimming || Amphibious)) { 2533. 		/* water effects on objects every now and then */ 2534. 		if (!rn2(5)) inpool_ok = TRUE; 2535. 		else return(FALSE); 2536. 	} 2537.  2538. 	if (!u.uinwater) { 2539. 	   You("%s into the water%c",  2540. 		Is_waterlevel(&u.uz) ? "plunge" : "fall",  2541. 		Amphibious || Swimming ? '.' : '!'); 2542. 	   if (!Swimming && !Is_waterlevel(&u.uz)) 2543. 		   You("sink like %s.",  2544. 			Hallucination ? "the Titanic" : "a rock"); 2545. 	} 2546.  2547. 	water_damage(invent, FALSE, FALSE); 2548. 2549. 	if (u.umonnum == PM_GREMLIN && rn2(3)) 2550. 	   (void)split_mon(&youmonst, (struct monst *)0); 2551. 	else if (u.umonnum == PM_IRON_GOLEM) { 2552. 	   You("rust!"); 2553. 	   i = d(2,6); 2554. 	   if (u.mhmax > i) u.mhmax -= i;  2555. losehp(i, "rusting away", KILLED_BY); 2556. 	} 2557. 	if (inpool_ok) return(FALSE); 2558. 2559. 	if ((i = number_leashed) > 0) { 2560. 		pline_The("leash%s slip%s loose.", 2561. 			(i > 1) ? "es" : "",  2562. 			(i > 1) ? "" : "s"); 2563. 		unleash_all; 2564. 	} 2565.  2566. 	if (Amphibious || Swimming) { 2567. 		if (Amphibious) { 2568. 			if (flags.verbose) 2569. 				pline("But you aren't drowning."); 2570. 			if (!Is_waterlevel(&u.uz)) { 2571. 				if (Hallucination) 2572. 					Your("keel hits the bottom."); 2573. 				else 2574. 					You("touch bottom."); 2575. 			} 2576. 		}  2577. 		if (Punished) { 2578. 			unplacebc; 2579. 			placebc; 2580. 		} 2581. 		vision_recalc(2);	/* unsee old position */ 2582. 		u.uinwater = 1; 2583. 		under_water(1); 2584. 		vision_full_recalc = 1; 2585. 		return(FALSE); 2586. 	} 2587. 	if((Teleportation || can_teleport(youmonst.data)) &&  2588. 	   (Teleport_control || rn2(3) < Luck+2)) { 2589. 		You("attempt a teleport spell.");	/* utcsri!carroll */ 2590. 		(void) dotele; 2591. 		if(!is_pool(u.ux,u.uy)) 2592. 			return(TRUE); 2593. 	} 2594. #ifdef STEED 2595. 	if (u.usteed) { 2596. 		dismount_steed(DISMOUNT_GENERIC); 2597. 		if(!is_pool(u.ux,u.uy)) 2598. 			return(TRUE); 2599. 	} 2600. #endif 2601. 	crawl_ok = FALSE; 2602. 	/* look around for a place to crawl to */ 2603. 	for (i = 0; i < 100; i++) { 2604. 		x = rn1(3,u.ux - 1); 2605. 		y = rn1(3,u.uy - 1); 2606. 		if (goodpos(x, y, &youmonst)) { 2607. 			crawl_ok = TRUE; 2608. 			goto crawl; 2609. 		} 2610. 	}  2611. 	/* one more scan */ 2612. 	for (x = u.ux - 1; x <= u.ux + 1; x++) 2613. 		for (y = u.uy - 1; y <= u.uy + 1; y++) 2614. 			if (goodpos(x, y, &youmonst)) { 2615. 				crawl_ok = TRUE; 2616. 				goto crawl; 2617. 			} 2618. crawl:; 2619. 	if (crawl_ok) { 2620. 		boolean lost = FALSE; 2621. 		/* time to do some strip-tease... */ 2622. 		boolean succ = Is_waterlevel(&u.uz) ? TRUE : 2623. 				emergency_disrobe(&lost); 2624. 2625. 		You("try to crawl out of the water."); 2626. 		if (lost) 2627. 			You("dump some of your gear to lose weight..."); 2628. 		if (succ) { 2629. 			pline("Pheew! That was close."); 2630. 			teleds(x,y); 2631. 			return(TRUE); 2632. 		} 2633. 		/* still too much weight */ 2634. 		pline("But in vain."); 2635. 	} 2636. 	u.uinwater = 1; 2637. 	You("drown."); 2638. 	killer_format = KILLED_BY_AN; 2639. 	killer = (levl[u.ux][u.uy].typ == POOL || Is_medusa_level(&u.uz)) ? 2640. 	   "pool of water" : "moat"; 2641. 	done(DROWNING); 2642. 	/* oops, we're still alive. better get out of the water. */ 2643. 	while (!safe_teleds) { 2644. 		pline("You're still drowning."); 2645. 		done(DROWNING); 2646. 	} 2647. 	u.uinwater = 0; 2648. 	You("find yourself back %s.", Is_waterlevel(&u.uz) ? 2649. 		"in an air bubble" : "on land"); 2650. 	return(TRUE); 2651. } 2652.  2653. void 2654. drain_en(n) 2655. register int n; 2656. { 2657. 	if (!u.uenmax) return; 2658. 	You_feel("your magical energy drain away!"); 2659. 	u.uen -= n; 2660. if(u.uen < 0) { 2661. 		u.uenmax += u.uen; 2662. 		if(u.uenmax < 0) u.uenmax = 0; 2663. 		u.uen = 0; 2664. 	} 2665. 	flags.botl = 1; 2666. } 2667.  2668. int 2669. dountrap	/* disarm a trap */ 2670. { 2671. 	if (near_capacity >= HVY_ENCUMBER) { 2672. 	   pline("You're too strained to do that."); 2673. 	   return 0; 2674. 	} 2675. 	if ((nohands(youmonst.data) && !webmaker(youmonst.data)) || !youmonst.data->mmove) { 2676. 	   pline("And just how do you expect to do that?"); 2677. 	   return 0; 2678. 	} else if (u.ustuck && sticks(youmonst.data)) { 2679. 	   pline("You'll have to let go of %s first.", mon_nam(u.ustuck)); 2680. 	   return 0; 2681. 	} 2682. 	if (u.ustuck || (welded(uwep) && bimanual(uwep))) { 2683. 	   Your("%s seem to be too busy for that.",  2684. 		 makeplural(body_part(HAND))); 2685. 	   return 0; 2686. 	} 2687. 	return untrap(FALSE); 2688. } 2689. #endif /* OVLB */ 2690. #ifdef OVL2 2691. 2692. /* Probability of disabling a trap. Helge Hafting */ 2693. STATIC_OVL int 2694. untrap_prob(ttmp) 2695. struct trap *ttmp; 2696. { 2697. 	int chance = 3; 2698. 2699. 	/* Only spiders know how to deal with webs reliably */ 2700. 	if (ttmp->ttyp == WEB && !webmaker(youmonst.data)) 2701. 	 	chance = 30; 2702. 	if (Confusion || Hallucination) chance++; 2703. 	if (Blind) chance++; 2704. 	if (Stunned) chance += 2; 2705. 	if (Fumbling) chance *= 2; 2706. 	/* Your own traps are better known than others. */ 2707. 	if (ttmp && ttmp->madeby_u) chance--; 2708. 	if (Role_if(PM_ROGUE)) { 2709. 	   if (rn2(2 * MAXULEV) < u.ulevel) chance--; 2710. 	   if (u.uhave.questart && chance > 1) chance--; 2711. 	} else if (Role_if(PM_RANGER) && chance > 1) chance--; 2712. 	return rn2(chance); 2713. } 2714.  2715. /* Replace trap with object(s). Helge Hafting */ 2716. STATIC_OVL void 2717. cnv_trap_obj(otyp, cnt, ttmp) 2718. int otyp; 2719. int cnt; 2720. struct trap *ttmp; 2721. { 2722. 	struct obj *otmp = mksobj(otyp, TRUE, FALSE); 2723. 	otmp->quan=cnt; 2724. 	otmp->owt = weight(otmp); 2725. 	/* Only dart traps are capable of being poisonous */ 2726. 	if (otyp != DART) 2727. 	   otmp->opoisoned = 0; 2728. 	place_object(otmp, ttmp->tx, ttmp->ty); 2729. 	/* Sell your own traps only... */ 2730. 	if (ttmp->madeby_u) sellobj(otmp, ttmp->tx, ttmp->ty); 2731. 	stackobj(otmp); 2732. 	newsym(ttmp->tx, ttmp->ty); 2733. 	deltrap(ttmp); 2734. } 2735.  2736. /* while attempting to disarm an adjacent trap, we've fallen into it */ 2737. STATIC_OVL void 2738. move_into_trap(ttmp) 2739. struct trap *ttmp; 2740. { 2741. 	int bc; 2742. 	xchar x = ttmp->tx, y = ttmp->ty, bx, by, cx, cy; 2743. 	boolean unused; 2744. 2745. 	/* we know there's no monster in the way, and we're not trapped */ 2746. 	if (!Punished || drag_ball(x, y, &bc, &bx, &by, &cx, &cy, &unused)) { 2747. 	   u.ux0 = u.ux,  u.uy0 = u.uy; 2748. 	   u.ux = x,  u.uy = y;  2749. u.umoved = TRUE; 2750. 	   newsym(u.ux0, u.uy0); 2751. 	   vision_recalc(1); 2752. 	   check_leash(u.ux0, u.uy0); 2753. 	   if (Punished) move_bc(0, bc, bx, by, cx, cy); 2754. 	   spoteffects(TRUE);	/* dotrap */ 2755. 	   exercise(A_WIS, FALSE); 2756. 	} 2757. }  2758.  2759. /* 0: doesn't even try 2760. * 1: tries and fails 2761. * 2: succeeds 2762. */  2763. STATIC_OVL int 2764. try_disarm(ttmp, force_failure) 2765. struct trap *ttmp; 2766. boolean force_failure; 2767. { 2768. 	struct monst *mtmp = m_at(ttmp->tx,ttmp->ty); 2769. 	int ttype = ttmp->ttyp; 2770. 	boolean under_u = (!u.dx && !u.dy); 2771. 	boolean holdingtrap = (ttype == BEAR_TRAP || ttype == WEB); 2772. 	 2773. 	/* Test for monster first, monsters are displayed instead of trap. */ 2774. 	if (mtmp && (!mtmp->mtrapped || !holdingtrap)) { 2775. 		pline("%s is in the way.", Monnam(mtmp)); 2776. 		return 0; 2777. 	} 2778. 	/* We might be forced to move onto the trap's location. */ 2779. 	if (sobj_at(BOULDER, ttmp->tx, ttmp->ty)  2780. 				&& !Passes_walls && !under_u) { 2781. 		There("is a boulder in your way."); 2782. 		return 0; 2783. 	} 2784. 	/* duplicate tight-space checks from test_move */ 2785. 	if (u.dx && u.dy && 2786. 	    bad_rock(youmonst.data,u.ux,ttmp->ty) &&  2787. 	    bad_rock(youmonst.data,ttmp->tx,u.uy)) { 2788. 	   if ((invent && (inv_weight + weight_cap > 600)) ||  2789. 		bigmonst(youmonst.data)) { 2790. 		/* don't allow untrap if they can't get thru to it */ 2791. 		You("are unable to reach the %s!", 2792. 		    defsyms[trap_to_defsym(ttype)].explanation); 2793. 		return 0; 2794. 	   }  2795. 	}  2796. 	/* untrappable traps are located on the ground. */ 2797. 	if (!can_reach_floor) { 2798. #ifdef STEED 2799. 		if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) 2800. 			You("aren't skilled enough to reach from %s.", 2801. 				mon_nam(u.usteed)); 2802. 		else 2803. #endif 2804. 		You("are unable to reach the %s!", 2805. 			defsyms[trap_to_defsym(ttype)].explanation); 2806. 		return 0; 2807. 	} 2808.  2809. 	/* Will our hero succeed? */ 2810. 	if (force_failure || untrap_prob(ttmp)) { 2811. 		if (rnl(5)) { 2812. 		   pline("Whoops..."); 2813. 		   if (mtmp) {		/* must be a trap that holds monsters */ 2814. 			if (ttype == BEAR_TRAP) { 2815. 			   if (mtmp->mtame) abuse_dog(mtmp); 2816. 			   if ((mtmp->mhp -= rnd(4)) <= 0) killed(mtmp); 2817. 			} else if (ttype == WEB) { 2818. 			   if (!webmaker(youmonst.data)) { 2819. 				struct trap *ttmp2 = maketrap(u.ux, u.uy, WEB); 2820. 				if (ttmp2) { 2821. 				   pline_The("webbing sticks to you. You're caught too!"); 2822. 				   dotrap(ttmp2, NOWEBMSG); 2823. 				} 2824. 			    } else 2825. 				pline("%s remains entangled.", Monnam(mtmp)); 2826. 			} 2827. 		    } else if (under_u) { 2828. 			dotrap(ttmp, 0); 2829. 		   } else { 2830. 			move_into_trap(ttmp); 2831. 		   }  2832. 		} else { 2833. 		   pline("%s %s is difficult to %s.",  2834. 			  ttmp->madeby_u ? "Your" : under_u ? "This" : "That",  2835. 			  defsyms[trap_to_defsym(ttype)].explanation,  2836. 			  (ttype == WEB) ? "remove" : "disarm"); 2837. 		} 2838. 		return 1; 2839. 	} 2840. 	return 2; 2841. } 2842.  2843. STATIC_OVL void 2844. reward_untrap(ttmp, mtmp) 2845. struct trap *ttmp; 2846. struct monst *mtmp; 2847. { 2848. 	if (!ttmp->madeby_u) { 2849. 	   if (rnl(10) < 8 && !mtmp->mpeaceful &&  2850. 		    !mindless(mtmp->data) &&  2851. 		    mtmp->data->mlet != S_HUMAN) { 2852. 		mtmp->mpeaceful = 1; 2853. 		set_malign(mtmp);	/* reset alignment */ 2854. 		pline("%s is grateful.", Monnam(mtmp)); 2855. 	   }  2856. 	    /* Helping someone out of a trap is a nice thing to do, 2857. 	    * A lawful may be rewarded, but not too often. */ 2858. 	    if (!rn2(3) && !rnl(8) && u.ualign.type == A_LAWFUL) { 2859. 		adjalign(1); 2860. 		You_feel("that you did the right thing."); 2861. 	   }  2862. 	}  2863. }  2864.  2865. STATIC_OVL int 2866. disarm_holdingtrap(ttmp) /* Helge Hafting */ 2867. struct trap *ttmp; 2868. { 2869. 	struct monst *mtmp; 2870. 	int fails = try_disarm(ttmp, FALSE); 2871. 2872. 	if (fails < 2) return fails; 2873. 2874. 	/* ok, disarm it. */ 2875.  2876. 	/* untrap the monster, if any. 2877. 	  There's no need for a cockatrice test, only the trap is touched */ 2878. 	if ((mtmp = m_at(ttmp->tx,ttmp->ty)) != 0) { 2879. 		mtmp->mtrapped = 0; 2880. 		You("remove %s %s from %s.", the_your[ttmp->madeby_u], 2881. 			(ttmp->ttyp == BEAR_TRAP) ? "bear trap" : "webbing",  2882. 			mon_nam(mtmp)); 2883. 		reward_untrap(ttmp, mtmp); 2884. 	} else { 2885. 		if (ttmp->ttyp == BEAR_TRAP) { 2886. 			You("disarm %s bear trap.", the_your[ttmp->madeby_u]); 2887. 			cnv_trap_obj(BEARTRAP, 1, ttmp); 2888. 		} else /* if (ttmp->ttyp == WEB) */ { 2889. 			You("succeed in removing %s web.", the_your[ttmp->madeby_u]); 2890. 			deltrap(ttmp); 2891. 		} 2892. 	}  2893. 	newsym(u.ux + u.dx, u.uy + u.dy); 2894. 	return 1; 2895. } 2896.  2897. STATIC_OVL int 2898. disarm_landmine(ttmp) /* Helge Hafting */ 2899. struct trap *ttmp; 2900. { 2901. 	int fails = try_disarm(ttmp, FALSE); 2902. 2903. 	if (fails < 2) return fails; 2904. 	You("disarm %s land mine.", the_your[ttmp->madeby_u]); 2905. 	cnv_trap_obj(LAND_MINE, 1, ttmp); 2906. 	return 1; 2907. } 2908.  2909. /* getobj will filter down to cans of grease and known potions of oil */ 2910. static NEARDATA const char oil[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS, 0 }; 2911. 2912. /* it may not make much sense to use grease on floor boards, but so what? */ 2913. STATIC_OVL int 2914. disarm_squeaky_board(ttmp) 2915. struct trap *ttmp; 2916. { 2917. 	struct obj *obj; 2918. 	boolean bad_tool; 2919. 	int fails; 2920. 2921. 	obj = getobj(oil, "untrap with"); 2922. 	if (!obj) return 0; 2923. 2924. 	bad_tool = (obj->cursed ||  2925. 			((obj->otyp != POT_OIL || obj->lamplit) && 2926. 			 (obj->otyp != CAN_OF_GREASE || !obj->spe))); 2927. 2928. 	fails = try_disarm(ttmp, bad_tool); 2929. 	if (fails < 2) return fails; 2930. 2931. 	/* successfully used oil or grease to fix squeaky board */ 2932. 	if (obj->otyp == CAN_OF_GREASE) { 2933. 	   check_unpaid(obj); 2934. 	   obj->spe--; 2935. 	} else { 2936. 	   useup(obj);	/* oil */ 2937. 	   makeknown(POT_OIL); 2938. 	} 2939. 	You("repair the squeaky board.");	/* no madeby_u */ 2940. 	deltrap(ttmp); 2941. 	newsym(u.ux + u.dx, u.uy + u.dy); 2942. 	more_experienced(1, 5); 2943. 	newexplevel; 2944. 	return 1; 2945. } 2946.  2947. /* removes traps that shoot arrows, darts, etc. */ 2948. STATIC_OVL int 2949. disarm_shooting_trap(ttmp, otyp) 2950. struct trap *ttmp; 2951. int otyp; 2952. { 2953. 	int fails = try_disarm(ttmp, FALSE); 2954. 2955. 	if (fails < 2) return fails; 2956. 	You("disarm %s trap.", the_your[ttmp->madeby_u]); 2957. 	cnv_trap_obj(otyp, 50-rnl(50), ttmp); 2958. 	return 1; 2959. } 2960.  2961. /* Is the weight too heavy? 2962. * Formula as in near_capacity & check_capacity */ 2963. STATIC_OVL int 2964. try_lift(mtmp, ttmp, wt, stuff) 2965. struct monst *mtmp; 2966. struct trap *ttmp; 2967. int wt; 2968. boolean stuff; 2969. { 2970. 	int wc = weight_cap; 2971. 2972. 	if (((wt * 2) / wc) >= HVY_ENCUMBER) { 2973. 	   pline("%s is %s for you to lift.", Monnam(mtmp),  2974. 		  stuff ? "carrying too much" : "too heavy"); 2975. 	   if (!ttmp->madeby_u && !mtmp->mpeaceful && mtmp->mcanmove &&  2976. 		    !mindless(mtmp->data) &&  2977. 		    mtmp->data->mlet != S_HUMAN && rnl(10) < 3) { 2978. 		mtmp->mpeaceful = 1; 2979. 		set_malign(mtmp);		/* reset alignment */ 2980. 		pline("%s thinks it was nice of you to try.", Monnam(mtmp)); 2981. 	   }  2982. 	    return 0; 2983. 	} 2984. 	return 1; 2985. } 2986.  2987. /* Help trapped monster (out of a (spiked) pit) */ 2988. STATIC_OVL int 2989. help_monster_out(mtmp, ttmp) 2990. struct monst *mtmp; 2991. struct trap *ttmp; 2992. { 2993. 	int wt; 2994. 	struct obj *otmp; 2995. 	boolean uprob; 2996. 2997. 	/*  2998. 	 * This works when levitating too -- consistent with the ability 2999. 	 * to hit monsters while levitating. 3000. 	 * 3001. 	 * Should perhaps check that our hero has arms/hands at the 3002. 	 * moment. Helping can also be done by engulfing... 3003. * 3004. 	 * Test the monster first - monsters are displayed before traps. 3005. 	 */ 3006. 	if (!mtmp->mtrapped) { 3007. 		pline("%s isn't trapped.", Monnam(mtmp)); 3008. 		return 0; 3009. 	} 3010. 	/* Do you have the necessary capacity to lift anything? */ 3011. 	if (check_capacity((char *)0)) return 1; 3012. 3013. 	/* Will our hero succeed? */ 3014. 	if ((uprob = untrap_prob(ttmp)) && !mtmp->msleeping && mtmp->mcanmove) { 3015. 		You("try to reach out your %s, but %s backs away skeptically.", 3016. 			makeplural(body_part(ARM)),  3017. 			mon_nam(mtmp)); 3018. 		return 1; 3019. 	} 3020.  3021.  3022. 	/* is it a cockatrice?... */ 3023. 	if (touch_petrifies(mtmp->data) && !uarmg && !Stone_resistance) { 3024. 		You("grab the trapped %s using your bare %s.", 3025. 				mtmp->data->mname, makeplural(body_part(HAND))); 3026. 3027. 		if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) 3028. 			display_nhwindow(WIN_MESSAGE, FALSE); 3029. 		else { 3030. 			char kbuf[BUFSZ]; 3031. 3032. 			Sprintf(kbuf, "trying to help %s out of a pit",  3033. 					an(mtmp->data->mname)); 3034. 			instapetrify(kbuf); 3035. 			return 1; 3036. 		} 3037. 	}  3038. 	/* need to do cockatrice check first if sleeping or paralyzed */ 3039. 	if (uprob) { 3040. 	   You("try to grab %s, but cannot get a firm grasp.",  3041. 		mon_nam(mtmp)); 3042. 	   if (mtmp->msleeping) { 3043. 		mtmp->msleeping = 0; 3044. 		pline("%s awakens.", Monnam(mtmp)); 3045. 	   }  3046. 	    return 1; 3047. 	} 3048.  3049. 	You("reach out your %s and grab %s.",  3050. 	    makeplural(body_part(ARM)), mon_nam(mtmp)); 3051. 3052. 	if (mtmp->msleeping) { 3053. 	   mtmp->msleeping = 0; 3054. 	   pline("%s awakens.", Monnam(mtmp)); 3055. 	} else if (mtmp->mfrozen && !rn2(mtmp->mfrozen)) { 3056. 	   /* After such manhandling, perhaps the effect wears off */ 3057. 	   mtmp->mcanmove = 1; 3058. 	   mtmp->mfrozen = 0; 3059. 	   pline("%s stirs.", Monnam(mtmp)); 3060. 	} 3061.  3062. 	/* is the monster too heavy? */ 3063. 	wt = inv_weight + mtmp->data->cwt; 3064. 	if (!try_lift(mtmp, ttmp, wt, FALSE)) return 1; 3065. 3066. 	/* is the monster with inventory too heavy? */ 3067. 	for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) 3068. 		wt += otmp->owt; 3069. 	if (!try_lift(mtmp, ttmp, wt, TRUE)) return 1; 3070. 3071. 	You("pull %s out of the pit.", mon_nam(mtmp)); 3072. 	mtmp->mtrapped = 0; 3073. 	fill_pit(mtmp->mx, mtmp->my); 3074. 	reward_untrap(ttmp, mtmp); 3075. 	return 1; 3076. } 3077.  3078. int 3079. untrap(force) 3080. boolean force; 3081. { 3082. 	register struct obj *otmp; 3083. 	register boolean confused = (Confusion > 0 || Hallucination > 0); 3084. 	register int x,y; 3085. 	int ch; 3086. 	struct trap *ttmp; 3087. 	struct monst *mtmp; 3088. 	boolean trap_skipped = FALSE; 3089. 3090. 	if(!getdir((char *)0)) return(0); 3091. 	x = u.ux + u.dx; 3092. 	y = u.uy + u.dy; 3093. 3094. 	if ((ttmp = t_at(x,y)) && ttmp->tseen) { 3095. 		if (u.utrap) { 3096. 			You("cannot deal with traps while trapped!"); 3097. 			return 1; 3098. 		} 3099. 		switch(ttmp->ttyp) { 3100. 			case BEAR_TRAP: 3101. 			case WEB: 3102. 				return disarm_holdingtrap(ttmp); 3103. 			case LANDMINE: 3104. 				return disarm_landmine(ttmp); 3105. 			case SQKY_BOARD: 3106. 				return disarm_squeaky_board(ttmp); 3107. 			case DART_TRAP: 3108. 				return disarm_shooting_trap(ttmp, DART); 3109. 			case ARROW_TRAP: 3110. 				return disarm_shooting_trap(ttmp, ARROW); 3111. 			case PIT: 3112. 			case SPIKED_PIT: 3113. 				if (!u.dx && !u.dy) { 3114. 				   You("are already on the edge of the pit."); 3115. 				   return 0; 3116. 				} 3117. 				if (!(mtmp = m_at(x,y))) { 3118. 				   pline("Try filling the pit instead."); 3119. 				   return 0; 3120. 				} 3121. 				return help_monster_out(mtmp, ttmp); 3122. 			default: 3123. 				You("cannot disable %s trap.", (u.dx || u.dy) ? "that" : "this"); 3124. 				return 0; 3125. 		} /* end switch */ 3126. 	} /* end if */ 3127. 3128. 	if(!u.dx && !u.dy) { 3129. 	   for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) 3130. 		if(Is_box(otmp)) { 3131. 		   There("is %s here.", doname(otmp)); 3132. 3133. 		    switch (ynq("Check for traps?")) { 3134. 			case 'q': return(0); 3135. 			case 'n': continue; 3136. 		   }  3137.  3138. 		    if((otmp->otrapped && (force || (!confused 3139. 				&& rn2(MAXULEV + 1 - u.ulevel) < 10))) 3140. 		       || (!force && confused && !rn2(3))) { 3141. 			You("find a trap on %s!", the(xname(otmp))); 3142. 			exercise(A_WIS, TRUE); 3143. 3144. 			switch (ynq("Disarm it?")) { 3145. 			   case 'q': return(1); 3146. 			   case 'n': trap_skipped = TRUE;  continue; 3147. 			} 3148.  3149. 			if(otmp->otrapped) { 3150. 			   exercise(A_DEX, TRUE); 3151. 			   ch = ACURR(A_DEX) + u.ulevel; 3152. 			   if (Role_if(PM_ROGUE)) ch *= 2; 3153. 			   if(!force && (confused || Fumbling || 3154. 				rnd(75+level_difficulty/2) > ch)) { 3155. 				(void) chest_trap(otmp, FINGER, TRUE); 3156. 			   } else { 3157. 				You("disarm it!"); 3158. 				otmp->otrapped = 0; 3159. 			   }  3160. 			} else pline("That %s was not trapped.", xname(otmp)); 3161. 			return(1); 3162. 		   } else { 3163. 			You("find no traps on %s.", the(xname(otmp))); 3164. 			return(1); 3165. 		   }  3166. 		}  3167.  3168. 	    You(trap_skipped ? "find no other traps here."  3169. 			     : "know of no traps here."); 3170. 	   return(0); 3171. 	} 3172.  3173. 	if ((mtmp = m_at(x,y))				&&  3174. 		mtmp->m_ap_type == M_AP_FURNITURE	&&  3175. 		(mtmp->mappearance == S_hcdoor || 3176. 			mtmp->mappearance == S_vcdoor)	&& 3177. 		!Protection_from_shape_changers)	 { 3178. 3179. 	    stumble_onto_mimic(mtmp); 3180. 	   return(1); 3181. 	} 3182.  3183. 	if (!IS_DOOR(levl[x][y].typ)) { 3184. 	   if ((ttmp = t_at(x,y)) && ttmp->tseen) 3185. 		You("cannot disable that trap."); 3186. 	   else 3187. 		You("know of no traps there."); 3188. 	   return(0); 3189. 	} 3190.  3191. 	switch (levl[x][y].doormask) { 3192. 	   case D_NODOOR: 3193. 		You("%s no door there.", Blind ? "feel" : "see"); 3194. 		return(0); 3195. 	   case D_ISOPEN: 3196. 		pline("This door is safely open."); 3197. 		return(0); 3198. 	   case D_BROKEN: 3199. 		pline("This door is broken."); 3200. 		return(0); 3201. 	} 3202.  3203. 	if ((levl[x][y].doormask & D_TRAPPED 3204. 	    && (force ||  3205. 		 (!confused && rn2(MAXULEV - u.ulevel + 11) < 10)))  3206. 	    || (!force && confused && !rn2(3))) { 3207. 		You("find a trap on the door!"); 3208. 		exercise(A_WIS, TRUE); 3209. 		if (ynq("Disarm it?") != 'y') return(1); 3210. 		if (levl[x][y].doormask & D_TRAPPED) { 3211. 		   ch = 15 + (Role_if(PM_ROGUE) ? u.ulevel*3 : u.ulevel); 3212. 		   exercise(A_DEX, TRUE); 3213. 		   if(!force && (confused || Fumbling || 3214. 				    rnd(75+level_difficulty/2) > ch)) { 3215. 			You("set it off!"); 3216. 			b_trapped("door", FINGER); 3217. 			levl[x][y].doormask = D_NODOOR; 3218. 			unblock_point(x, y); 3219. 			newsym(x, y); 3220. 			/* (probably ought to charge for this damage...) */ 3221. 			if (*in_rooms(x, y, SHOPBASE)) add_damage(x, y, 0L); 3222. 		   } else { 3223. 			You("disarm it!"); 3224. 			levl[x][y].doormask &= ~D_TRAPPED; 3225. 		   }  3226. 		} else pline("This door was not trapped."); 3227. 		return(1); 3228. 	} else { 3229. 		You("find no traps on the door."); 3230. 		return(1); 3231. 	} 3232. }  3233. #endif /* OVL2 */ 3234. #ifdef OVLB 3235. 3236. /* only called when the player is doing something to the chest directly */ 3237. boolean 3238. chest_trap(obj, bodypart, disarm) 3239. register struct obj *obj; 3240. register int bodypart; 3241. boolean disarm; 3242. { 3243. 	register struct obj *otmp = obj, *otmp2; 3244. 	char	buf[80]; 3245. 	const char *msg; 3246. 	coord cc; 3247. 3248. 	if (get_obj_location(obj, &cc.x, &cc.y, 0))	/* might be carried */ 3249. 	   obj->ox = cc.x,  obj->oy = cc.y;  3250. 3251. 	otmp->otrapped = 0;	/* trap is one-shot; clear flag first in case 3252. 				  chest kills you and ends up in bones file */ 3253. 	You(disarm ? "set it off!" : "trigger a trap!"); 3254. 	display_nhwindow(WIN_MESSAGE, FALSE); 3255. 	if (Luck > -13 && rn2(13+Luck) > 7) {	/* saved by luck */ 3256. 	   /* trap went off, but good luck prevents damage */ 3257. 	   switch (rn2(13)) { 3258. 		case 12: 3259. 		case 11: msg = "explosive charge is a dud";  break; 3260. 		case 10: 3261. 		case 9:  msg = "electric charge is grounded";  break; 3262. 		case 8: 3263. 		case 7:  msg = "flame fizzles out";  break; 3264. 		case 6: 3265. 		case 5: 3266. 		case 4:  msg = "poisoned needle misses";  break; 3267. 		case 3: 3268. 		case 2: 3269. 		case 1: 3270. 		case 0:  msg = "gas cloud blows away";  break; 3271. 		default: impossible("chest disarm bug");  msg = (char *)0; 3272. 			 break; 3273. 	   }  3274. 	    if (msg) pline("But luckily the %s!", msg); 3275. 	} else { 3276. 	   switch(rn2(20) ? ((Luck >= 13) ? 0 : rn2(13-Luck)) : rn2(26)) { 3277. 		case 25: 3278. 		case 24: 3279. 		case 23: 3280. 		case 22: 3281. 		case 21: { 3282. 			 struct monst *shkp = 0; 3283. 			 long loss = 0L; 3284. 			 boolean costly, insider; 3285. 			 register xchar ox = obj->ox, oy = obj->oy; 3286. 3287. 			  /* the obj location need not be that of player */ 3288. 			 costly = (costly_spot(ox, oy) &&  3289. 				   (shkp = shop_keeper(*in_rooms(ox, oy, 3290. 				   SHOPBASE))) != (struct monst *)0); 3291. 			 insider = (*u.ushops && inside_shop(u.ux, u.uy) &&  3292. 				    *in_rooms(ox, oy, SHOPBASE) == *u.ushops); 3293. 3294. 			  pline("%s!", Tobjnam(obj, "explode")); 3295. 			 Sprintf(buf, "exploding %s", xname(obj)); 3296. 3297. 			  if(costly) 3298. 			     loss += stolen_value(obj, ox, oy,  3299. 						(boolean)shkp->mpeaceful, TRUE); 3300. 			 delete_contents(obj); 3301. 			 for(otmp = level.objects[u.ux][u.uy];  3302. 							otmp; otmp = otmp2) { 3303. 			     otmp2 = otmp->nexthere; 3304. 			     if(costly) 3305. 				 loss += stolen_value(otmp, otmp->ox,  3306. 					  otmp->oy, (boolean)shkp->mpeaceful,  3307. 					  TRUE); 3308. 			     delobj(otmp); 3309. 			 }  3310. 			  wake_nearby; 3311. 			 losehp(d(6,6), buf, KILLED_BY_AN); 3312. 			 exercise(A_STR, FALSE); 3313. 			 if(costly && loss) { 3314. 			     if(insider) 3315. 			     You("owe %ld %s for objects destroyed.",  3316. 							loss, currency(loss)); 3317. 			     else { 3318. 				 You("caused %ld %s worth of damage!",  3319. 							loss, currency(loss)); 3320. 				 make_angry_shk(shkp, ox, oy); 3321. 			     }  3322. 			  }  3323. 			  return TRUE; 3324. 			} 3325. 		case 20: 3326. 		case 19: 3327. 		case 18: 3328. 		case 17: 3329. 			pline("A cloud of noxious gas billows from %s.", 3330. 							the(xname(obj))); 3331. 			poisoned("gas cloud", A_STR, "cloud of poison gas",15); 3332. 			exercise(A_CON, FALSE); 3333. 			break; 3334. 		case 16: 3335. 		case 15: 3336. 		case 14: 3337. 		case 13: 3338. 			You_feel("a needle prick your %s.",body_part(bodypart)); 3339. 			poisoned("needle", A_CON, "poisoned needle",10); 3340. 			exercise(A_CON, FALSE); 3341. 			break; 3342. 		case 12: 3343. 		case 11: 3344. 		case 10: 3345. 		case 9: 3346. 			dofiretrap(obj); 3347. 			break; 3348. 		case 8: 3349. 		case 7: 3350. 		case 6: { 3351. 			int dmg; 3352. 3353. 			You("are jolted by a surge of electricity!"); 3354. 			if(Shock_resistance) { 3355. 			   shieldeff(u.ux, u.uy); 3356. 			   You("don't seem to be affected."); 3357. 			   dmg = 0; 3358. 			} else 3359. 			   dmg = d(4, 4); 3360. 			destroy_item(RING_CLASS, AD_ELEC); 3361. 			destroy_item(WAND_CLASS, AD_ELEC); 3362. 			if (dmg) losehp(dmg, "electric shock", KILLED_BY_AN); 3363. 			break; 3364. 		     }  3365. 		case 5: 3366. 		case 4: 3367. 		case 3: 3368. 			if (!Free_action) { 3369. 			pline("Suddenly you are frozen in place!"); 3370. 			nomul(-d(5, 6)); 3371. 			exercise(A_DEX, FALSE); 3372. 			nomovemsg = You_can_move_again; 3373. 			} else You("momentarily stiffen."); 3374. 			break; 3375. 		case 2: 3376. 		case 1: 3377. 		case 0: 3378. 			pline("A cloud of %s gas billows from %s.", 3379. 						hcolor((char *)0),  3380. 						the(xname(obj))); 3381. 			if(!Stunned) { 3382. 			   if (Hallucination) 3383. 				pline("What a groovy feeling!"); 3384. 			   else if (Blind) 3385. 				You("%s and get dizzy...", 3386. 				    stagger(youmonst.data, "stagger")); 3387. 			   else 3388. 				You("%s and your vision blurs...", 3389. 				    stagger(youmonst.data, "stagger")); 3390. 			} 3391. 			make_stunned(HStun + rn1(7, 16),FALSE); 3392. 			make_hallucinated(HHallucination + rn1(5, 16),FALSE,0L); 3393. 			break; 3394. 		default: impossible("bad chest trap"); 3395. 			break; 3396. 	   }  3397. 	    bot;			/* to get immediate botl re-display */ 3398. 	} 3399.  3400. 	return FALSE; 3401. } 3402.  3403. #endif /* OVLB */ 3404. #ifdef OVL0 3405. 3406. struct trap * 3407. t_at(x,y) 3408. register int x, y; 3409. { 3410. 	register struct trap *trap = ftrap; 3411. 	while(trap) { 3412. 		if(trap->tx == x && trap->ty == y) return(trap); 3413. 		trap = trap->ntrap; 3414. 	} 3415. 	return((struct trap *)0); 3416. } 3417.  3418. #endif /* OVL0 */ 3419. #ifdef OVLB 3420. 3421. void 3422. deltrap(trap) 3423. register struct trap *trap; 3424. { 3425. 	register struct trap *ttmp; 3426. 3427. 	if(trap == ftrap) 3428. 		ftrap = ftrap->ntrap; 3429. 	else { 3430. 		for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ; 3431. 		ttmp->ntrap = trap->ntrap; 3432. 	} 3433. 	dealloc_trap(trap); 3434. } 3435.  3436. boolean delfloortrap(ttmp) 3437. register struct trap *ttmp; 3438. { 3439. 	/* Destroy a trap that emanates from the floor. */ 3440. 	/* some of these are arbitrary -dlc */ 3441. 	if (ttmp && ((ttmp->ttyp == SQKY_BOARD) || 3442. 		    (ttmp->ttyp == BEAR_TRAP) || 3443. 		    (ttmp->ttyp == LANDMINE) || 3444. 		    (ttmp->ttyp == FIRE_TRAP) || 3445. 		    (ttmp->ttyp == PIT) || 3446. 		    (ttmp->ttyp == SPIKED_PIT) || 3447. 		    (ttmp->ttyp == HOLE) || 3448. 		    (ttmp->ttyp == TRAPDOOR) || 3449. 		    (ttmp->ttyp == TELEP_TRAP) || 3450. 		    (ttmp->ttyp == LEVEL_TELEP) || 3451. 		    (ttmp->ttyp == WEB) || 3452. 		    (ttmp->ttyp == MAGIC_TRAP) || 3453. 		    (ttmp->ttyp == ANTI_MAGIC))) { 3454. 	   register struct monst *mtmp; 3455. 3456. 	    if (ttmp->tx == u.ux && ttmp->ty == u.uy) { 3457. 		u.utrap = 0; 3458. 		u.utraptype = 0; 3459. 	   } else if ((mtmp = m_at(ttmp->tx, ttmp->ty)) != 0) { 3460. 		mtmp->mtrapped = 0; 3461. 	   }  3462. 	    deltrap(ttmp); 3463. 	   return TRUE; 3464. 	} else 3465. 	   return FALSE; 3466. } 3467.  3468. /* used for doors (also tins). can be used for anything else that opens. */ 3469. void 3470. b_trapped(item, bodypart) 3471. register const char *item; 3472. register int bodypart; 3473. { 3474. 	register int lvl = level_difficulty; 3475. 	int dmg = rnd(5 + (lvl < 5 ? lvl : 2+lvl/2)); 3476. 3477. 	pline("KABOOM!!  %s was booby-trapped!", The(item)); 3478. 	wake_nearby; 3479. 	losehp(dmg, "explosion", KILLED_BY_AN); 3480. 	exercise(A_STR, FALSE); 3481. 	if (bodypart) exercise(A_CON, FALSE); 3482. 	make_stunned(HStun + dmg, TRUE); 3483. } 3484.  3485. /* Monster is hit by trap. */ 3486. /* Note: doesn't work if both obj and d_override are null */ 3487. STATIC_OVL boolean 3488. thitm(tlev, mon, obj, d_override) 3489. register int tlev; 3490. register struct monst *mon; 3491. register struct obj *obj; 3492. int d_override; 3493. { 3494. 	register int strike; 3495. 	register boolean trapkilled = FALSE; 3496. 3497. 	if (d_override) strike = 1; 3498. 	else if (obj) strike = (find_mac(mon) + tlev + obj->spe <= rnd(20)); 3499. 	else strike = (find_mac(mon) + tlev <= rnd(20)); 3500. 3501. 	/* Actually more accurate than thitu, which doesn't take 3502. 	 * obj->spe into account. 3503. 	 */ 3504. 	if(!strike) { 3505. 		if (obj && cansee(mon->mx, mon->my)) 3506. 		   pline("%s is almost hit by %s!", Monnam(mon), doname(obj)); 3507. 	} else { 3508. 		int dam = 1; 3509. 3510. 		if (obj && cansee(mon->mx, mon->my)) 3511. 			pline("%s is hit by %s!", Monnam(mon), doname(obj)); 3512. 		if (d_override) dam = d_override; 3513. 		else if (obj) { 3514. 			dam = dmgval(obj, mon); 3515. 			if (dam < 1) dam = 1; 3516. 		} 3517. 		if ((mon->mhp -= dam) <= 0) { 3518. 			int xx = mon->mx; 3519. 			int yy = mon->my; 3520. 3521. 			monkilled(mon, "", AD_PHYS); 3522. 			if (mon->mhp <= 0) { 3523. 				newsym(xx, yy); 3524. 				trapkilled = TRUE; 3525. 			} 3526. 		}  3527. 	}  3528. 	if (obj && (!strike || d_override)) { 3529. 		place_object(obj, mon->mx, mon->my); 3530. 		stackobj(obj); 3531. 	} else if (obj) dealloc_obj(obj); 3532. 3533. 	return trapkilled; 3534. } 3535.  3536. boolean 3537. unconscious 3538. { 3539. 	return((boolean)(multi < 0 && (!nomovemsg ||  3540. 		u.usleep ||  3541. 		!strncmp(nomovemsg,"You regain con", 14) ||  3542. 		!strncmp(nomovemsg,"You are consci", 14)))); 3543. } 3544.  3545. static char lava_killer[] = "molten lava"; 3546. 3547. boolean 3548. lava_effects 3549. { 3550.     register struct obj *obj, *obj2; 3551.    int dmg; 3552.    boolean usurvive; 3553. 3554.     burn_away_slime; 3555.    if (likes_lava(youmonst.data)) return FALSE; 3556. 3557.     if (!Fire_resistance) { 3558. 	if(Wwalking) { 3559. 	   dmg = d(6,6); 3560. 	   pline_The("lava here burns you!"); 3561. 	   if(dmg < u.uhp) { 3562. 		losehp(dmg, lava_killer, KILLED_BY); 3563. 		goto burn_stuff; 3564. 	   }  3565. 	} else 3566. 	   You("fall into the lava!"); 3567. 3568. 	usurvive = Lifesaved || discover; 3569. #ifdef WIZARD 3570. 	if (wizard) usurvive = TRUE; 3571. #endif 3572. 	for(obj = invent; obj; obj = obj2) { 3573. 	   obj2 = obj->nobj; 3574. 	   if(is_organic(obj) && !obj->oerodeproof) { 3575. 		if(obj->owornmask) { 3576. 		   if (usurvive) 3577. 			Your("%s into flame!", aobjnam(obj, "burst")); 3578. 3579. 		    if(obj == uarm) (void) Armor_gone; 3580. 		   else if(obj == uarmc) (void) Cloak_off; 3581. 		   else if(obj == uarmh) (void) Helmet_off; 3582. 		   else if(obj == uarms) (void) Shield_off; 3583. 		   else if(obj == uarmg) (void) Gloves_off; 3584. 		   else if(obj == uarmf) (void) Boots_off; 3585. #ifdef TOURIST 3586. 		   else if(obj == uarmu) setnotworn(obj); 3587. #endif 3588. 		   else if(obj == uleft) Ring_gone(obj); 3589. 		   else if(obj == uright) Ring_gone(obj); 3590. 		   else if(obj == ublindf) Blindf_off(obj); 3591. 		   else if(obj == uamul) Amulet_off; 3592. 		   else if(obj == uwep) uwepgone; 3593. 		   else if (obj == uquiver) uqwepgone; 3594. 		   else if (obj == uswapwep) uswapwepgone; 3595. 		} 3596. 		useupall(obj); 3597. 	   }  3598. 	}  3599.  3600. 	/* s/he died... */ 3601. 	u.uhp = -1; 3602. 	killer_format = KILLED_BY; 3603. 	killer = lava_killer; 3604. 	You("burn to a crisp..."); 3605. 	done(BURNING); 3606. 	while (!safe_teleds) { 3607. 		pline("You're still burning."); 3608. 		done(BURNING); 3609. 	} 3610. 	You("find yourself back on solid %s.", surface(u.ux, u.uy)); 3611. 	return(TRUE); 3612.    }  3613.  3614.     if (!Wwalking) { 3615. 	u.utrap = rn1(4, 4) + (rn1(4, 12) << 8); 3616. 	u.utraptype = TT_LAVA; 3617. 	You("sink into the lava, but it only burns slightly!"); 3618. 	if (u.uhp > 1) 3619. 	   losehp(1, lava_killer, KILLED_BY); 3620.    }  3621.     /* just want to burn boots, not all armor; destroy_item doesn't work on  3622. armor anyway */ 3623. burn_stuff: 3624.    if(uarmf && !uarmf->oerodeproof && is_organic(uarmf)) { 3625. 	/* save uarmf value because Boots_off sets uarmf to null */ 3626. 	obj = uarmf; 3627. 	Your("%s bursts into flame!", xname(obj)); 3628. 	(void) Boots_off; 3629. 	useup(obj); 3630.    }  3631.     destroy_item(SCROLL_CLASS, AD_FIRE); 3632.    destroy_item(SPBOOK_CLASS, AD_FIRE); 3633.    destroy_item(POTION_CLASS, AD_FIRE); 3634.    return(FALSE); 3635. } 3636.  3637. #endif /* OVLB */ 3638. 3639. /*trap.c*/