Source:NetHack 3.3.0/trap.c

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