Source:NetHack 3.0.0/trap.c

Below is the full text to trap.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.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.0	88/10/22 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include	"hack.h"  6.    #include	"edog.h"  7.    #include	"trapname.h"  8. 9.   void domagictrap; 10.  static boolean thitm; 11.   12.   /* Generic rust-armor function. Returns TRUE if a message was printed; 13.   * "print", if set, means to print a message (and thus to return TRUE) even 14.   * if the item could not be rusted; otherwise a message is printed and TRUE is  15. * returned only for rustable items. 16.   */  17.   boolean 18.  rust_dmg(otmp, ostr, type, print) 19.  register struct obj *otmp; 20.  register char *ostr; 21.  int type; 22.  boolean print; 23.  {  24.   	static const char *gook[] = { "slag", "rust", "rot", "corrosion" }; 25.  	static const char *action[] = { "smolder", "rust", "rot", "corrode" }; 26.  	boolean vulnerable = FALSE; 27.  	boolean plural; 28.   29.   	if (!otmp) return(FALSE); 30.  	switch(type) { 31.  		case 0: 32.  		case 2: vulnerable = is_flammable(otmp); break; 33.  		case 1: vulnerable = is_rustprone(otmp); break; 34.  		case 3: vulnerable = (otmp->otyp == BRONZE_PLATE_MAIL); break; 35.  	}  36.    37.   	if (!print && (!vulnerable || otmp->rustfree || otmp->spe < -2)) 38.  		return FALSE; 39.   40.   	plural = is_gloves(otmp) || is_boots(otmp); 41.   42.   	if (!vulnerable) 43.  		Your("%s %s not affected!", ostr, plural ? "are" : "is"); 44.  	else if (otmp->spe >= -2) { 45.  		if (otmp->rustfree) 46.  			pline("The %s on your %s vanishes instantly!",  47.   						gook[type], ostr); 48.  		else if (otmp->blessed && !rnl(4)) 49.  			pline("Somehow, your %s %s not affected!", ostr,  50.   					plural ? "are" : "is"); 51.  		else { 52.  			Your("%s %s%s!", ostr, action[type],  53.   				plural ? "" : "s"); 54.  			otmp->spe--; 55.  			adj_abon(otmp, -1); 56.  		}  57.   	} else Your("%s look%s quite rusted.", ostr, plural ? "" : "s"); 58.  	return(TRUE); 59.  }  60.    61.   struct trap * 62.  maketrap(x,y,typ) 63.  register int x, y, typ; 64.  {  65.   	register struct trap *ttmp; 66.  	register struct permonst *ptr; 67.   68.   	ttmp = newtrap; 69.  	ttmp->ttyp = typ; 70.  	ttmp->tx = x;  71. ttmp->ty = y; 72. switch(typ) { 73.  	    case MONST_TRAP:	    /* create a monster in "hiding" */ 74.  		if(rn2(5) && (ptr = mkclass(S_PIERCER))) 75.  			ttmp->pm = monsndx(ptr); 76.  		else 77.  			ttmp->pm = rndmonnum; 78.  		break; 79.  	    case STATUE_TRAP:	    /* create a "living" statue */ 80.  		ttmp->pm = rndmonnum; 81.  		(void) mkstatue(&mons[ttmp->pm], x, y); 82.  		break; 83.  	    default: 84.  		ttmp->pm = -1; 85.  		break; 86.  	}  87.   	ttmp->tseen = 0; 88.  	ttmp->once = 0; 89.  	ttmp->ntrap = ftrap; 90.  	ftrap = ttmp; 91.  	return(ttmp); 92.  }  93.    94.   int 95.  teleok(x, y)  96. register int x, y; 97. {				/* might throw him into a POOL 98.  				 * removed by GAN 10/20/86 99.  				 */  100.  #ifdef STUPID 101. 	boolean	tmp1, tmp2, tmp3; 102. #  ifdef POLYSELF 103. 	tmp1 = isok(x,y) && (!IS_ROCK(levl[x][y].typ) ||  104.  		passes_walls(uasmon)) && !levl[x][y].mmask; 105. #  else 106. 	tmp1 = isok(x,y) && !IS_ROCK(levl[x][y].typ) && !levl[x][y].mmask; 107. #  endif 108. 	tmp2 = !sobj_at(BOULDER,x,y) && !t_at(x,y); 109. 	tmp3 = !(is_pool(x,y) &&  110.  	       !(Levitation || Wwalking 111. #ifdef POLYSELF 112. 		 || is_flyer(uasmon) 113. #endif 114. 		)) &&  115.  	       !(IS_DOOR(levl[x][y].typ) &&  116.  		     (levl[x][y].doormask & (D_LOCKED | D_CLOSED))); 117. 	return(tmp1 && tmp2 && tmp3); 118. #else 119. 	return( isok(x,y) &&  120.  #  ifdef POLYSELF  121.  		(!IS_ROCK(levl[x][y].typ) || passes_walls(uasmon)) &&  122.  #  else  123.  		!IS_ROCK(levl[x][y].typ) &&  124.  #  endif  125.  		!levl[x][y].mmask &&  126.  		!sobj_at(BOULDER,x,y) && !t_at(x,y) &&  127.  		!(is_pool(x,y) && 128. 		!(Levitation || Wwalking  129.  #ifdef POLYSELF  130.  		  || is_flyer(uasmon)  131.  #endif  132.  		  )) &&  133.  		!(IS_DOOR(levl[x][y].typ) && 134. 		     (levl[x][y].doormask & (D_LOCKED | D_CLOSED)))  135.  	); 136. #endif 137. 	/* Note: gold is permitted (because of vaults) */ 138. }  139.   140.  static void 141. vtele { 142. 	register struct mkroom *croom; 143.  144.  	for(croom = &rooms[0]; croom->hx >= 0; croom++) 145. 	    if(croom->rtype == VAULT) { 146. 		register int x, y;  147. 148. 		x = rn2(2) ? croom->lx : croom->hx; 149. 		y = rn2(2) ? croom->ly : croom->hy; 150. 		if(teleok(x,y)) { 151. 		    teleds(x,y); 152. 		    return; 153. 		}  154.  	    }  155.  	tele; 156. }  157.   158.  void 159. dotrap(trap) 160. register struct trap *trap; 161. {  162.  	register int ttype = trap->ttyp; 163. 	register struct monst *mtmp; 164. 	register struct obj *otmp; 165.  166.  	nomul(0); 167. 	if(trap->tseen && !Fumbling && !(ttype == PIT 168. 	   || ttype == SPIKED_PIT 169. #ifdef SPELLS 170. 	   || ttype == ANTI_MAGIC 171. #endif 172. 		) && !rn2(5)) 173. 		You("escape a%s.", traps[ttype]); 174. 	else { 175. 	    trap->tseen = 1; 176. 	    if(Invisible && ttype != MONST_TRAP) 177. 		newsym(trap->tx,trap->ty); 178. 	    switch(ttype) { 179. 		case SLP_GAS_TRAP: 180. 		    if(Sleep_resistance) { 181. 			You("are enveloped in a cloud of gas!"); 182. 			break; 183. 		    }  184.  		    pline("A cloud of gas puts you to sleep!"); 185. 		    flags.soundok = 0; 186. 		    nomul(-rnd(25)); 187. 		    afternmv = Hear_again; 188. 		    break; 189. 		case BEAR_TRAP: 190. 		    if(Levitation  191.  #ifdef POLYSELF  192.  			|| is_flyer(uasmon)  193.  #endif  194.  			) { 195. 			You("%s over a bear trap.",  196.  			      Levitation ? "float" : "fly"); 197. 			break; 198. 		    }  199.  		    u.utrap = 4 + rn2(4); 200. 		    u.utraptype = TT_BEARTRAP; 201. 		    pline("A bear trap closes on your %s!",  202.  			body_part(FOOT)); 203. #ifdef POLYSELF 204. 		    if(u.umonnum == PM_OWLBEAR) 205. 			You("howl in anger!"); 206. #endif 207. 		    break; 208. 		case STATUE_TRAP: 209. 		    for(otmp=fobj; otmp; otmp=otmp->nobj) { 210. 			if(otmp->otyp == STATUE && otmp->ox == u.ux &&  211.  				otmp->oy == u.uy && otmp->corpsenm == trap->pm) 212. 			    if(mtmp=makemon(&mons[trap->pm],u.ux,u.uy)) { 213. 				pline("The statue comes to life!"); 214. 				delobj(otmp); 215. 				break; 216. 			    }  217.  		    }  218.  		    deltrap(trap); 219. 		    break; 220. 		case MONST_TRAP: 221. 		    if(mtmp=makemon(&mons[trap->pm],u.ux,u.uy)) { 222. 		      switch(mtmp->data->mlet) { 223. 			case S_PIERCER: 224. 			    pline("%s suddenly drops from the ceiling!",  225.  				  Xmonnam(mtmp)); 226. 			    if(uarmh) 227. 				pline("Its blow glances off your helmet."); 228. 			    else 229. 				(void) thitu(3,d(4,6),"falling piercer"); 230. 			    break; 231. 			default:	/* monster surprises you. */ 232.  			    pline("%s attacks you by surprise!",  233.  				  Xmonnam(mtmp)); 234. 			    break; 235. 		      }  236.  		    }  237.  		    deltrap(trap); 238. 		    break; 239. 		case ARROW_TRAP: 240. 		    pline("An arrow shoots out at you!"); 241. 		    if(!thitu(8,rnd(6),"arrow")){ 242. 			(void) mksobj_at(ARROW, u.ux, u.uy); 243. 			fobj->quan = 1; 244. 			fobj->owt = weight(fobj); 245. 		    }  246.  		    break; 247. 		case TRAPDOOR: 248. 		    if(is_maze_lev  249.  #ifdef STRONGHOLD  250.  		 	 && (dlevel > stronghold_level)  251.  #endif /* STRONGHOLD /**/  252.  		      ) { 253. 	pline("A trap door in the ceiling opens and a rock falls on your %s!",  254.  				body_part(HEAD)); 255. 			if(uarmh) 256. 			    pline("Fortunately, you are wearing a helmet!"); 257. 			losehp(uarmh ? 2 : d(2,10),"falling rock"); 258. 			(void) mksobj_at(ROCK, u.ux, u.uy); 259. 			fobj->quan = 1; 260. 			fobj->owt = weight(fobj); 261. 			stackobj(fobj); 262. 			if(Invisible) newsym(u.ux, u.uy); 263. 		    } else { 264. 			register int newlevel = dlevel + 1; 265. 			while(!rn2(4) && newlevel < 29) newlevel++; 266. 			pline("A trap door opens up under you!"); 267. 			if(Levitation || u.ustuck || dlevel == MAXLEVEL  268.  #ifdef POLYSELF  269.  					|| is_flyer(uasmon)  270.  #endif  271.  #ifdef ENDGAME  272.  					|| dlevel == ENDLEVEL  273.  #endif  274.  							) { 275. 			    You("don't fall in."); 276. 			    break; 277. 			}  278.  #ifdef WALKIES 279. 			if(!next_to_u) 280. 			    You("are jerked back by your pet!"); 281. 			else { 282. #endif 283. 			    unsee; 284. 			    (void) fflush(stdout); 285. 			    goto_level(newlevel, FALSE); 286. #ifdef WALKIES 287. 			}  288.  #endif 289. 		    }  290.  		    break; 291. 		case DART_TRAP: 292. 		    pline("A little dart shoots out at you!"); 293. 		    if(thitu(7,rnd(3),"little dart")) { 294. 			if(!rn2(6)) poisoned("dart",A_CON,"poison dart"); 295. 		    } else { 296. 			(void) mksobj_at(DART, u.ux, u.uy); 297. 			fobj->quan = 1; 298. 			fobj->opoisoned = 1; 299. 			fobj->owt = weight(fobj); 300. 		    }  301.  		    break; 302. 		case TELEP_TRAP: 303. 		    if(trap->once) { 304. 			deltrap(trap); 305. #ifdef ENDGAME 306. 			if(dlevel == ENDLEVEL) { 307. 			    You("feel a wrenching sensation."); 308. 			    break; 309. 			}  310.  #endif 311. 			if(Antimagic) { 312. 			    shieldeff(u.ux, u.uy); 313. 			    You("feel a wrenching sensation."); 314. 			} else { 315. 			    newsym(u.ux, u.uy); 316. 			    vtele; 317. 			}  318.  		    } else { 319. #ifdef ENDGAME 320. 			if(dlevel == ENDLEVEL) { 321. 			    pline("A shiver runs down your spine..."); 322. 			    break; 323. 			}  324.  #endif 325. 			if(Antimagic) { 326. 			    shieldeff(u.ux, u.uy); 327. 			    You("feel a wrenching sensation."); 328. 			} else { 329. 			    newsym(u.ux, u.uy); 330. 			    tele; 331. 			}  332.  		    }  333.  		    break; 334. 		case RUST_TRAP: 335. #ifdef POLYSELF 336. #ifdef GOLEMS 337. 		    if (u.umonnum == PM_IRON_GOLEM) { 338. 			pline("A gush of water hits you!"); 339. 			You("are covered with rust!"); 340. 			rehumanize; 341. 			break; 342. 		    }  343.  #endif /* GOLEMS */ 344. #endif 345. 		/* Unlike monsters, traps cannot aim their rust attacks at  346. * you, so instead of looping through and taking either the 347. 		 * first rustable one or the body, we take whatever we get, 348. 		 * even if it is not rustable. 349. 		 */  350.  		    switch (rn2(5)) { 351. 			case 0: 352. 			    pline("A gush of water hits you on the %s!",  353.  					body_part(HEAD)); 354. 			    (void) rust_dmg(uarmh, "helmet", 1, TRUE); 355. 			    break; 356. 			case 1: 357. 			    pline("A gush of water hits your left %s!",  358.  					body_part(ARM)); 359. 			    if (rust_dmg(uarms, "shield", 1, TRUE)) break; 360. 			    if (uwep && bimanual(uwep)) 361. 				goto two_hand; 362. 			    /* Two goto statements in a row--aaarrrgggh! */ 363.  glovecheck:		    (void) rust_dmg(uarmg, "gauntlets", 1, TRUE); 364. 			    /* Not "metal gauntlets" since it gets called 365. 			     * even if it's leather for the message 366. 			     */  367.  			    break; 368. 			case 2: 369. 			    pline("A gush of water hits your right %s!",  370.  					body_part(ARM)); 371. two_hand:		    corrode_weapon; 372. 			    goto glovecheck; 373. 			default: 374. 			    pline("A gush of water hits you!"); 375. 			    if (uarmc) (void) rust_dmg(uarmc, "cloak", 1, TRUE); 376. 			    else if (uarm) 377. 				(void) rust_dmg(uarm, "armor", 1, TRUE); 378. #ifdef SHIRT 379. 			    else if (uarmu) 380. 				(void) rust_dmg(uarmu, "shirt", 1, TRUE); 381. #endif 382. 		    }  383.  		    break; 384. 		case PIT: 385. 		    if (Levitation  386.  #ifdef POLYSELF  387.  			|| is_flyer(uasmon) || u.umonnum == PM_WUMPUS  388.  #endif  389.  			) { 390. 			pline("A pit opens up under you!"); 391. 			You("don't fall in!"); 392. 			break; 393. 		    }  394.  		    You("fall into a pit!"); 395. #ifdef POLYSELF 396. 		    if (!passes_walls(uasmon)) 397. #endif 398. 			u.utrap = rn1(6,2); 399. 		    u.utraptype = TT_PIT; 400. 		    losehp(rnd(6),"fall into a pit"); 401. 		    selftouch("Falling, you"); 402. 		    break; 403. 		case SPIKED_PIT: 404. 		    if (Levitation  405.  #ifdef POLYSELF  406.  			|| is_flyer(uasmon) || u.umonnum == PM_WUMPUS  407.  #endif  408.  			) { 409. 			pline("A pit full of spikes opens up under you!"); 410. 			You("don't fall in!"); 411. 			break; 412. 		    }  413.  		    You("fall into a pit!"); 414. 		    You("land on a set of sharp iron spikes!"); 415. #ifdef POLYSELF 416. 		    if (!passes_walls(uasmon)) 417. #endif 418. 			u.utrap = rn1(6,2); 419. 		    u.utraptype = TT_PIT; 420. 		    losehp(rnd(10),"fall onto iron spikes"); 421. 		    if(!rn2(6)) poisoned("spikes",A_STR,"poison spikes"); 422. 		    selftouch("Falling, you"); 423. 		    break; 424. 		case LEVEL_TELEP: 425. 		    pline("You have %s onto a level teleport trap!",  426.  #ifdef POLYSELF  427.  			is_flyer(uasmon) ? "flown" :  428.  			(Levitation || nolimbs(uasmon)) ? "moved" : "stepped"); 429. #else 430. 			Levitation ? "moved" : "stepped"); 431.  #endif  432.  		    if(Antimagic)  433.  			shieldeff(u.ux, u.uy);  434.  		    if(Antimagic 435. #ifdef ENDGAME 436. 				|| dlevel == ENDLEVEL 437. #endif 438. 							) {  439.  			You("feel a wrenching sensation.");  440.  			break;  441.  		    }  442.  		    if(!Blind)  443.  		      You("are momentarily blinded by a flash of light.");  444.  		    else  445.  			You("are momentarily disoriented.");  446.  		    deltrap(trap);  447.  		    newsym(u.ux,u.uy);  448.  		    level_tele;  449.  		    break;  450.  #ifdef SPELLS  451.  		case ANTI_MAGIC:  452.  		    if(Antimagic) {  453.  			shieldeff(u.ux, u.uy);  454.  			You("feel momentarily lethargic.");  455.  		    } else drain_en(rnd((int)u.ulevel) + 1);  456.  		    break;  457.  #endif  458.  #ifdef POLYSELF  459.  		case POLY_TRAP:  460.  		    if(Antimagic) {  461.  			shieldeff(u.ux, u.uy);  462.  			You("feel momentarily different.");  463.  			/* Trap did nothing; don't remove it --KAA */  464.  		    } else {  465.  			You("feel a change coming over you.");  466.  			polyself; 467. 			deltrap(trap); 468. 		    }  469.  		    break; 470. #endif 471. 		case MGTRP:	    /* A magic trap. */ 472.  		    if (!rn2(30)) { 473. 			You("are caught in a magical explosion!"); 474. 			losehp(rnd(10), "magical explosion"); 475. #ifdef SPELLS 476. 			Your("body absorbs some of the magical energy!"); 477. 			u.uen = (u.uenmax += 2); 478. #endif 479. 			deltrap(trap); 480. 			if(Invisible) newsym(u.ux,u.uy); 481. 		    } else domagictrap; 482. 		    break; 483. 		case SQBRD:	    /* Stepped on a squeaky board. */ 484.  		    if (Levitation  485.  #ifdef POLYSELF  486.  			|| is_flyer(uasmon)  487.  #endif  488.  			) { 489. 			if (Hallucination) You("notice a crease in the linoleum."); 490. 			else You("notice a loose board below you."); 491. 		    } else { 492. 			pline("A board underfoot gives off a loud squeak!"); 493. 			wake_nearby; 494. 		    }  495.  		    break; 496. 		case WEB: /* Our luckless player has stumbled into a web. */ 497.   498.  		    pline("You've %s into a spider web!",  499.  			  Levitation ? "floated" :  500.  #ifdef POLYSELF  501.  			  is_flyer(uasmon) ? "flown" :  502.  #endif  503.  			  "stumbled"); 504. 		    u.utraptype = TT_WEB; 505.  506.  		    /* Time stuck in the web depends on your strength. */ 507.   508.  		    if (ACURR(A_STR) == 3) u.utrap = rn1(6,6); 509. 		    else if (ACURR(A_STR) < 6) u.utrap = rn1(6,4); 510. 		    else if (ACURR(A_STR) < 9) u.utrap = rn1(4,4); 511. 		    else if (ACURR(A_STR) < 12) u.utrap = rn1(4,2); 512. 		    else if (ACURR(A_STR) < 15) u.utrap = rn1(2,2); 513. 		    else if (ACURR(A_STR) < 18) u.utrap = rnd(2); 514. 		    else if (ACURR(A_STR) < 69) u.utrap = 1; 515. 		    else { 516. 			u.utrap = 0; 517. 			You("tear through the web!"); 518. 			deltrap(trap); 519. 	   		if(Invisible) newsym(u.ux,u.uy); 520. 		    }  521.  		    break; 522.  523.  		case LANDMINE: { 524. #		ifndef LINT 525. 		    register struct monst *mtmp = fmon; 526. #		endif /* LINT */ 527.  528.  		    if (Levitation  529.  #ifdef POLYSELF  530.  						|| is_flyer(uasmon)  531.  #endif  532.  								) { 533. 			You("see a trigger in a pile of soil below you!"); 534. 			if (rn2(3)) break; 535. 			pline("KAABLAMM!!!  The air currents set it off!"); 536. 		    } else { 537. #ifdef POLYSELF 538. 			pline("KAABLAMM!!!  You %s a land mine!",  539.  				nolimbs(uasmon) ? "encountered" : "stepped on"); 540. #else 541. 			pline("KAABLAMM!!!  You stepped on a land mine!"); 542. #endif 543. 			set_wounded_legs(LEFT_SIDE, 40 + rnd(35)); 544. 			set_wounded_legs(RIGHT_SIDE, 40 + rnd(35)); 545. 		    }  546.  		    losehp(rnd(16), "land mine"); 547. 		    /* wake everything on the level */ 548. 		    while(mtmp) { 549. 			if(mtmp->msleep) mtmp->msleep = 0; 550. 			mtmp = mtmp->nmon; 551. 		    }  552.  		    deltrap(t_at(u.ux, u.uy)); /* mines only explode once */ 553. 		    if(Invisible) newsym(u.ux,u.uy); 554. 		    }  555.  		    break; 556. 		default: 557. 		    impossible("You hit a trap of type %u", trap->ttyp); 558. 	    }  559.  	}  560.  }  561.   562.  #ifdef WALKIES 563. static boolean 564. teleport_pet(mtmp) 565. register struct monst *mtmp; 566. {  567.  	register struct obj *otmp; 568.  569.  	if(mtmp->mleashed) { 570. 	    otmp = get_mleash(mtmp); 571. 	    if(!otmp) 572. 		impossible("%s is leashed, without a leash.", Monnam(mtmp)); 573. 	    if(otmp->cursed) { 574. # ifdef SOUNDS 575. 		yelp(mtmp); 576. # endif 577. 		return FALSE; 578. 	    } else { 579. 		Your("leash goes slack."); 580. 		m_unleash(mtmp); 581. 		return TRUE; 582. 	    }  583.  	}  584.  	return TRUE; 585. }  586.  #endif 587.  588.  int 589. mintrap(mtmp) 590. register struct monst *mtmp; 591. {  592.  	register struct trap *trap = t_at(mtmp->mx, mtmp->my); 593. 	register int newlev, wasintrap = mtmp->mtrapped; 594. 	register boolean trapkilled = FALSE, tdoor = FALSE; 595. 	struct obj *otmp; 596.  597.  	if(!trap) { 598. 		mtmp->mtrapped = 0;	/* perhaps teleported? */ 599.  	} else if(wasintrap) { 600. 		if(!rn2(40)) mtmp->mtrapped = 0; 601. 	} else { 602. 	    register int tt = trap->ttyp; 603.  604.  	/* A bug fix for dumb messages by ab@unido. 605. 	 */  606.  	    int in_sight = cansee(mtmp->mx,mtmp->my) 607. 			   && (!mtmp->minvis || See_invisible); 608.  609.  	    if(mtmp->mtrapseen & (1 << tt)) { 610. 		/* he has been in such a trap - perhaps he escapes */ 611. 		if(rn2(4)) return(0); 612. 	    }  613.  	    mtmp->mtrapseen |= (1 << tt); 614. 	    switch (tt) { 615. 		case BEAR_TRAP: 616. 			if(bigmonst(mtmp->data)) { 617. 				if(in_sight) 618. 				  pline("%s is caught in a bear trap!",  619.  					Monnam(mtmp)); 620. 				else 621. 				    if(mtmp->data == &mons[PM_OWLBEAR]  622.  					&& flags.soundok) 623. 			    You("hear the roaring of an angry bear!"); 624. 				mtmp->mtrapped = 1; 625. 			}  626.  			break; 627. #ifdef POLYSELF 628. 		case POLY_TRAP: 629. 		    if(!resist(mtmp, WAND_SYM, 0, NOTELL)) 630. 			(void) newcham(mtmp, (struct permonst *)0); 631. 		    break; 632. #endif 633. 		case RUST_TRAP: 634. 			if(in_sight) 635. 				pline("A gush of water hits %s!", mon_nam(mtmp)); 636. #ifdef GOLEMS 637. 			if (mtmp->data == &mons[PM_IRON_GOLEM]) { 638. 				if (in_sight) pline("%s falls to pieces!",  639.  								Monnam(mtmp)); 640. 				else if(mtmp->mtame) 641. 				     pline("May %s rust in peace.",  642.  								mon_nam(mtmp)); 643. 				mondied(mtmp); 644. 				trapkilled = TRUE; 645. 			}  646.  #endif /* GOLEMS */ 647. 			break; 648. 		case PIT: 649. 		case SPIKED_PIT: 650. 			/* there should be a mtmp/data -> floating */ 651. 			if(!is_flyer(mtmp->data) /* ab */  652.  			   && mtmp->data != &mons[PM_WUMPUS] /* 3. */) { 653. 				if (!passes_walls(mtmp->data)) 654. 				  mtmp->mtrapped = 1; 655. 				if(in_sight) 656. 				  pline("%s falls into a pit!", Monnam(mtmp)); 657. 				if(thitm(0, mtmp, (struct obj *)0, 658. 				  rnd((tt==PIT) ? 6 : 10))) 659. 				  trapkilled = TRUE; 660. 			}  661.  			break; 662. 		case SLP_GAS_TRAP: 663. 			if(!resists_sleep(mtmp->data) &&  664.  			   !mtmp->msleep && !mtmp->mfroz) { 665. 				mtmp->msleep = 1; 666. 				if(in_sight) 667. 				  pline("%s suddenly falls asleep!",  668.  					Monnam(mtmp)); 669. 			}  670.  			break; 671. 		case TELEP_TRAP: 672. #ifdef WALKIES 673. 			if(teleport_pet(mtmp)) { 674. #endif 675. 			    rloc(mtmp); 676. 			    if(in_sight && !cansee(mtmp->mx,mtmp->my)) 677. 				pline("%s suddenly disappears!",  678.  					Monnam(mtmp)); 679. #ifdef WALKIES 680. 			}  681.  #endif 682. 			break; 683. 		case ARROW_TRAP: 684. 			otmp = mksobj(ARROW, FALSE); 685. 			otmp->quan = 1; 686. 			otmp->owt = weight(otmp); 687. 			if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE; 688. 			break; 689. 		case DART_TRAP: 690. 			otmp = mksobj(DART, FALSE); 691. 			otmp->quan = 1; 692. 			otmp->owt = weight(otmp); 693. 			if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE; 694. 			break; 695. 		case TRAPDOOR: 696. 			if(is_maze_lev  697.  #ifdef STRONGHOLD  698.  			   && (dlevel > stronghold_level && dlevel < MAXLEVEL)  699.  #endif  700.  			  ) { 701. 				otmp = mksobj(ROCK, FALSE); 702. 				otmp->quan = 1; 703. 				otmp->owt = weight(otmp); 704. 				if(thitm(0, mtmp, otmp, d(2, 10))) 705. 					trapkilled = TRUE; 706. 				break; 707. 			}  708.  			tdoor = TRUE; 709. 			/* Fall through */ 710. 		case LEVEL_TELEP: 711. 			if(!is_flyer(mtmp->data)  712.  #ifdef WORM  713.  				&& !mtmp->wormno  714.  			    /* long worms cannot be allowed to change levels */  715.  #endif  716.  			    ){ 717. #ifdef WALKIES 718. 			    if(teleport_pet(mtmp)) { 719. #endif 720. 				if(tdoor) 721. 				    fall_down(mtmp, dlevel+1); 722. 				else { 723. 				    newlev = rnd(3); 724. 				    if(!rn2(2)) newlev = -(newlev); 725. 				    newlev = dlevel + newlev; 726. 				    if(newlev > MAXLEVEL) { 727. 					if(dlevel != MAXLEVEL) 728. 					    newlev = MAXLEVEL; 729. 					else newlev = MAXLEVEL - rnd(3); 730. 				    }  731.  				    if(newlev < 1) { 732. 					if(dlevel != 1) newlev = 1; 733. 					else newlev = 1 + rnd(3); 734. 				    }  735.  				    fall_down(mtmp, newlev); 736. 				}  737.  				if(in_sight) 738. 		pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp)); 739. 				return(2);	/* no longer on this level */ 740. #ifdef WALKIES 741. 			    }  742.  #endif 743. 			}  744.  			break; 745. 		case MONST_TRAP: 746. 		case STATUE_TRAP: 747. 			break; 748. 		case MGTRP: 749. 			/* A magic trap. Monsters immune. */ 750.  			break; 751. 		case SQBRD: { 752. 			register struct monst *ztmp = fmon; 753.  754.  			if(is_flyer(mtmp->data)) break; 755. 			/* Stepped on a squeaky board. */ 756.  			if (in_sight) 757. 			   pline("%s steps on a squeaky board.", Monnam(mtmp)); 758. 			else 759. 			   You("hear a distant squeak."); 760. 			/* Wake up nearby monsters. */ 761.  		       while(ztmp) { 762. 			 if(dist2(mtmp->mx,mtmp->my,ztmp->mx,ztmp->my) < 40) 763. 			       if(ztmp->msleep) ztmp->msleep = 0; 764. 			 ztmp = ztmp->nmon; 765. 		       }  766.  			break; 767. 		}  768.  	       case WEB: 769. 		       /* Monster in a web. */ 770.  			/* in_sight check and confused bear by Eric Backus */ 771. 		       if(mtmp->data->mlet != S_SPIDER) { 772. 			 if(in_sight) 773. 				pline("%s is caught in a web!", Monnam(mtmp)); 774. 			  else 775. 			    if(mtmp->data == &mons[PM_OWLBEAR]) 776. 			      You("hear the roaring of a confused bear!"); 777. 			 mtmp->mtrapped = 1; 778. 		       }  779.  		      break; 780. #ifdef SPELLS 781. 		case ANTI_MAGIC:	break; 782. #endif 783. 		case LANDMINE: { 784. 			register struct monst *mntmp = fmon; 785.  786.  			if(rn2(3)) 787. 				break; /* monsters usually don't set it off */ 788. 			if(in_sight) 789. 				pline("KAABLAMM!!!  %s steps on a land mine!",  790.  				      Monnam(mtmp)); 791. 			else if (flags.soundok) 792. 				pline("Kaablamm!  You hear an explosion in the distance!"); 793. 			deltrap(t_at(mtmp->mx, mtmp->my)); 794. 			if(thitm(0, mtmp, (struct obj *)0, rnd(16))) 795. 				trapkilled = TRUE; 796. 			/* wake everything on the level */ 797. 			while(mntmp) { 798. 				if(mntmp->msleep) 799. 					mntmp->msleep = 0; 800. 				mntmp = mntmp->nmon; 801. 			}  802.  			break; 803. 		}  804.  		default: 805. 			impossible("Some monster encountered a strange trap of type %d.",tt); 806. 	    }  807.  	}  808.  	if(trapkilled) return 2; 809. 	else return mtmp->mtrapped; 810. }  811.   812.  void 813. selftouch(arg) 814. char *arg; 815. {  816.  	if(uwep && (uwep->otyp == CORPSE && uwep->corpsenm == PM_COCKATRICE)  817.  #ifdef POLYSELF  818.  			&& !resists_ston(uasmon)  819.  #endif  820.  	){ 821. 		pline("%s touch the cockatrice corpse.", arg); 822. 		You("turn to stone..."); 823. 		killer = "cockatrice corpse accident"; 824. 		done("stoned"); 825. 	}  826.  }  827.   828.  void 829. float_up { 830. 	if(u.utrap) { 831. 		if(u.utraptype == TT_PIT) { 832. 			u.utrap = 0; 833. 			You("float up, out of the pit!"); 834. 		} else { 835. 			You("float up, only your %s is still stuck.",  836.  				body_part(LEG)); 837. 		}  838.  	} else 839. 		if (Hallucination) 840. 			pline("Oh wow!  You're floating in the air!"); 841. 		else 842. 			You("start to float in the air!"); 843. }  844.   845.  int 846. float_down { 847. 	register struct trap *trap; 848.  849.  	if(Levitation) return(0); /* maybe another ring/potion/boots */ 850.  851.  	/* check for falling into pool - added by GAN 10/20/86 */ 852. 	if(is_pool(u.ux,u.uy) && !(Wwalking 853. #ifdef POLYSELF 854. 				    || is_flyer(uasmon) 855. #endif 856. 				    ))  857.  		drown; 858.  859.  	You("float gently to the ground."); 860. 	if(trap = t_at(u.ux,u.uy)) 861. 		switch(trap->ttyp) { 862. 		case MONST_TRAP: 863. 		case STATUE_TRAP: 864. 			break; 865. 		case TRAPDOOR: 866. 			if(is_maze_lev  867.  #ifdef STRONGHOLD  868.  			   && (dlevel >= stronghold_level || dlevel < MAXLEVEL)  869.  #endif  870.  			   || u.ustuck) break; 871. 			/* fall into next case */ 872. 		default: 873. 			dotrap(trap); 874. 	}  875.  	if(!flags.nopick && (levl[u.ux][u.uy].omask || levl[u.ux][u.uy].gmask)) 876. 	    pickup(1); 877. 	return 0; 878. }  879.   880.   881.  void 882. tele { 883. 	coord cc; 884. 	register int nux,nuy; 885.  886.  #ifdef STRONGHOLD 887. 	/* Disable teleportation in stronghold && Vlad's Tower */ 888. 	if(dlevel == stronghold_level ||  889.  # ifdef ENDGAME  890.  	   dlevel == ENDLEVEL ||  891.  # endif  892.  	   (dlevel >= tower_level && dlevel <= tower_level + 2)) { 893. # ifdef WIZARD 894. 		if (!wizard) { 895. # endif 896. 		    pline("A mysterious force prevents you from teleporting!"); 897. 		    return; 898. # ifdef WIZARD 899. 		}  900.  # endif 901. 	}  902.  #endif /* STRONGHOLD /**/ 903. 	if((u.uhave_amulet || dlevel == wiz_level) && !rn2(3)) { 904. 	    You("feel disoriented for a moment."); 905. 	    return; 906. 	}  907.  	if(Teleport_control) { 908. 	    if (unconscious) 909. 		pline("Being unconscious, you cannot control your teleport."); 910. 	    else { 911. 		    pline("To what position do you want to be teleported?"); 912. 		    getpos(&cc, 1, "the desired position"); /* 1: force valid */ 913. 		    /* possible extensions: introduce a small error if  914. magic power is low; allow transfer to solid rock */ 915. 		    if(teleok(cc.x, cc.y)){ 916. 			teleds(cc.x, cc.y); 917. 			return; 918. 		    }  919.  		    pline("Sorry..."); 920. 		}  921.  	}  922.  	do { 923. 		nux = rnd(COLNO-1); 924. 		nuy = rn2(ROWNO); 925. 	} while(!teleok(nux, nuy)); 926. 	teleds(nux, nuy); 927. }  928.   929.  void 930. teleds(nux, nuy) 931. register int nux,nuy; 932. {  933.  	if(Punished) unplacebc; 934. 	unsee; 935. 	u.utrap = 0; 936. 	u.ustuck = 0; 937. 	u.ux = nux; 938. 	u.uy = nuy; 939. #ifdef POLYSELF 940. 	if (hides_under(uasmon)) 941. 		u.uundetected = (levl[nux][nuy].omask || levl[nux][nuy].gmask); 942. 	else 943. 		u.uundetected = 0; 944. 	if (u.usym == S_MIMIC_DEF) u.usym = S_MIMIC; 945. #endif 946. 	setsee; 947. 	if(Punished) placebc(1); 948. 	if(u.uswallow){ 949. 		u.uswldtim = u.uswallow = 0; 950. 		docrt; 951. 	}  952.  	nomul(0); 953. 	spoteffects; 954. }  955.   956.  int 957. dotele 958. {  959.  	struct trap *trap; 960. #ifdef SPELLS 961. 	boolean castit = FALSE; 962. 	register int sp_no; 963. #endif 964.  965.  	trap = t_at(u.ux, u.uy); 966. 	if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP || trap->once)) 967. 		trap = 0; 968.  969.  	if (trap) 970. 		You("jump onto the teleportation trap..."); 971. 	else if(!Teleportation ||  972.  	   (u.ulevel < (pl_character[0] == 'W' ? 8 : 12) 973. #ifdef POLYSELF 974. 	    && !can_teleport(uasmon) 975. #endif 976. 	   )  977.  	  ) {  978.  #ifdef SPELLS 979. 		/* Try to use teleport away spell. */ 980.  		castit = objects[SPE_TELEPORT_AWAY].oc_name_known; 981. 		if (castit) { 982. 		    for (sp_no = 0; sp_no < MAXSPELL &&  983.  				spl_book[sp_no].sp_id != NO_SPELL &&  984.  				spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY; sp_no++); 985.  986.  		    if (sp_no == MAXSPELL ||  987.  			spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY) 988. 			    castit = FALSE; 989. 		}  990.  #endif 991. #ifdef WIZARD 992. 		if (!wizard) { 993. #endif 994. #ifdef SPELLS 995. 		    if (!castit) { 996. 			if (!Teleportation) 997. 			    You("don't know that spell."); 998. 			else 999. #endif 1000. 			   You("are not able to teleport at will."); 1001. 			return(0); 1002. #ifdef SPELLS 1003. 		   }  1004. #endif 1005. #ifdef WIZARD 1006. 		} 1007. #endif 1008. 	} 1009.  1010. 	if(!trap && (u.uhunger <= 100 || ACURR(A_STR) < 6)) { 1011. 		You("lack the strength for a teleport spell."); 1012. #ifdef WIZARD 1013. 		if(!wizard) 1014. #endif 1015. 		return(1); 1016. 	} 1017.  1018. #ifdef SPELLS 1019. 	if (castit) 1020. # ifdef WIZARD 1021. 		if (!spelleffects(++sp_no, TRUE) && !wizard) return(0); 1022. # else 1023. 		return spelleffects(++sp_no, TRUE); 1024. # endif 1025. #endif 1026. 1027. #ifdef WALKIES 1028. 	if(next_to_u) { 1029. #endif 1030. 		tele; 1031. #ifdef WALKIES 1032. 		(void) next_to_u; 1033. 	} else { 1034. 		You("shudder for a moment."); 1035. 		return(0); 1036. 	} 1037. #endif 1038. 	if (!trap) morehungry(100); 1039. 	return(1); 1040. } 1041.  1042. void 1043. placebc(attach) 1044. int attach; 1045. { 1046. 	if(!uchain || !uball){ 1047. 		impossible("Where are your chain and ball??"); 1048. 		return; 1049. 	} 1050. 	uball->ox = uchain->ox = u.ux; 1051. 	uball->oy = uchain->oy = u.uy; 1052. 	levl[u.ux][u.uy].omask = 1; 1053. 	if(attach){ 1054. 		uchain->nobj = fobj; 1055. 		fobj = uchain; 1056. 		if(!carried(uball)){ 1057. 			uball->nobj = fobj; 1058. 			fobj = uball; 1059. 		} 1060. 	}  1061. }  1062.  1063. void 1064. unplacebc{ 1065. 	if(!carried(uball)){ 1066. 		freeobj(uball); 1067. 		unpobj(uball); 1068. 	} 1069. 	freeobj(uchain); 1070. 	unpobj(uchain); 1071. } 1072.  1073. void 1074. level_tele { 1075. register int newlevel; 1076. #ifdef WALKIES 1077. register boolean pet_by_u = next_to_u; 1078. #endif 1079. 1080. 	if(u.uhave_amulet  1081. #ifdef ENDGAME  1082. 		|| dlevel == ENDLEVEL  1083. #endif  1084. 	) { 1085. 	   You("feel very disoriented for a moment."); 1086. 	   return; 1087. 	} 1088. 	if(Teleport_control  1089. #ifdef WIZARD  1090. 	   || wizard  1091. #endif  1092. 		) { 1093. 	   char buf[BUFSZ]; 1094. 1095. 	    do { 1096. 	     pline("To what level do you want to teleport? [type a number] "); 1097. 	     getlin(buf); 1098. 	   } while(!digit(buf[0]) && (buf[0] != '-' || !digit(buf[1]))); 1099. 	   newlevel = atoi(buf); 1100. 	} else { 1101. 	   newlevel = rn2(5) | !Fire_resistance ? rnd(dlevel + 3) : 1102. #ifdef STRONGHOLD 1103. 		stronghold_level + 1; 1104. #else 1105. 		HELLLEVEL; 1106. #endif 1107. 	   if(dlevel == newlevel) 1108. 		if(is_maze_lev) newlevel--; else newlevel++; 1109. 	} 1110. 	if(newlevel < 0) { 1111. #ifdef WALKIES 1112. 	   if(pet_by_u) { 1113. #endif 1114. 		if(newlevel <= -10) { 1115. 			You("arrive in heaven."); 1116. 			pline("\"You are here a bit early, but we'll let you in.\""); 1117. 			killer = "visit to heaven"; 1118. 			done("died"); 1119. 		} else	if (newlevel == -9) { 1120. 			You("feel deliriously happy. "); 1121. 			pline("(In fact, you're on Cloud 9!) "); 1122. 			more; 1123. 		} else 1124. #ifndef STRONGHOLD 1125. 			newlevel = 0; 1126. #else 1127. 			newlevel = 1; 1128. #endif 1129. 		You("are now high above the clouds..."); 1130. 		if(Levitation) { 1131. 		   You("float gently down to earth."); 1132. #ifndef STRONGHOLD 1133. 		   done("escaped"); 1134. #endif 1135. 		} 1136. #ifdef POLYSELF 1137. 		if(is_flyer(uasmon)) { 1138. 		   You("fly down to earth."); 1139. # ifndef STRONGHOLD 1140. 		   done("escaped"); 1141. # endif 1142. 		} 1143. #endif 1144. 		pline("Unfortunately, you don't know how to fly."); 1145. 		You("plummet a few thousand feet to your death."); 1146. 		dlevel = 0; 1147. 		killer = "long fall"; 1148. 		done("died"); 1149. #ifdef WALKIES 1150. 	   } else { 1151. 		You("shudder for a moment..."); 1152. 		return; 1153. 	   }  1154. #endif 1155. 	} 1156. 	/* calls done("escaped") if newlevel==0 */ 1157. #ifdef WALKIES 1158. 	if(!pet_by_u) 1159. 	   You("shudder for a moment..."); 1160. 	else 1161. #endif 1162. 	   goto_level(newlevel, FALSE); 1163. } 1164.  1165. void 1166. domagictrap { 1167. 	register int fate = rnd(20); 1168. 1169. 	/* What happened to the poor sucker? */ 1170.  1171. 	if (fate < 10) { 1172. 1173. 	  /* Most of the time, it creates some monsters. */ 1174. 	  register int cnt = rnd(4); 1175. 1176. 	  /* below checks for blindness added by GAN 10/30/86 */ 1177. 	 if (!Blind)  { 1178. 		You("are momentarily blinded by a flash of light!"); 1179. 		make_blinded((long)rn1(5,10),FALSE); 1180. 	 }  else 1181. 		You("hear a deafening roar!"); 1182. 	 while(cnt--) 1183. 	  (void) makemon((struct permonst *) 0, u.ux, u.uy); 1184. 	} 1185. 	else 1186. 	 switch (fate) { 1187. 1188. 	     case 10: 1189. 	    case 11: 1190. 		     /* sometimes nothing happens */ 1191. 			break; 1192. 	    case 12: 1193. 		     /* a flash of fire */ 1194. 		     {  1195. 			register int num; 1196. 1197. 			/* changed to be in conformance with 1198. 			 * SCR_FIRE by GAN 11/02/86 1199. 			 */ 1200.  1201. 			pline("A tower of flame bursts from the floor!"); 1202. 			if(Fire_resistance) { 1203. 				shieldeff(u.ux, u.uy); 1204. 				You("are uninjured."); 1205. 				break; 1206. 			} else { 1207. 				num = rnd(6); 1208. 				u.uhpmax -= num; 1209. 				losehp(num,"a burst of flame"); 1210. 				break; 1211. 			} 1212. 		      }  1213.  1214. 	     /* odd feelings */ 1215. 	    case 13:   pline("A shiver runs up and down your spine!"); 1216. 			break; 1217. 	    case 14:   You("hear distant howling."); 1218. 			break; 1219. 	    case 15:   You("suddenly yearn for your distant homeland."); 1220. 			break; 1221. 	    case 16:   Your("pack shakes violently!"); 1222. 			break; 1223. 	    case 17:	You("smell charred flesh."); 1224. 			break; 1225. 1226. 	     /* very occasionally something nice happens. */ 1227.  1228. 	     case 19: 1229. 		   /* tame nearby monsters */ 1230. 		  {   register int i,j; 1231. 		      register boolean confused = (Confusion != 0); 1232. 		      register int bd = confused ? 5 : 1; 1233.  1234. 		       /* below pline added by GAN 10/30/86 */ 1235. 		      adjattrib(A_CHA,1,FALSE); 1236. 		      for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) 1237. 		      if(levl[u.ux+i][u.uy+j].mmask) 1238. 			  (void) tamedog(m_at(u.ux+i, u.uy+j), (struct obj *)0); 1239. 		      break; 1240. 		  }  1241.  1242. 	     case 20: 1243. 		   /* uncurse stuff */ 1244. 		  {  register struct obj *obj; 1245. 		     register boolean confused = (Confusion != 0); 1246. 1247. 			/* below plines added by GAN 10/30/86 */ 1248. 			if (confused) 1249. 			   if (Hallucination) 1250. 				You("feel the power of the Force against you!"); 1251. 			   else 1252. 				You("feel like you need some help."); 1253. 			else 1254. 			   if (Hallucination) 1255. 				You("feel in touch with the Universal Oneness."); 1256. 			   else 1257. 				You("feel like someone is helping you."); 1258. 		      for(obj = invent; obj ; obj = obj->nobj) 1259. 			      if(obj->owornmask) 1260. 				   if(confused) 1261. 					curse(obj); 1262. 				   else 1263. 					obj->cursed = 0; 1264. 		      if(Punished && !confused) 1265. 			   unpunish; 1266. 		      break; 1267. 		  }  1268. 	     default: break; 1269. 	 }  1270. }  1271.  1272. void 1273. drown { 1274. 	register struct obj *obj; 1275. 1276. 	/* Scrolls and potions get affected by the water */ 1277. 	for(obj = invent; obj; obj = obj->nobj) { 1278. 		if(obj->olet == SCROLL_SYM && rn2(12) > u.uluck) 1279. 			obj->otyp = SCR_BLANK_PAPER; 1280. 		if(obj->olet == POTION_SYM && rn2(12) > u.uluck) { 1281. 			if (obj->spe == -1) { 1282. 				obj->otyp = POT_WATER; 1283. 				obj->blessed = obj->cursed = 0; 1284. 				obj->spe = 0; 1285. 			} else obj->spe--; 1286. 		} 1287. 	}  1288.  1289. #ifdef POLYSELF 1290. 	if(u.usym == S_GREMLIN && rn2(3)) { 1291. 		struct monst *mtmp; 1292. 		if(mtmp = cloneu) { 1293. 			mtmp->mhpmax = (u.mhmax /= 2); 1294. 			You("multiply."); 1295. 		} 1296. 	}  1297.  1298. 	if(is_swimmer(uasmon)) return; 1299. #endif 1300. 1301. 	You("fell into %s!",  1302. 	      levl[u.ux][u.uy].typ == POOL ? "a pool" : "the moat"); 1303. 	You("can't swim!"); 1304. 	if( 1305. #ifdef WIZARD  1306. 	wizard ||  1307. #endif  1308. 	rn2(3) < u.uluck+2) { 1309. 		You("attempt a teleport spell.");	/* utcsri!carroll */ 1310. 		(void) dotele; 1311. 		if(!is_pool(u.ux,u.uy)) return; 1312. 	} 1313. 	You("drown."); 1314. 	killer = levl[u.ux][u.uy].typ == POOL ? "pool of water" : "moat"; 1315. 	done("drowned"); 1316. } 1317.  1318. #ifdef SPELLS 1319. void 1320. drain_en(n) 1321. register int n; 1322. { 1323. 	if (!u.uenmax) return; 1324. 	You("feel your magical energy drain away!"); 1325. 	u.uen -= n; 1326. if(u.uen < 0) { 1327. 		u.uenmax += u.uen; 1328. 		if(u.uenmax < 0) u.uenmax = 0; 1329. 		u.uen = 0; 1330. 	} 1331. 	flags.botl = 1; 1332. } 1333. #endif 1334. 1335. int 1336. dountrap {	/* disarm a trapped object */ 1337. 	register struct obj *otmp; 1338. 	register boolean confused = (Confusion > 0); 1339. 	register int x,y; 1340. 	int ch; 1341. 	struct trap *ttmp; 1342. 1343. #ifdef POLYSELF 1344. 	if(nohands(uasmon)) { 1345. 	   pline("And just how do you expect to do that?"); 1346. 	   return(0); 1347. 	} 1348. #endif 1349. 	if(!getdir(TRUE)) return(0); 1350. 	x = u.ux + u.dx; 1351. 	y = u.uy + u.dy; 1352. 1353. 	if(!u.dx && !u.dy) { 1354. 	   if(levl[x][y].omask) 1355. 		for(otmp = fobj; otmp; otmp = otmp->nobj) 1356. 		   if((otmp->ox == x) && (otmp->oy == y)) 1357. 			if(Is_box(otmp)) { 1358. 			   pline("There is %s here, check for traps? ",  1359. 				  doname(otmp)); 1360. 1361. 			    switch (ynq) { 1362. 				case 'q': return(0); 1363. 				case 'n': continue; 1364. 			   }  1365.  1366. 			    if((otmp->otrapped && !confused && rn2(44-dlevel*2) < 10)  1367. 			       || confused && !rn2(3)) { 1368. 				You("find a trap on the %s! Disarm it? ",  1369. 				       xname(otmp)); 1370. 1371. 				switch (ynq) { 1372. 				   case 'q': return(1); 1373. 				   case 'n': continue; 1374. 				} 1375.  1376. 				if(otmp->otrapped) { 1377. 				   ch = 15 + 1378. 					 (pl_character[0] == 'R') ? u.ulevel*3 : 1379. 					 u.ulevel; 1380. 				   if(confused || Fumbling || rnd(75+dlevel/2) > ch) { 1381. 					You("set it off!"); 1382. 					chest_trap(otmp, FINGER); 1383. 				   } else { 1384. 					You("disarm it!"); 1385. 					otmp->otrapped = 0; 1386. 				   }  1387. 				} else pline("That %s was not trapped.",  1388. 					     doname(otmp)); 1389. 				return(1); 1390. 			   } else { 1391. 				You("find no traps on the %s.", 1392. 				    xname(otmp)); 1393. 				return(1); 1394. 			   }  1395. 			}  1396. 	    if ((ttmp = t_at(x,y)) && ttmp->tseen) 1397. 		You("cannot disable this trap."); 1398. 	   else 1399. 		You("know of no traps here."); 1400. 	   return(0); 1401. 	} 1402.  1403. 	if (!IS_DOOR(levl[x][y].typ)) { 1404. 	   if ((ttmp = t_at(x,y)) && ttmp->tseen) 1405. 		You("cannot disable that trap."); 1406. 	   else 1407. 		You("know of no traps there."); 1408. 	   return(0); 1409. 	} 1410.  1411. 	switch (levl[x][y].doormask) { 1412. 	   case D_NODOOR: 1413. 		You("%s no door there.", Blind ? "feel" : "see"); 1414. 		return(0); 1415. 	   case D_ISOPEN: 1416. 		pline("This door is safely open."); 1417. 		return(0); 1418. 	   case D_BROKEN: 1419. 		pline("This door is broken."); 1420. 		return(0); 1421. 	} 1422.  1423. 	if ((levl[x][y].doormask & D_TRAPPED && !confused && 1424. 	    rn2(44-dlevel*2) < 10)  1425. 	    || confused && !rn2(3)) { 1426. 		You("find a trap on the door! Disarm it? "); 1427. 		if (ynq != 'y') return(1); 1428. 		if (levl[x][y].doormask & D_TRAPPED) { 1429. 		   ch = 15 + 1430. 			 (pl_character[0] == 'R') ? u.ulevel*3 : 1431. 			 u.ulevel; 1432. 		   if(confused || Fumbling || rnd(75+dlevel/2) > ch) { 1433. 			   You("set it off!"); 1434. 			   b_trapped("door"); 1435. 		   } else { 1436. 			   You("disarm it!"); 1437. 			   levl[x][y].doormask &= ~D_TRAPPED; 1438. 		   }  1439. 		} else pline("This door was not trapped."); 1440. 		return(1); 1441. 	} else { 1442. 		You("find no traps on the door."); 1443. 		return(1); 1444. 	} 1445. }  1446.  1447. /* this is only called when the player is doing something to the chest 1448. * -- i.e., the player and the chest are in the same position */ 1449. void 1450. chest_trap(obj, bodypart) 1451. register struct obj *obj; 1452. register int bodypart; 1453. { 1454. 	register struct obj *otmp,*otmp2; 1455. 	char	buf[80]; 1456. 1457. 	if(rn2(13+u.uluck) > 7) return; 1458. 1459. 	otmp = obj; 1460. 	switch(rn2(13-u.uluck)) {	/* which trap? */ 1461. 		case 23: 1462. 		case 22: 1463. 		case 21: 1464. 			pline("The %s explodes!", xname(obj)); 1465. 			Sprintf(buf, "exploding %s", xname(obj)); 1466. 1467. 			delete_contents(obj); 1468. 			for(otmp = fobj; otmp; otmp = otmp2) { 1469. 			   otmp2 = otmp->nobj; 1470. 			   if((otmp->ox == u.ux) && (otmp->oy == u.uy)) 1471. 				delobj(otmp); 1472. 			} 1473.  1474. 			losehp(d(6,6), buf); 1475. 			wake_nearby; 1476. 			return; 1477. 		case 20: 1478. 		case 19: 1479. 		case 18: 1480. 		case 17: 1481. 			pline("A cloud of noxious gas billows from the %s.", 1482. 			      xname(obj)); 1483. 			poisoned("gas cloud", A_STR, "cloud of poison gas"); 1484. 			break; 1485. 		case 16: 1486. 		case 15: 1487. 		case 14: 1488. 		case 13: 1489. 			pline("A tower of flame erupts from the %s", 1490. 			      xname(obj)); 1491. 			if(Fire_resistance) { 1492. 			   shieldeff(u.ux, u.uy); 1493. 			   You("don't seem to be affected."); 1494. 			} else	losehp(d(4, 6), "tower of flame"); 1495. 			destroy_item(SCROLL_SYM, AD_FIRE); 1496. #ifdef SPELLS 1497. 			destroy_item(SPBOOK_SYM, AD_FIRE); 1498. #endif 1499. 			destroy_item(POTION_SYM, AD_FIRE); 1500. 			break; 1501. 		case 12: 1502. 		case 10: 1503. 		case 9: 1504. 			You("are jolted by a surge of electricity!"); 1505. 			if(Shock_resistance) { 1506. 			   shieldeff(u.ux, u.uy); 1507. 			   You("don't seem to be affected."); 1508. 			} else	losehp(d(4, 4), "electric shock"); 1509. 			destroy_item(RING_SYM, AD_ELEC); 1510. 			destroy_item(WAND_SYM, AD_ELEC); 1511. 			break; 1512. 		case 8: 1513. 		case 7: 1514. 		case 6: 1515. 			pline("Suddenly you are frozen in place!"); 1516. 			nomovemsg = "You can move again."; 1517. 			multi = -d(5, 6); 1518. 			break; 1519. 		case 5: 1520. 		case 4: 1521. 		case 3: 1522. 			pline("A cloud of %s gas billows from the %s", 1523. 			      hcolor, xname(obj)); 1524. 			if(!Stunned) 1525. 			   if (Hallucination) 1526. 				pline("What a groovy feeling!"); 1527. 			   else 1528. 				You("stagger and your vision blurs..."); 1529. 			make_stunned(HStun + rn1(7, 16),FALSE); 1530. 			make_hallucinated(Hallucination + rn1(5, 16),FALSE); 1531. 			break; 1532. 		default: 1533. 			You("feel a needle prick your %s.",body_part(bodypart)); 1534. 			poisoned("needle", A_CON, "a poisoned needle"); 1535. 			break; 1536. 	} 1537. 	otmp->otrapped = 0;		/* these traps are one-shot things */ 1538. } 1539.  1540. void 1541. wake_nearby {			/* Wake up nearby monsters. */ 1542. 	register struct monst *mtmp; 1543. 1544. 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1545. 	   if(dist(mtmp->mx,mtmp->my) < u.ulevel*20) { 1546. 		if(mtmp->msleep) mtmp->msleep = 0; 1547. 		if(mtmp->mtame)  EDOG(mtmp)->whistletime = moves; 1548. 	   }  1549. 	}  1550. }  1551.  1552. struct trap * 1553. t_at(x,y) 1554. register int x, y; 1555. { 1556. 	register struct trap *trap = ftrap; 1557. 	while(trap) { 1558. 		if(trap->tx == x && trap->ty == y) return(trap); 1559. 		trap = trap->ntrap; 1560. 	} 1561. 	return((struct trap *)0); 1562. } 1563.  1564. void 1565. deltrap(trap) 1566. register struct trap *trap; 1567. { 1568. 	register struct trap *ttmp; 1569. 1570. 	if(trap == ftrap) 1571. 		ftrap = ftrap->ntrap; 1572. 	else { 1573. 		for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ; 1574. 		ttmp->ntrap = trap->ntrap; 1575. 	} 1576. 	free((genericptr_t) trap); 1577. } 1578.  1579. void 1580. b_trapped(item)		/* used for doors. can be used */ 1581. register char *item;   /* for anything else that opens */ 1582. { 1583. 	register int dmg = rn2(15) + rnd((int)u.ulevel); 1584. 1585. 	pline("KABOOM!!  The %s was booby-trapped!", item); 1586. 	make_stunned(HStun + dmg, TRUE); 1587. 	losehp(dmg, "explosion"); 1588. } 1589.  1590. /* Monster is hit by trap. */ 1591. /* Note: doesn't work if both obj and d_override are null */ 1592. static boolean 1593. thitm(tlev, mon, obj, d_override) 1594. register int tlev; 1595. register struct monst *mon; 1596. register struct obj *obj; 1597. int d_override; 1598. { 1599. 	register int strike; 1600. 	register boolean trapkilled = FALSE; 1601. 1602. 	if (d_override) strike = 1; 1603. 	else if (obj) strike = (mon->data->ac + tlev + obj->spe <= rnd(20)); 1604. 	else strike = (mon->data->ac + tlev <= rnd(20)); 1605. 1606. 	/* Actually more accurate than thitu, which doesn't take 1607. 	 * obj->spe into account. 1608. 	 */ 1609. 	if(!strike) { 1610. 		if (cansee(mon->mx, mon->my)) 1611. 			pline("%s is almost hit by %s!", Monnam(mon), 1612. 								doname(obj)); 1613. 	} else { 1614. 		int dam = 1; 1615. 1616. 		if (obj && cansee(mon->mx, mon->my)) 1617. 			pline("%s is hit by %s!", Monnam(mon), doname(obj)); 1618. 		if (d_override) dam = d_override; 1619. 		else if (obj) { 1620. 			dam = dmgval(obj, mon->data); 1621. 			if (dam < 1) dam = 1; 1622. 		} 1623. 		if ((mon->mhp -= dam) <= 0) { 1624. 			if (cansee(mon->mx, mon->my)) 1625. 				pline("%s is killed!", Monnam(mon)); 1626. 			else if (mon->mtame) 1627. 	You("have a sad feeling for a moment, then it passes."); 1628. 			mondied(mon); 1629. 			trapkilled = TRUE; 1630. 		} 1631. 	}  1632. 	if (obj && (!strike || d_override)) { 1633. 		obj->ox = mon->mx; 1634. 		obj->oy = mon->my; 1635. 		obj->nobj = fobj; 1636. 		fobj = obj; 1637. 		stackobj(fobj); 1638. 		levl[obj->ox][obj->oy].omask = 1; 1639. 	} else if (obj) free ((genericptr_t)obj); 1640. 1641. 	return trapkilled; 1642. } 1643.  1644. boolean 1645. unconscious 1646. { 1647. 	return (multi < 0 && (!nomovemsg || 1648. 	     !strncmp(nomovemsg,"You wake", 8) || 1649. 	     !strncmp(nomovemsg,"You awake", 9) || 1650. 	     !strncmp(nomovemsg,"You regain con", 15) || 1651. 	     !strncmp(nomovemsg,"You are consci", 15))); 1652. }