Source:NetHack 3.1.0/trap.c

From NetHackWiki
Revision as of 07:41, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.1.0/trap.c moved to Source:NetHack 3.1.0/trap.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

1.    /*	SCCS Id: @(#)trap.c	3.1	92/12/10	*/
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.    #ifdef OVLB
8.    const char *traps[TRAPNUM] = {
9.    	"",
10.   	"n arrow trap",
11.   	" dart trap",
12.   	" falling rock trap",
13.   	" squeaky board",
14.   	" bear trap",
15.   	" land mine",
16.   	" sleeping gas trap",
17.   	" rust trap",
18.   	" fire trap",
19.   	" pit",
20.   	" spiked pit",
21.   	" trapdoor",
22.   	" teleportation trap",
23.   	" level teleporter",
24.   	" magic portal",
25.   	" web",
26.   	" statue trap",
27.   	" magic trap",
28.   	"n anti-magic field"
29.   #ifdef POLYSELF
30.   	," polymorph trap"
31.   #endif
32.   };
33.   
34.   #endif /* OVLB */
35.   
36.   static void FDECL(domagicportal,(struct trap *));
37.   static void NDECL(dofiretrap);
38.   static void NDECL(domagictrap);
39.   static boolean FDECL(emergency_disrobe,(boolean *));
40.   STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int));
41.   
42.   #ifdef OVLB
43.   
44.   static int FDECL(teleok, (int,int,BOOLEAN_P));
45.   static void NDECL(vtele);
46.   static void FDECL(no_fall_through, (BOOLEAN_P));
47.   
48.   /* Generic rust-armor function.  Returns TRUE if a message was printed;
49.    * "print", if set, means to print a message (and thus to return TRUE) even
50.    * if the item could not be rusted; otherwise a message is printed and TRUE is
51.    * returned only for rustable items.
52.    */
53.   boolean
54.   rust_dmg(otmp, ostr, type, print)
55.   register struct obj *otmp;
56.   register const char *ostr;
57.   int type;
58.   boolean print;
59.   {
60.   	static const char NEARDATA *action[] = { "smoulder", "rust", "rot", "corrode" };
61.   	static const char NEARDATA *msg[] =  { "burnt", "rusted", "rotten", "corroded" };
62.   	boolean vulnerable = FALSE;
63.   	boolean plural;
64.   	boolean grprot = FALSE;
65.   
66.   	if (!otmp) return(FALSE);
67.   	switch(type) {
68.   		case 0:
69.   		case 2: vulnerable = is_flammable(otmp); break;
70.   		case 1: vulnerable = is_rustprone(otmp); grprot = TRUE; break;
71.   		case 3: vulnerable = is_corrodeable(otmp); grprot = TRUE; break;
72.   	}
73.   
74.   	if (!print && (!vulnerable || otmp->oerodeproof || otmp->oeroded == MAX_ERODE))
75.   		return FALSE;
76.   
77.   	plural = is_gloves(otmp) || is_boots(otmp);
78.   
79.   	if (!vulnerable)
80.   		if (flags.verbose)
81.   		    Your("%s %s not affected.", ostr, plural ? "are" : "is");
82.   	else if (otmp->oeroded < MAX_ERODE) {
83.   		if (grprot && otmp->greased)
84.   			grease_protect(otmp,ostr,plural);
85.   		else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
86.   			if (flags.verbose)
87.   				pline("Somehow, your %s %s not affected.",
88.   					ostr, plural ? "are" : "is");
89.   		} else {
90.   			Your("%s %s%s%s!", ostr, action[type],
91.   				plural ? "" : "s",
92.   			        otmp->oeroded+1 == MAX_ERODE ? " completely" :
93.   				otmp->oeroded ? " further" : "");
94.   			otmp->oeroded++;
95.   		}
96.   	} else
97.   		if (flags.verbose)
98.   			Your("%s %s%s completely %s.", ostr,
99.   			     Blind ? "feel" : "look",
100.  			     plural ? "" : "s", msg[type]);
101.  	return(TRUE);
102.  }
103.  
104.  void
105.  grease_protect(otmp,ostr,plu)
106.  register struct obj *otmp;
107.  register const char *ostr;
108.  register boolean plu;
109.  {
110.  	static const char txt[] = "protected by the layer of grease!";
111.  
112.  	if (ostr)
113.  		Your("%s %s %s",ostr,plu ? "are" : "is",txt);
114.  	else
115.  		Your("%s %s",aobjnam(otmp,"are"),txt);
116.  	if (!rn2(2)) {
117.  		pline("The grease dissolves.");
118.  		otmp->greased = 0;
119.  	}
120.  }
121.  
122.  struct trap *
123.  maketrap(x,y,typ)
124.  register int x, y, typ;
125.  {
126.  	register struct trap *ttmp;
127.  	register boolean oldplace;
128.  
129.  	if (ttmp = t_at(x,y)) {
130.  	    oldplace = TRUE;
131.  	    if (u.utrap && (x == u.ux) && (y == u.uy) && 
132.  	      ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP) ||
133.  	      (u.utraptype == TT_WEB && typ != WEB) ||
134.  	      (u.utraptype == TT_PIT && typ != PIT && typ != SPIKED_PIT)))
135.  		    u.utrap = 0;
136.  	} else {
137.  	    oldplace = FALSE;
138.  	    ttmp = newtrap();
139.  	    ttmp->tx = x;
140.  	    ttmp->ty = y;
141.  	}
142.  	ttmp->ttyp = typ;
143.  	switch(typ) {
144.  	    case STATUE_TRAP:	    /* create a "living" statue */
145.  		(void) mkcorpstat(STATUE, &mons[rndmonnum()], x, y, FALSE);
146.  		break;
147.  	    case PIT:
148.  	    case SPIKED_PIT:
149.  	    case TRAPDOOR:
150.  		levl[x][y].doormask = 0;   /* subsumes altarmask, icedpool... */
151.  		if (IS_ROOM(levl[x][y].typ))
152.  			levl[x][y].typ = ROOM;
153.  		break;
154.  	}
155.  	ttmp->tseen = 0;
156.  	ttmp->once = 0;
157.  	ttmp->dst.dnum = -1;
158.  	ttmp->dst.dlevel = -1;
159.  	if (!oldplace) {
160.  	    ttmp->ntrap = ftrap;
161.  	    ftrap = ttmp;
162.  	}
163.  	return(ttmp);
164.  }
165.  
166.  static int
167.  teleok(x, y, trapok)
168.  register int x, y;
169.  boolean trapok;
170.  {				/* might throw him into a POOL
171.  				 * removed by GAN 10/20/86
172.  				 */
173.  #ifdef STUPID
174.  	boolean	tmp1, tmp2, tmp3, tmp4;
175.  # ifdef POLYSELF
176.  	tmp1 = isok(x,y) && (!IS_ROCK(levl[x][y].typ) ||
177.  		passes_walls(uasmon)) && !MON_AT(x, y);
178.  # else
179.  	tmp1 = isok(x,y) && !IS_ROCK(levl[x][y].typ) && !MON_AT(x, y);
180.  # endif
181.  	tmp2 = !sobj_at(BOULDER,x,y) && (trapok || !t_at(x,y));
182.  	tmp3 = !(is_pool(x,y) &&
183.  	       !(Levitation || Wwalking || Magical_breathing
184.  # ifdef POLYSELF
185.  		 || is_flyer(uasmon) || is_swimmer(uasmon)
186.  		 || is_clinger(uasmon)
187.  # endif
188.  		)) && !closed_door(x,y);
189.  	tmp4 = !is_lava(x,y);
190.  	return(tmp1 && tmp2 && tmp3 && tmp4);
191.  #else
192.  	return( isok(x,y) &&
193.  # ifdef POLYSELF
194.  		(!IS_ROCK(levl[x][y].typ) || passes_walls(uasmon)) &&
195.  # else
196.  		!IS_ROCK(levl[x][y].typ) &&
197.  # endif
198.  		!MON_AT(x, y) &&
199.  		!sobj_at(BOULDER,x,y) && (trapok || !t_at(x,y)) &&
200.  		!(is_pool(x,y) &&
201.  		!(Levitation || Wwalking || Magical_breathing
202.  # ifdef POLYSELF
203.  		  || is_flyer(uasmon) || is_swimmer(uasmon)
204.  		  || is_clinger(uasmon)
205.  # endif
206.  		  )) && !is_lava(x,y) && !closed_door(x,y));
207.  #endif
208.  	/* Note: gold is permitted (because of vaults) */
209.  }
210.  
211.  boolean
212.  safe_teleds()
213.  {
214.  	register int nux, nuy;
215.  	short tcnt = 0;
216.  
217.  	do {
218.  		nux = rnd(COLNO-1);
219.  		nuy = rn2(ROWNO);
220.  	} while (!teleok(nux, nuy, tcnt>200) && tcnt++ < 400);
221.  
222.  	if (tcnt < 400) {
223.  		teleds(nux, nuy);
224.  		return TRUE;
225.  	} else
226.  		return FALSE;
227.  }
228.  
229.  static void
230.  vtele()
231.  {
232.  	register struct mkroom *croom = search_special(VAULT);
233.  	coord c;
234.  
235.  	if(croom && somexy(croom, &c) && teleok(c.x,c.y,FALSE)) {
236.  		teleds(c.x,c.y);
237.  		return;
238.  	}
239.  	tele();
240.  }
241.  
242.  static void
243.  no_fall_through(td)
244.  boolean td;
245.  {
246.  	/* floor objects get a chance of falling down.  the case
247.  	 * where the hero does NOT fall down is treated here.  the
248.  	 * case where the hero does fall down is treated in goto_level().
249.  	 * reason: the target level of the fall is not determined here,
250.  	 * and it need not be the next level.  if we want falling
251.  	 * objects to arrive near the player, we must call impact_drop()
252.  	 * _after_ the target level is determined.
253.  	 */
254.  	impact_drop((struct obj *)0, u.ux, u.uy, 0);
255.  	if (!td) {
256.  		display_nhwindow(WIN_MESSAGE, FALSE);
257.  		pline("The opening under you closes up.");
258.  	}
259.  }
260.  
261.  void
262.  fall_through(td)
263.  boolean td;	/* td == TRUE : trapdoor */
264.  {
265.  	register int newlevel = dunlev(&u.uz);
266.  
267.  	if(Blind && Levitation) return;
268.  
269.  	do {
270.  	    newlevel++;
271.  	} while(!rn2(4) && newlevel < dunlevs_in_dungeon(&u.uz));
272.  
273.  	if(td) pline("A trap door opens up under you!");
274.  	else pline("The floor opens up under you!");
275.  
276.  	if(Levitation || u.ustuck || !Can_fall_thru(&u.uz)
277.  #ifdef POLYSELF
278.  	   || is_flyer(uasmon) || is_clinger(uasmon)
279.  #endif
280.  	   || (Inhell && !u.uevent.invoked &&
281.  					newlevel == dunlevs_in_dungeon(&u.uz))
282.  		) {
283.  		    You("don't fall in.");
284.  		    no_fall_through(td);
285.  		    return;
286.  	}
287.  #ifdef WALKIES
288.  	if(!next_to_u()) {
289.  	    You("are jerked back by your pet!");
290.  	    no_fall_through(td);
291.  	    return;
292.  	}
293.  #endif
294.  	if(*u.ushops) shopdig(1);
295.  	if(Is_stronghold(&u.uz)) goto_hell(TRUE, TRUE);
296.  	else {
297.  	    d_level	dtmp;
298.  	    dtmp.dnum = u.uz.dnum;
299.  	    dtmp.dlevel = newlevel;
300.  	    goto_level(&dtmp, FALSE, TRUE, FALSE);
301.  	    if(!td) pline("The hole in the ceiling above you closes up.");
302.  	}
303.  }
304.  
305.  void
306.  dotrap(trap)
307.  register struct trap *trap;
308.  {
309.  	register int ttype = trap->ttyp;
310.  	register struct monst *mtmp;
311.  	register struct obj *otmp;
312.  
313.  	nomul(0);
314.  	if(trap->tseen && !Fumbling &&
315.  #ifdef POLYSELF
316.  	   !((ttype == PIT || ttype == SPIKED_PIT) && !is_clinger(uasmon)) &&
317.  #else
318.  	   !(ttype == PIT || ttype == SPIKED_PIT) &&
319.  #endif
320.  	   !(ttype == MAGIC_PORTAL || ttype == ANTI_MAGIC) && !rn2(5))
321.  		You("escape a%s.", traps[ttype]);
322.  	else {
323.  	    seetrap(trap);
324.  	    switch(ttype) {
325.  		case ARROW_TRAP:
326.  		    pline("An arrow shoots out at you!");
327.  		    otmp = mksobj(ARROW, TRUE, FALSE);
328.  		    otmp->quan = 1L;
329.  		    otmp->owt = weight(otmp);
330.  		    if(thitu(8,dmgval(otmp,uasmon),otmp,"arrow"))
331.  			obfree(otmp, (struct obj *)0);
332.  		    else {
333.  			place_object(otmp, u.ux, u.uy);
334.  			otmp->nobj = fobj;
335.  			fobj = otmp;		
336.  			stackobj(otmp);
337.  			newsym(u.ux, u.uy);
338.  		    }
339.  		    break;
340.  		case DART_TRAP:
341.  		    pline("A little dart shoots out at you!");
342.  		    otmp = mksobj(DART, TRUE, FALSE);
343.  		    otmp->quan = 1L;
344.  		    otmp->owt = weight(otmp);
345.  		    if (!rn2(6)) otmp->opoisoned = 1;
346.  		    if(thitu(7,dmgval(otmp,uasmon),otmp,"little dart")) {
347.  			if (otmp->opoisoned)
348.  			    poisoned("dart",A_CON,"poison dart",10);
349.  			obfree(otmp, (struct obj *)0);
350.  		    } else {
351.  			place_object(otmp, u.ux, u.uy);
352.  			otmp->nobj = fobj;
353.  			fobj = otmp;		
354.  			stackobj(otmp);
355.  			newsym(u.ux, u.uy);
356.  		    }
357.  		    break;
358.  		case ROCKTRAP:
359.  		    {
360.  			int dmg = d(2,6); /* should be std ROCK dmg? */
361.  
362.  			otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE);
363.  			otmp->quan = 1L;
364.  			otmp->owt = weight(otmp);
365.  
366.  	pline("A trap door in the ceiling opens and a rock falls on your %s!",
367.  				body_part(HEAD));
368.  
369.  			if (uarmh)
370.  			    if(is_metallic(uarmh)) {
371.  				pline("Fortunately, you are wearing a hard helmet.");
372.  				dmg = 2;
373.  			    } else if (flags.verbose)
374.   				Your("%s does not protect you.", xname(uarmh));
375.  
376.  			stackobj(otmp);
377.  			newsym(u.ux,u.uy);	/* map the rock */
378.  
379.  			losehp(dmg, "falling rock", KILLED_BY_AN);
380.  			exercise(A_STR, FALSE);
381.  		    }
382.  		    break;
383.  
384.  		case SQKY_BOARD:	    /* stepped on a squeaky board */
385.  		    if (Levitation
386.  #ifdef POLYSELF
387.  			|| is_flyer(uasmon) || is_clinger(uasmon)
388.  #endif
389.  			) {
390.  			if (Hallucination) You("notice a crease in the linoleum.");
391.  			else You("notice a loose board below you.");
392.  		    } else {
393.  			pline("A board beneath you squeaks loudly.");
394.  			wake_nearby();
395.  		    }
396.  		    break;
397.  
398.  		case BEAR_TRAP:
399.  		    if(Levitation
400.  #ifdef POLYSELF
401.  				|| is_flyer(uasmon)) {
402.  			You("%s over a bear trap.",
403.  			      Levitation ? "float" : "fly");
404.  #else
405.  				) {
406.  			You("float over a bear trap.");
407.  #endif
408.  			break;
409.  		    }
410.  #ifdef POLYSELF
411.  		    if(amorphous(uasmon)) {
412.  			pline("A bear trap closes harmlessly through you.");
413.  			break;
414.  		    }
415.  #endif
416.  		    u.utrap = rn1(4, 4);
417.  		    u.utraptype = TT_BEARTRAP;
418.  		    pline("A bear trap closes on your %s!",
419.  			body_part(FOOT));
420.  #ifdef POLYSELF
421.  		    if(u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR)
422.  			You("howl in anger!");
423.  #endif
424.  		    exercise(A_DEX, FALSE);
425.  		    break;
426.  
427.  		case SLP_GAS_TRAP:
428.  		    if(Sleep_resistance) {
429.  			You("are enveloped in a cloud of gas!");
430.  			break;
431.  		    }
432.  		    pline("A cloud of gas puts you to sleep!");
433.  		    flags.soundok = 0;
434.  		    nomul(-rnd(25));
435.  		    u.usleep = 1;
436.  		    nomovemsg = "You wake up.";
437.  		    afternmv = Hear_again;
438.  		    break;
439.  
440.  		case RUST_TRAP:
441.  #ifdef POLYSELF
442.  		    if (u.umonnum == PM_IRON_GOLEM) {
443.  			pline("A gush of water hits you!");
444.  			You("are covered with rust!");
445.  			rehumanize();
446.  			break;
447.  		    } else
448.  		    if (u.umonnum == PM_GREMLIN && rn2(3)) {
449.  			pline("A gush of water hits you!");
450.  			if(mtmp = cloneu()) {
451.  			    mtmp->mhpmax = (u.mhmax /= 2);
452.  			    You("multiply.");
453.  			}
454.  			break;
455.  		    }
456.  #endif
457.  		/* Unlike monsters, traps cannot aim their rust attacks at
458.  		 * you, so instead of looping through and taking either the
459.  		 * first rustable one or the body, we take whatever we get,
460.  		 * even if it is not rustable.
461.  		 */
462.  		    switch (rn2(5)) {
463.  			case 0:
464.  			    pline("A gush of water hits you on the %s!",
465.  					body_part(HEAD));
466.  			    (void) rust_dmg(uarmh, "helmet", 1, TRUE);
467.  			    break;
468.  			case 1:
469.  			    pline("A gush of water hits your left %s!",
470.  					body_part(ARM));
471.  			    if (rust_dmg(uarms, "shield", 1, TRUE)) break;
472.  			    if (uwep && bimanual(uwep))
473.  				goto two_hand;
474.  			    /* Two goto statements in a row--aaarrrgggh! */
475.  glovecheck:		    (void) rust_dmg(uarmg, "gauntlets", 1, TRUE);
476.  			    /* Not "metal gauntlets" since it gets called
477.  			     * even if it's leather for the message
478.  			     */
479.  			    break;
480.  			case 2:
481.  			    pline("A gush of water hits your right %s!",
482.  					body_part(ARM));
483.  two_hand:		    erode_weapon(FALSE);
484.  			    goto glovecheck;
485.  			default:
486.  			    pline("A gush of water hits you!");
487.  			    if (uarmc) (void) rust_dmg(uarmc, "cloak", 1, TRUE);
488.  			    else if (uarm)
489.  				(void) rust_dmg(uarm, "armor", 1, TRUE);
490.  #ifdef TOURIST
491.  			    else if (uarmu)
492.  				(void) rust_dmg(uarmu, "shirt", 1, TRUE);
493.  #endif
494.  		    }
495.  		    break;
496.  
497.                  case FIRE_TRAP:
498.  	            dofiretrap();
499.  	            break;
500.  
501.  		case PIT:
502.  		    if (Levitation
503.  #ifdef POLYSELF
504.  			|| is_flyer(uasmon) || is_clinger(uasmon)
505.  #endif
506.  			) {
507.  			if(Blind) break;
508.  			if(trap->tseen)
509.  			    You("see a pit below you.");
510.  			else {
511.  			    pline("A pit opens up under you!");
512.  			    You("don't fall in!");
513.  			}
514.  			break;
515.  		    }
516.  		    You("fall into a pit!");
517.  #ifdef POLYSELF
518.  		    if (!passes_walls(uasmon))
519.  #endif
520.  			u.utrap = rn1(6,2);
521.  		    u.utraptype = TT_PIT;
522.  		    losehp(rnd(6),"fell into a pit", NO_KILLER_PREFIX);
523.  		    if (Punished && !carried(uball)) {
524.  			unplacebc();
525.  			ballfall();
526.  			placebc();
527.  		    }
528.  		    selftouch("Falling, you");
529.  		    exercise(A_STR, FALSE);
530.  		    vision_full_recalc = 1;	/* vision limits change */
531.  		    break;
532.  		case SPIKED_PIT:
533.  		    if (Levitation
534.  #ifdef POLYSELF
535.  			|| is_flyer(uasmon) || is_clinger(uasmon)
536.  #endif
537.  			) {
538.  			if(Blind) break;
539.  			pline("A pit full of spikes opens up under you!");
540.  			You("don't fall in!");
541.  			break;
542.  		    }
543.  		    You("fall into a pit!");
544.  		    You("land on a set of sharp iron spikes!");
545.  #ifdef POLYSELF
546.  		    if (!passes_walls(uasmon))
547.  #endif
548.  			u.utrap = rn1(6,2);
549.  		    u.utraptype = TT_PIT;
550.  		    losehp(rnd(10),"fell into a pit of iron spikes",
551.  			NO_KILLER_PREFIX);
552.  		    if(!rn2(6)) poisoned("spikes",A_STR,"fall onto poison spikes",8);
553.  		    if (Punished && !carried(uball)) {
554.  			unplacebc();
555.  			ballfall();
556.  			placebc();
557.  		    }
558.  		    selftouch("Falling, you");
559.  		    vision_full_recalc = 1;	/* vision limits change */
560.  		    exercise(A_STR, FALSE);
561.  		    exercise(A_DEX, FALSE);
562.  		    break;
563.  
564.  		case TRAPDOOR:
565.  		    if(!Can_fall_thru(&u.uz))
566.  			panic("Trapdoors cannot exist on this level.");
567.  		    fall_through(TRUE);
568.  		    break;
569.  
570.  		case TELEP_TRAP:
571.  		    if(In_endgame(&u.uz) || Antimagic) {
572.  			if(Antimagic)
573.  			    shieldeff(u.ux, u.uy);
574.  			You("feel a wrenching sensation.");
575.  #ifdef WALKIES
576.  		    } else if(!next_to_u()) {
577.  			    You(shudder_for_moment);
578.  #endif
579.  		    } else if(trap->once) {
580.  			deltrap(trap);
581.  			newsym(u.ux,u.uy);	/* get rid of trap symbol */
582.  			vtele();
583.  		    } else
584.  			tele();
585.  		    break;
586.  		case LEVEL_TELEP:
587.  		    You("%s onto a level teleport trap!",
588.  			  Levitation ? (const char *)"float" :
589.  #ifdef POLYSELF
590.  			  locomotion(uasmon, "step"));
591.  #else
592.  			  (const char *)"step");
593.  #endif
594.  		    if(Antimagic) {
595.  			shieldeff(u.ux, u.uy);
596.  		    }
597.  		    if(Antimagic || In_endgame(&u.uz)) {
598.  			You("feel a wrenching sensation.");
599.  			break;
600.  		    }
601.  		    if(!Blind)
602.  		        You("are momentarily blinded by a flash of light.");
603.  		    else
604.  			You("are momentarily disoriented.");
605.  		    deltrap(trap);
606.  		    newsym(u.ux,u.uy);	/* get rid of trap symbol */
607.  		    level_tele();
608.  		    break;
609.  
610.  		case WEB: /* Our luckless player has stumbled into a web. */
611.  #ifdef POLYSELF
612.  		    if (amorphous(uasmon)) {
613.  		        if (acidic(uasmon) || u.umonnum == PM_GELATINOUS_CUBE)
614.  			{
615.  			    deltrap(trap);
616.  			    newsym(u.ux,u.uy);/* update position */
617.  			    You("dissolve a spider web.");
618.  			    break;
619.  			}
620.  			You("flow through a spider web.");
621.  			break;
622.  		    }
623.  		    if (uasmon->mlet == S_SPIDER) {
624.  			pline("There is a spider web here.");
625.  			break;
626.  		    }
627.  #endif
628.  		    You("%s into a spider web!",
629.  			  Levitation ? (const char *)"float" :
630.  #ifdef POLYSELF
631.  			  locomotion(uasmon, "stumble"));
632.  #else
633.  			  (const char *)"stumble");
634.  #endif
635.  		    u.utraptype = TT_WEB;
636.  
637.  		    /* Time stuck in the web depends on your strength. */
638.  		    {
639.  		    register int str = ACURR(A_STR);
640.  
641.  		    if (str == 3) u.utrap = rn1(6,6);
642.  		    else if (str < 6) u.utrap = rn1(6,4);
643.  		    else if (str < 9) u.utrap = rn1(4,4);
644.  		    else if (str < 12) u.utrap = rn1(4,2);
645.  		    else if (str < 15) u.utrap = rn1(2,2);
646.  		    else if (str < 18) u.utrap = rnd(2);
647.  		    else if (str < 69) u.utrap = 1;
648.  		    else {
649.  			u.utrap = 0;
650.  			You("tear through the web!");
651.  			deltrap(trap);
652.  			newsym(u.ux,u.uy);	/* get rid of trap symbol */
653.  		    }
654.  		    }
655.  		    break;
656.  
657.  		case STATUE_TRAP:
658.  		    deltrap(trap);
659.  		    newsym(u.ux,u.uy);	/* get rid of trap symbol */
660.  		    for(otmp=level.objects[u.ux][u.uy];
661.  						otmp; otmp = otmp->nexthere)
662.  			if(otmp->otyp == STATUE)
663.  			    if(mtmp=makemon(&mons[otmp->corpsenm],u.ux,u.uy)) {
664.  				pline("The statue comes to life!");
665.  				/* mimic statues become seen mimics */
666.  				if(mtmp->m_ap_type) seemimic(mtmp);
667.  				delobj(otmp);
668.  				break;
669.  			    }
670.  		    break;
671.  
672.  		case MAGIC_TRAP:	    /* A magic trap. */
673.  		    if (!rn2(30)) {
674.  			deltrap(trap);
675.  			newsym(u.ux,u.uy);	/* update position */
676.  			You("are caught in a magical explosion!");
677.  			losehp(rnd(10), "magical explosion", KILLED_BY_AN);
678.  			Your("body absorbs some of the magical energy!");
679.  			u.uen = (u.uenmax += 2);
680.  		    } else domagictrap();
681.  		    break;
682.  
683.  		case ANTI_MAGIC:
684.  		    if(Antimagic) {
685.  			shieldeff(u.ux, u.uy);
686.  			You("feel momentarily lethargic.");
687.  		    } else drain_en(rnd((int)u.ulevel) + 1);
688.  		    break;
689.  
690.  #ifdef POLYSELF
691.  		case POLY_TRAP:
692.  		    if(Antimagic) {
693.  			shieldeff(u.ux, u.uy);
694.  			You("feel momentarily different.");
695.  			/* Trap did nothing; don't remove it --KAA */
696.  		    } else {
697.  			deltrap(trap);	/* delete trap before polymorph */
698.  			newsym(u.ux,u.uy);	/* get rid of trap symbol */
699.  			You("feel a change coming over you.");
700.  			polyself();
701.  		    }
702.  		    break;
703.  #endif
704.  
705.  		case LANDMINE: {
706.  		    if (Levitation
707.  #ifdef POLYSELF
708.  					|| is_flyer(uasmon)
709.  #endif
710.  								) {
711.  			You("see a trigger in a pile of soil below you.");
712.  			if (rn2(3)) break;
713.  			pline("KAABLAMM!!!  The air currents set it off!");
714.  		    } else {
715.  			pline("KAABLAMM!!!  You triggered a land mine!");
716.  			set_wounded_legs(LEFT_SIDE, rn1(35, 41));
717.  			set_wounded_legs(RIGHT_SIDE, rn1(35, 41));
718.  		    }
719.  		    losehp(rnd(16), "land mine", KILLED_BY_AN);
720.  		    /* wake everything on the level */
721.  		    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
722.  			if(mtmp->msleep) mtmp->msleep = 0;
723.  		    }
724.  		    deltrap(t_at(u.ux, u.uy));	/* mines only explode once */
725.  		    newsym(u.ux,u.uy);		/* get rid of trap symbol */
726.  		  }
727.  		    break;
728.  
729.                  case MAGIC_PORTAL:
730.  #ifdef WALKIES
731.  		    if(!next_to_u())
732.  			    You(shudder_for_moment);
733.  		    else
734.  #endif
735.  			    domagicportal(trap);
736.  	            break;
737.  
738.  		default:
739.  		    impossible("You hit a trap of type %u", trap->ttyp);
740.  	    }
741.  	}
742.  }
743.  
744.  #endif /* OVLB */
745.  
746.  #ifdef WALKIES
747.  
748.  STATIC_DCL boolean FDECL(teleport_pet, (struct monst *));
749.  
750.  #ifdef OVLB
751.  
752.  STATIC_OVL boolean
753.  teleport_pet(mtmp)
754.  register struct monst *mtmp;
755.  {
756.  	register struct obj *otmp;
757.  
758.  	if(mtmp->mleashed) {
759.  	    otmp = get_mleash(mtmp);
760.  	    if(!otmp)
761.  		impossible("%s is leashed, without a leash.", Monnam(mtmp));
762.  	    if(otmp->cursed) {
763.  # ifdef SOUNDS
764.  		yelp(mtmp);
765.  # endif
766.  		return FALSE;
767.  	    } else {
768.  		Your("leash goes slack.");
769.  		m_unleash(mtmp);
770.  		return TRUE;
771.  	    }
772.  	}
773.  	return TRUE;
774.  }
775.  
776.  #endif /* OVLB */
777.  
778.  #endif /* WALKIES */
779.  
780.  #ifdef OVLB
781.  
782.  void
783.  seetrap(trap)
784.  	register struct trap *trap;
785.  {
786.  	if(!trap->tseen) {
787.  	    trap->tseen = 1;
788.  	    newsym(trap->tx, trap->ty);
789.  	}
790.  }
791.  
792.  #endif /* OVLB */
793.  #ifdef OVL1
794.  
795.  int
796.  mintrap(mtmp)
797.  register struct monst *mtmp;
798.  {
799.  	register struct trap *trap = t_at(mtmp->mx, mtmp->my);
800.  	boolean trapkilled = FALSE, tdoor = FALSE;
801.  	struct permonst *mptr = mtmp->data;
802.  	struct obj *otmp;
803.  
804.  	if(!trap) {
805.  		mtmp->mtrapped = 0;	/* perhaps teleported? */
806.  	} else if (mtmp->mtrapped) {	/* was in trap */
807.  		if(!rn2(40)) 
808.  			if (sobj_at(BOULDER, mtmp->mx, mtmp->my) && 
809.  			    ((trap->ttyp == PIT) || 
810.  			     (trap->ttyp == SPIKED_PIT))) {
811.  				if (!rn2(2)) {
812.  					mtmp->mtrapped = 0;
813.  					fill_pit(mtmp->mx, mtmp->my);
814.  				}
815.  			} else
816.  				mtmp->mtrapped = 0;
817.  	} else {
818.  	    register int tt = trap->ttyp;
819.  
820.  	    /* A bug fix for dumb messages by ab@unido.
821.  	     */
822.  	    int in_sight = canseemon(mtmp);
823.  
824.  	    if(mtmp->mtrapseen & (1 << tt)) {
825.  		/* it has been in such a trap - perhaps it escapes */
826.  		if(rn2(4)) return(0);
827.  	    }
828.  	    mtmp->mtrapseen |= (1 << tt);
829.  	    switch (tt) {
830.  		case ARROW_TRAP:
831.  			otmp = mksobj(ARROW, TRUE, FALSE);
832.  			otmp->quan = 1L;
833.  			otmp->owt = weight(otmp);
834.  			if(in_sight) seetrap(trap);
835.  			if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE;
836.  			break;
837.  		case DART_TRAP:
838.  			otmp = mksobj(DART, TRUE, FALSE);
839.  			otmp->quan = 1L;
840.  			otmp->owt = weight(otmp);
841.  			if (!rn2(6)) otmp->opoisoned = 1;
842.  			if(in_sight) seetrap(trap);
843.  			if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE;
844.  			break;
845.  		case ROCKTRAP:
846.  			otmp = mksobj(ROCK, TRUE, FALSE);
847.  			otmp->quan = 1L;
848.  			otmp->owt = weight(otmp);
849.  			if(in_sight) seetrap(trap);
850.  			if(!is_whirly(mptr) && !passes_walls(mptr) &&
851.  			   thitm(0, mtmp, otmp, d(2, 6)))
852.  			    trapkilled = TRUE;
853.  			break;
854.  
855.  		case SQKY_BOARD: {
856.  			register struct monst *ztmp = fmon;
857.  
858.  			if(is_flyer(mptr)) break;
859.  			/* stepped on a squeaky board */
860.  			if (in_sight) {
861.  			    pline("A board beneath %s squeaks loudly.", mon_nam(mtmp));
862.  			    seetrap(trap);
863.  			} else
864.  			   You("hear a distant squeak.");
865.  			/* wake up nearby monsters */
866.  			while(ztmp) {
867.  			    if(dist2(mtmp->mx,mtmp->my,ztmp->mx,ztmp->my) < 40)
868.  				if(ztmp->msleep) ztmp->msleep = 0;
869.  			    ztmp = ztmp->nmon;
870.  			}
871.  			break;
872.  		}
873.  
874.  		case BEAR_TRAP:
875.  			if(mptr->msize > MZ_SMALL &&
876.  			   !amorphous(mptr) && !is_flyer(mptr)) {
877.  				mtmp->mtrapped = 1;
878.  				if(in_sight) {
879.  				  pline("%s is caught in a bear trap!",
880.  					Monnam(mtmp));
881.  				  seetrap(trap);
882.  				} else
883.  				    if((mptr == &mons[PM_OWLBEAR]
884.  					|| mptr == &mons[PM_BUGBEAR])
885.  					&& flags.soundok)
886.  			    You("hear the roaring of an angry bear!");
887.  			}
888.  			break;
889.  
890.  		case SLP_GAS_TRAP:
891.  			if(!resists_sleep(mptr) &&
892.  			   !mtmp->msleep && mtmp->mcanmove) {
893.  				mtmp->mcanmove = 0;
894.  				mtmp->mfrozen = rnd(25);
895.  				if (in_sight) {
896.  				    pline("%s suddenly falls asleep!",
897.  								Monnam(mtmp));
898.  				    seetrap(trap);
899.  				}
900.  			}
901.  			break;
902.  
903.  		case RUST_TRAP:
904.  			if (in_sight) {
905.  			    pline("A gush of water hits %s!", mon_nam(mtmp));
906.  			    seetrap(trap);
907.  			}
908.  			if (mptr == &mons[PM_IRON_GOLEM]) {
909.  				if (in_sight)
910.  				    pline("%s falls to pieces!", Monnam(mtmp));
911.  				else if(mtmp->mtame)
912.  				    pline("May %s rust in peace.",
913.  								mon_nam(mtmp));
914.  				mondied(mtmp);
915.  				trapkilled = TRUE;
916.  			} else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
917.  				struct monst *mtmp2 = clone_mon(mtmp);
918.  
919.  				if (mtmp2) {
920.  				    mtmp2->mhpmax = (mtmp->mhpmax /= 2);
921.  				    if(in_sight)
922.  					pline("%s multiplies.", Monnam(mtmp));
923.  				}
924.  			}
925.  			break;
926.  
927.  		case FIRE_TRAP:
928.  			if (in_sight)
929.  		pline("A tower of flame bursts from the floor under %s!",
930.  					mon_nam(mtmp));
931.  			if(resists_fire(mptr)) {
932.  			    if (in_sight) {
933.  				shieldeff(mtmp->mx,mtmp->my);
934.  				pline("%s is uninjured.", Monnam(mtmp));
935.  			    }
936.  			} else {
937.  			    int num=rnd(6);
938.  
939.  			    if (thitm(0, mtmp, (struct obj *)0, num))
940.  				trapkilled = TRUE;
941.  			    else mtmp->mhpmax -= num;
942.  			}
943.  			(void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
944.  			(void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
945.  			(void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
946.  			if (in_sight) seetrap(trap);
947.  			break;
948.  
949.  		case PIT:
950.  		case SPIKED_PIT:
951.  			if ( !is_flyer(mptr) && 
952.  			     (!mtmp->wormno || (count_wsegs(mtmp) < 6)) &&
953.  			     !is_clinger(mptr) ) {
954.  				if (!passes_walls(mptr))
955.  				    mtmp->mtrapped = 1;
956.  				if(in_sight) {
957.  				    pline("%s falls into a pit!", Monnam(mtmp));
958.  				    seetrap(trap);
959.  				}
960.  				if(thitm(0, mtmp, (struct obj *)0,
961.  					 rnd((tt==PIT) ? 6 : 10)))
962.  				    trapkilled = TRUE;
963.  			}
964.  			break;
965.  
966.  		case TRAPDOOR:
967.  			if(!Can_fall_thru(&u.uz))
968.  			    panic("Trapdoors cannot exist on this level.");
969.  
970.  			if ( (mptr == &mons[PM_WUMPUS]) ||
971.  			     (mtmp->wormno && count_wsegs(mtmp) > 5) ) break;
972.  			tdoor = TRUE;
973.  			/* Fall through */
974.  		case LEVEL_TELEP:
975.  			/* long worms w/tails can now change levels! - Norm */
976.  			if (!is_flyer(mptr)) {
977.  			    register int nlev;
978.  			    d_level tolevel;
979.  #ifdef WALKIES
980.  			    if(teleport_pet(mtmp)) {
981.  #endif
982.  				if(tdoor) {
983.  				    if(Is_stronghold(&u.uz))
984.  				        assign_level(&tolevel, &valley_level);
985.  				    else if(Is_botlevel(&u.uz)) {
986.  				        pline("%s avoids the trap.", 
987.  					                  Monnam(mtmp));
988.  					break;
989.  				    } else get_level(&tolevel,depth(&u.uz)+1);
990.  				} else {
991.  #ifdef MULDGN
992.  				    if(Is_knox(&u.uz)) {
993.  				        rloc(mtmp);
994.  					break;
995.  				    }
996.  #endif
997.  				    nlev = rnd(3);
998.  				    if(!rn2(2)) nlev = -(nlev);
999.  				    nlev = dunlev(&u.uz) + nlev;
1000. 				    if(nlev > dunlevs_in_dungeon(&u.uz)) {
1001. 				    	nlev = dunlevs_in_dungeon(&u.uz);
1002. 					/* teleport up if already on bottom */
1003. 					if (Is_botlevel(&u.uz)) 
1004. 					    nlev -= rnd(3);
1005. 				    }
1006. 				    if (nlev < 1) {
1007. 					nlev = 1;
1008. 					if (dunlev(&u.uz) == 1) {
1009. 					    nlev += rnd(3);
1010. 					    if (nlev >
1011. 					          dunlevs_in_dungeon(&u.uz)) 
1012. 					        nlev = 
1013. 						  dunlevs_in_dungeon(&u.uz);
1014. 					}
1015. 				    }
1016. 				    /* can't seem to go anywhere    */
1017. 				    /* (possible in short dungeons) */
1018. 				    if (nlev == dunlev(&u.uz)) {
1019. 					rloc(mtmp);
1020. 					break;
1021. 				    }
1022. 				    nlev = dungeons[u.uz.dnum].depth_start +
1023. 				                               nlev;
1024. 				    get_level(&tolevel, nlev);
1025. 				}
1026. 				if(in_sight) {
1027. 		pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
1028. 				    seetrap(trap);
1029. 				}
1030. 				migrate_to_level(mtmp, 
1031. 						 ledger_no(&tolevel), 0);
1032. 				return(3);	/* no longer on this level */
1033. #ifdef WALKIES
1034. 			    }
1035. #endif
1036. 			}
1037. 			break;
1038. 
1039. 		case TELEP_TRAP:
1040. 		case MAGIC_PORTAL:
1041. #ifdef WALKIES
1042. 			if(teleport_pet(mtmp)) {
1043. #endif
1044. 			    /* Note: don't remove the trap if a vault.  Other-
1045. 			     * wise the monster will be stuck there, since 
1046. 			     * the guard isn't going to come for it...
1047. 			     * Also: don't remove if magic portal.  In short,
1048. 			     * don't remove :-)
1049. 			     */
1050. 			    if (in_sight) {
1051. 				pline("%s suddenly disappears!", 
1052. 				                      Monnam(mtmp));
1053. 				seetrap(trap);
1054. 			    }
1055. 			    if (trap->once) vloc(mtmp);
1056. 			    else rloc(mtmp);
1057. #ifdef WALKIES
1058. 			}
1059. #endif
1060. 			break;
1061. 
1062. 	       case WEB:
1063. 			/* Monster in a web. */
1064. 			if (mptr->mlet == S_SPIDER) break;
1065. 			if (amorphous(mptr)) {
1066. 			    if (acidic(mptr) ||
1067. 				 mptr == &mons[PM_GELATINOUS_CUBE]) {
1068. 				if (in_sight)
1069. 				    pline("%s dissolves a spider web.",
1070. 						Monnam(mtmp));
1071. 				deltrap(trap);
1072. 				break;
1073. 			    }
1074. 			    if (in_sight)
1075. 				pline("%s flows through a spider web.",
1076. 						Monnam(mtmp));
1077. 			    break;
1078. 			}			
1079. 			switch (monsndx(mptr)) {
1080. 			    case PM_FIRE_ELEMENTAL:
1081. 				if (in_sight)
1082. 				    pline("%s burns a spider web!", Monnam(mtmp));
1083. 				deltrap(trap);
1084. 				break;
1085. 			    case PM_OWLBEAR: /* Eric Backus */
1086. 			    case PM_BUGBEAR:
1087. 				if (!in_sight) {
1088. 				    You("hear the roaring of a confused bear!");
1089. 				    mtmp->mtrapped = 1;
1090. 				    break;
1091. 				}
1092. 				/* fall though */
1093. 			    default:
1094. 				if (in_sight)
1095. 				    pline("%s is caught in a spider web.",
1096. 								Monnam(mtmp));
1097. 				mtmp->mtrapped = 1;
1098. 				break;
1099. 			}
1100. 			break;
1101. 
1102. 		case STATUE_TRAP:
1103. 			break;
1104. 
1105. 		case MAGIC_TRAP:
1106. 			/* A magic trap.  Monsters immune. */
1107. 			break;
1108. 		case ANTI_MAGIC:	
1109.                         break;
1110. 
1111. 		case LANDMINE: {
1112. 			register struct monst *mntmp = fmon;
1113. 
1114. 			if(rn2(3))
1115. 				break; /* monsters usually don't set it off */
1116. 			if(is_flyer(mptr)) {
1117. 				if (in_sight) {
1118. 	pline("A trigger appears in a pile of soil below %s.", Monnam(mtmp));
1119. 					seetrap(trap);
1120. 				}
1121. 				if (rn2(3)) break;
1122. 				if (in_sight)
1123. 					pline("The air currents set it off!");
1124. 			} else if(in_sight)
1125. 			    pline("KAABLAMM!!!  %s triggers a land mine!",
1126. 				  Monnam(mtmp));
1127. 			if (!in_sight)
1128. 				pline("Kaablamm!  You hear an explosion in the distance!");
1129. 			deltrap(trap);
1130. 			if(thitm(0, mtmp, (struct obj *)0, rnd(16)))
1131. 				trapkilled = TRUE;
1132. 			/* wake everything on the level */
1133. 			while(mntmp) {
1134. 				if(mntmp->msleep)
1135. 					mntmp->msleep = 0;
1136. 				mntmp = mntmp->nmon;
1137. 			}
1138. 			if (unconscious()) {
1139. 				multi = -1;
1140. 				nomovemsg="The explosion awakens you!";
1141. 			}
1142. 			break;
1143. 		}
1144. 
1145. #ifdef POLYSELF
1146. 		case POLY_TRAP:
1147. 		    if(!resist(mtmp, WAND_CLASS, 0, NOTELL)) {
1148. 			(void) newcham(mtmp, (struct permonst *)0);
1149. 			if (in_sight) seetrap(trap);
1150. 		    }
1151. 		    break;
1152. #endif
1153. 
1154. 		default:
1155. 			impossible("Some monster encountered a strange trap of type %d.", tt);
1156. 	    }
1157. 	}
1158. 	if(trapkilled) return 2;
1159. 	return mtmp->mtrapped;
1160. }
1161. 
1162. #endif /* OVL1 */
1163. #ifdef OVLB
1164. 
1165. void
1166. selftouch(arg)
1167. const char *arg;
1168. {
1169. 	if(uwep && (uwep->otyp == CORPSE && uwep->corpsenm == PM_COCKATRICE)
1170. #ifdef POLYSELF
1171. 			&& !resists_ston(uasmon)
1172. #endif
1173. 	){
1174. 		pline("%s touch the cockatrice corpse.", arg);
1175. #ifdef POLYSELF
1176. 		if(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))
1177. 		    return;
1178. #endif
1179. 		You("turn to stone...");
1180. 		killer_format = KILLED_BY;
1181. 		killer = "touching a cockatrice corpse";
1182. 		done(STONING);
1183. 	}
1184. }
1185. 
1186. void
1187. float_up()
1188. {
1189. 	if(u.utrap) {
1190. 		if(u.utraptype == TT_PIT) {
1191. 			u.utrap = 0;
1192. 			You("float up, out of the pit!");
1193. 			vision_full_recalc = 1;	/* vision limits change */
1194. 			fill_pit(u.ux, u.uy);
1195. 		} else if (u.utraptype == TT_INFLOOR) {
1196. 			Your("body pulls upward, but your %s are still stuck.",
1197. 			     makeplural(body_part(LEG)));
1198. 		} else {
1199. 			You("float up, only your %s is still stuck.",
1200. 				body_part(LEG));
1201. 		}
1202. 	}
1203. 	else if(Is_waterlevel(&u.uz))
1204. 		pline("It feels as though you'd lost some weight.");
1205. 	else if(u.uinwater)
1206. 		spoteffects();
1207. 	else if (Hallucination)
1208. 		pline("Up, up, and awaaaay!  You're walking on air!");
1209. 	else if(Is_airlevel(&u.uz))
1210. 		You("gain control over your movements.");
1211. 	else
1212. 		You("start to float in the air!");
1213. }
1214. 
1215. void
1216. fill_pit(x, y)
1217. int x, y;
1218. {
1219. 	struct obj *otmp;
1220. 	struct trap *t;
1221. 
1222. 	if ((t = t_at(x, y)) && 
1223. 	    ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT)) &&
1224. 	    (otmp = sobj_at(BOULDER, x, y))) {
1225. 		freeobj(otmp);
1226. 		(void) flooreffects(otmp, x, y, "settle");
1227. 	}
1228. }
1229. 
1230. int
1231. float_down()
1232. {
1233. 	register struct trap *trap = (struct trap *)0;
1234. 	boolean no_msg = FALSE;
1235. 
1236. 	if(Levitation) return(0); /* maybe another ring/potion/boots */
1237. 
1238. 	if (Punished && !carried(uball) &&
1239. 	    (is_pool(uball->ox, uball->oy) || 
1240. 	     ((trap = t_at(uball->ox, uball->oy)) && 
1241. 	      ((trap->ttyp == PIT) || (trap->ttyp == SPIKED_PIT) ||
1242. 	       (trap->ttyp == TRAPDOOR))))) {
1243. 			u.ux0 = u.ux;
1244. 			u.uy0 = u.uy;
1245. 			u.ux = uball->ox;
1246. 			u.uy = uball->oy;
1247. 			movobj(uchain, uball->ox, uball->oy);
1248. 			newsym(u.ux0, u.uy0);
1249. 			vision_full_recalc = 1;	/* in case the hero moved. */
1250. 	}
1251. 	/* check for falling into pool - added by GAN 10/20/86 */
1252. #ifdef POLYSELF
1253. 	if(!is_flyer(uasmon)) {
1254. #endif
1255. 		/* kludge alert:
1256. 		 * drown() and lava_effects() print various messages almost
1257. 		 * every time they're called which conflict with the "fall
1258. 		 * into" message below.  Thus, we want to avoid printing
1259. 		 * confusing, duplicate or out-of-order messages.
1260. 		 * Use knowledge of the two routines as a hack -- this
1261. 		 * should really handled differently -dlc
1262. 		 */
1263. 		if(is_pool(u.ux,u.uy) && !Wwalking && !u.uinwater)
1264. 			no_msg = drown();
1265. 
1266. 		if(is_lava(u.ux,u.uy)) {
1267. 			(void) lava_effects();
1268. 			no_msg = TRUE;
1269. 		}
1270. #ifdef POLYSELF
1271. 	}
1272. #endif
1273. 	if (!trap) {
1274. 		if(Is_airlevel(&u.uz))
1275. 			You("begin to tumble in place.");
1276. 		if(Is_waterlevel(&u.uz) && !no_msg)
1277. 			You("feel heavier.");
1278. 		/* u.uinwater msgs already in spoteffects()/drown() */
1279. 		else if (!u.uinwater && !no_msg) {
1280. 			if (Hallucination)
1281. 				pline("Bummer!  You've %s.",
1282. 			      	is_pool(u.ux,u.uy) ?
1283. 			      		"splashed down" : "hit the ground");
1284. 			else
1285. 				You("float gently to the %s.",
1286. 				    is_pool(u.ux,u.uy) ? "water" : "ground");
1287. 		}
1288. 		trap = t_at(u.ux,u.uy);
1289. 	}
1290. 
1291. 	if(trap)
1292. 		switch(trap->ttyp) {
1293. 		case STATUE_TRAP:
1294. 			break;
1295. 		case TRAPDOOR:
1296. 			if(!Can_fall_thru(&u.uz) || u.ustuck)
1297. 				break;
1298. 			/* fall into next case */
1299. 		default:
1300. 			dotrap(trap);
1301. 	}
1302. 	if(!flags.nopick && OBJ_AT(u.ux, u.uy) &&
1303. 	   !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) &&
1304. 	   (!is_pool(u.ux,u.uy) || Underwater))
1305. 	    pickup(1);
1306. 	return 0;
1307. }
1308. 
1309. 
1310. void
1311. tele()
1312. {
1313. 	coord cc;
1314. 
1315. 	/* Disable teleportation in stronghold && Vlad's Tower */
1316. 	if(level.flags.noteleport) {
1317. #ifdef WIZARD
1318. 		if (!wizard) {
1319. #endif
1320. 		    pline("A mysterious force prevents you from teleporting!");
1321. 		    return;
1322. #ifdef WIZARD
1323. 		}
1324. #endif
1325. 	}
1326. 
1327. 	/* don't show trap if "Sorry..." */
1328. 	if(!Blinded) make_blinded(0L,FALSE);
1329. 
1330. 	if((u.uhave.amulet || Is_wiz1_level(&u.uz) || Is_wiz2_level(&u.uz) ||
1331. 	       Is_wiz3_level(&u.uz)) && !rn2(3)) {
1332. 	    You("feel disoriented for a moment.");
1333. 	    return;
1334. 	}
1335. 	if(Teleport_control
1336. #ifdef WIZARD
1337. 			    || wizard
1338. #endif
1339. 					) {
1340. 	    if (unconscious())
1341. 		pline("Being unconscious, you cannot control your teleport.");
1342. 	    else {
1343. 		    pline("To what position do you want to be teleported?");
1344. 		    cc.x = u.ux;
1345. 		    cc.y = u.uy;
1346. 		    getpos(&cc, TRUE, "the desired position");/* force valid*/
1347.                     if(cc.x == -10) return; /* abort */
1348. 		    /* possible extensions: introduce a small error if
1349. 		       magic power is low; allow transfer to solid rock */
1350. 		    if(teleok(cc.x, cc.y, FALSE)){
1351. 			teleds(cc.x, cc.y);
1352. 			return;
1353. 		    }
1354. 		    pline("Sorry...");
1355. 		}
1356. 	}
1357. 
1358. 	(void) safe_teleds();
1359. }
1360. 
1361. void
1362. teleds(nux, nuy)
1363. register int nux,nuy;
1364. {
1365. 	if (Punished) unplacebc();
1366. 	u.utrap = 0;
1367. 	u.ustuck = 0;
1368. 	u.ux0 = u.ux;
1369. 	u.uy0 = u.uy;
1370. 	u.ux = nux;
1371. 	u.uy = nuy;
1372. 	fill_pit(u.ux0, u.uy0); /* do this now so that cansee() is correct */
1373. #ifdef POLYSELF
1374. 	if (hides_under(uasmon))
1375. 		u.uundetected = OBJ_AT(nux, nuy);
1376. 	else 
1377. 		u.uundetected = 0;
1378. 	if (u.usym == S_MIMIC_DEF) u.usym = S_MIMIC;
1379. #endif
1380. 	if(Punished) placebc();
1381. 	if(u.uswallow){
1382. 		u.uswldtim = u.uswallow = 0;
1383. 		docrt();
1384. 	}
1385. 	initrack(); /* teleports mess up tracking monsters without this */
1386. 	/*
1387. 	 *  Make sure the hero disappears from the old location.  This will
1388. 	 *  not happen if she is teleported within sight of her previous
1389. 	 *  location.  Force a full vision recalculation because the hero
1390. 	 *  is now in a new location.
1391. 	 */
1392. 	newsym(u.ux0,u.uy0);
1393. 	vision_full_recalc = 1;
1394. 	nomul(0);
1395. 	spoteffects();
1396. }
1397. 
1398. int
1399. dotele()
1400. {
1401. 	struct trap *trap;
1402. 	boolean castit = FALSE;
1403. 	register int sp_no = 0;
1404. 
1405. 	trap = t_at(u.ux, u.uy);
1406. 	if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP))
1407. 		trap = 0;
1408. 
1409. 	if (trap) {
1410. 		if (trap->once) {
1411. 			pline("This is a vault teleport, usable once only.");
1412. 			if (yn("Jump in?") == 'n')
1413. 				trap = 0;
1414. 			else {
1415. 				deltrap(trap);
1416. 				newsym(u.ux, u.uy);
1417. 			}
1418. 		}
1419. 		if (trap)
1420. #ifdef POLYSELF
1421. 			You("%s onto the teleportation trap.",
1422. 			    locomotion(uasmon, "jump"));
1423. #else
1424. 			You("jump onto the teleportation trap.");
1425. #endif
1426. 	}
1427. 	if(!trap && (!Teleportation ||
1428. 	   (u.ulevel < (pl_character[0] == 'W' ? 8 : 12)
1429. #ifdef POLYSELF
1430. 	    && !can_teleport(uasmon)
1431. #endif
1432. 	   )
1433. 	  )) {
1434. 		/* Try to use teleport away spell. */
1435. 		castit = objects[SPE_TELEPORT_AWAY].oc_name_known;
1436. 		if (castit) {
1437. 		    for (sp_no = 0; sp_no < MAXSPELL &&
1438. 				spl_book[sp_no].sp_id != NO_SPELL &&
1439. 				spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY; sp_no++);
1440. 
1441. 		    if (sp_no == MAXSPELL ||
1442. 			spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY)
1443. 			    castit = FALSE;
1444. 		}
1445. #ifdef WIZARD
1446. 		if (!wizard) {
1447. #endif
1448. 		    if (!castit) {
1449. 			if (!Teleportation)
1450. 			    You("don't know that spell.");
1451. 			else You("are not able to teleport at will.");
1452. 			return(0);
1453. 		    }
1454. #ifdef WIZARD
1455. 		}
1456. #endif
1457. 	}
1458. 
1459. 	if(!trap && (u.uhunger <= 100 || ACURR(A_STR) < 6)) {
1460. 		You("lack the strength for a teleport spell.");
1461. #ifdef WIZARD
1462. 		if(!wizard)
1463. #endif
1464. 		return(1);
1465. 	}
1466. 	if(!trap &&
1467. 	  check_capacity("Your concentration falters from carrying so much."))
1468. 	    return 1;
1469. 
1470. 	if (castit) {
1471. 		exercise(A_WIS, TRUE);
1472. 		if (spelleffects(++sp_no, TRUE))
1473. 			return(1);
1474. 		else
1475. #ifdef WIZARD
1476. 		    if (!wizard)
1477. #endif
1478. 			return(0);
1479. 	}
1480. #ifdef WALKIES
1481. 	if(next_to_u()) {
1482. #endif
1483. 		if (trap && trap->once) vtele();
1484. 		else tele();
1485. #ifdef WALKIES
1486. 		(void) next_to_u();
1487. 	} else {
1488. 		You(shudder_for_moment);
1489. 		return(0);
1490. 	}
1491. #endif
1492. 	if (!trap) morehungry(100);
1493. 	return(1);
1494. }
1495. 
1496. 
1497. void
1498. level_tele()
1499. {
1500. 	register int newlev;
1501. 	d_level newlevel;
1502. 
1503. 	if((u.uhave.amulet || In_endgame(&u.uz))
1504. #ifdef WIZARD
1505. 						&& !wizard
1506. #endif
1507. 							) {
1508. 	    You("feel very disoriented for a moment.");
1509. 	    return;
1510. 	}
1511. 	if(Teleport_control
1512. #ifdef WIZARD
1513. 	   || wizard
1514. #endif
1515. 		) {
1516. 	    char buf[BUFSZ];
1517. 
1518. 	    do {
1519. 	      getlin("To what level do you want to teleport? [type a number]",
1520. 			buf);
1521. 	    } while(!digit(buf[0]) && (buf[0] != '-' || !digit(buf[1])));
1522. 	    newlev = atoi(buf);
1523. 
1524. 	    /* no dungeon escape via this route */
1525. 	    if(newlev == 0) {
1526. 	        if(ynq("Go to Nowhere.  Are you sure?") != 'y') return;
1527. 	        You("scream in agony as your body begins to warp...");
1528. 		display_nhwindow(WIN_MESSAGE, FALSE);
1529. 	        You("cease to exist.");
1530. 	        killer_format = NO_KILLER_PREFIX;
1531. 	        killer = "committed suicide";
1532. 	        done(DIED);
1533. 		return;  
1534. 	    }
1535. #ifdef MULDGN
1536. 	    /* if in Knox and the requested level > 0, stay put.
1537. 	     * we let negative values requests fall into the "heaven" loop.
1538. 	     */
1539. 	    if(Is_knox(&u.uz) && newlev > 0) {
1540. 	        You(shudder_for_moment);
1541. 		return;
1542. 	    }
1543. 	    /* if in Quest, the player sees "Home 1", etc., on the status
1544. 	     * line, instead of the logical depth of the level.  controlled
1545. 	     * level teleport request is likely to be relativized to the
1546. 	     * status line, and consequently it should be incremented to 
1547. 	     * the value of the logical depth of the target level.
1548. 	     *
1549. 	     * we let negative values requests fall into the "heaven" loop.
1550. 	     */
1551. 	    if(In_quest(&u.uz) && newlev > 0)
1552. 	        newlev = newlev + dungeons[u.uz.dnum].depth_start - 1;
1553. #endif
1554. 	} else { /* involuntary level tele */
1555. #ifdef MULDGN
1556. 	    if(Is_knox(&u.uz)) {
1557. 	        You(shudder_for_moment);
1558. 		return;
1559. 	    }
1560. #endif
1561. 	    if(rn2(5)) newlev = rnd((int)depth(&u.uz) + 3);
1562. 	    else {
1563. 		You(shudder_for_moment);
1564. 		return; 
1565. 	    }
1566. 	    if(newlev == depth(&u.uz)) {
1567. 		/* if in a single-level dungeon... */
1568. 		if(dunlevs_in_dungeon(&u.uz) == 1) {
1569. 		    You(shudder_for_moment);
1570. 		    return; 
1571. 		}
1572. 		else if(dunlev(&u.uz) == 1) newlev++;
1573. 		else if(dunlev(&u.uz) == dunlevs_in_dungeon(&u.uz)) newlev--;
1574. 	        else if(In_hell(&u.uz)) newlev--;
1575. 		else newlev++;
1576. 	    } 
1577. 	}
1578. 
1579. #ifdef WALKIES
1580. 	if(!next_to_u()) {
1581. 		You(shudder_for_moment);
1582. 		return;
1583. 	}
1584. #endif
1585. 	if(newlev < 0) {
1586. 		if(newlev <= -10) {
1587. 			You("arrive in heaven.");
1588. 			verbalize("Thou art early, but we'll admit thee.");
1589. 			killer_format = NO_KILLER_PREFIX;
1590. 			killer = "went to heaven prematurely";
1591. 			done(DIED);
1592. 			return;
1593. 		} else	if (newlev == -9) {
1594. 			You("feel deliriously happy. ");
1595. 			pline("(In fact, you're on Cloud 9!) ");
1596. 			display_nhwindow(WIN_MESSAGE, FALSE);
1597. 		} else
1598. 			You("are now high above the clouds...");
1599. 
1600. 		if(Levitation || is_floater(uasmon)) {
1601. 		    You("float gently down to earth.");
1602. 		    u.uz.dnum = 0; /* he might have been in another dgn */
1603. 		    newlev = 1;
1604. 		}
1605. #ifdef POLYSELF
1606. 		else if(is_flyer(uasmon)) {
1607. 		    You("fly down to earth.");
1608. 		    u.uz.dnum = 0; /* he might have been in another dgn */
1609. 		    newlev = 1;
1610. 		}
1611. #endif
1612. 		else {
1613. 		    d_level save_dlevel;
1614. 		    
1615. 		    assign_level(&save_dlevel, &u.uz);
1616. 		    pline("Unfortunately, you don't know how to fly.");
1617. 		    You("plummet a few thousand feet to your death.");
1618. 		    u.uz.dnum = 0;
1619. 		    u.uz.dlevel = 0;
1620. 		    killer_format = NO_KILLER_PREFIX;
1621. 		    killer =
1622.     self_pronoun("teleported out of the dungeon and fell to %s death","his");
1623. 		    done(DIED);
1624. 		    assign_level(&u.uz, &save_dlevel);
1625. 		    flags.botl = 1;
1626. 		    return;
1627. 		}
1628. 	}
1629. 
1630. # ifdef WIZARD
1631. 	if (In_endgame(&u.uz)) {	/* must already be wizard */
1632. 	    newlevel.dnum = u.uz.dnum;
1633. 	    newlevel.dlevel = newlev;
1634. 	    goto_level(&newlevel, FALSE, FALSE, FALSE);
1635. 	    return;
1636. 	}
1637. # endif
1638. 
1639. 	/* calls done(ESCAPED) if newlevel==0 */
1640. 	if(u.uz.dnum == medusa_level.dnum &&
1641. 	    newlev >= dungeons[u.uz.dnum].depth_start +
1642. 						dunlevs_in_dungeon(&u.uz)) {
1643. 
1644. 		goto_hell(TRUE, FALSE);
1645. 	} else {
1646. 	    /* if invocation did not yet occur, teleporting into
1647. 	     * the last level of Gehennom is forbidden.
1648. 	     */
1649. 	    if(Inhell && !u.uevent.invoked &&
1650. 			newlev >= (dungeons[u.uz.dnum].depth_start +
1651. 					dunlevs_in_dungeon(&u.uz) - 1)) {
1652. 		newlev = dungeons[u.uz.dnum].depth_start +
1653. 					dunlevs_in_dungeon(&u.uz) - 2;
1654. 		pline("Sorry...");
1655. 	    }
1656. #ifdef MULDGN
1657. 	    /* no teleporting out of quest dungeon */
1658. 	    if(In_quest(&u.uz) && newlev < depth(&qstart_level))
1659. 		newlev = depth(&qstart_level);
1660. #endif
1661. 	    /* the player thinks of levels purely in logical terms, so
1662. 	     * we must translate newlev to a number relative to the
1663. 	     * current dungeon.
1664.   	     */
1665. 	    get_level(&newlevel, newlev);
1666. 	    goto_level(&newlevel, FALSE, FALSE, FALSE);
1667. 	}
1668. }
1669. 
1670. static void
1671. dofiretrap()
1672. {
1673. 
1674. 	register int num;
1675. 
1676. 	/* changed to be in conformance with
1677. 	 * SCR_FIRE by GAN 11/02/86
1678. 	 */
1679. 
1680. 	pline("A tower of flame bursts from the floor!");
1681. 	if(Fire_resistance) {
1682. 		shieldeff(u.ux, u.uy);
1683. 		You("are uninjured.");
1684. 	} else {
1685. 		num = rnd(6);
1686. 		u.uhpmax -= num;
1687. 		losehp(num,"burst of flame", KILLED_BY_AN);
1688. 	}
1689. 	destroy_item(SCROLL_CLASS, AD_FIRE);
1690. 	destroy_item(SPBOOK_CLASS, AD_FIRE);
1691. 	destroy_item(POTION_CLASS, AD_FIRE);
1692. }
1693. 
1694. static void
1695. domagicportal(ttmp)
1696. register struct trap *ttmp;
1697. {
1698. 	struct d_level target_level;
1699. 
1700. 	/* if landed from another portal, do nothing */
1701. 	/* problem: level teleport landing escapes the check */
1702. 	if(!on_level(&u.uz, &u.uz0)) return;
1703. 
1704. 	You("activated a magic portal!");
1705. 	You("feel dizzy for a moment, but the sensation passes.");
1706. 
1707. 	/* prevent the poor shnook, whose amulet was stolen  */
1708. 	/* while in the endgame, from accidently triggering  */
1709. 	/* the portal to the next level, and thus losing the */
1710. 	/* game                                              */
1711. 	if(In_endgame(&u.uz) && !u.uhave.amulet) return;
1712. 
1713. 	target_level = ttmp->dst;
1714. 	goto_level(&target_level, FALSE, FALSE, TRUE);
1715. }
1716. 
1717. static void
1718. domagictrap()
1719. {
1720. 	register int fate = rnd(20);
1721. 
1722. 	/* What happened to the poor sucker? */
1723. 
1724. 	if (fate < 10) {
1725. 
1726. 	  /* Most of the time, it creates some monsters. */
1727. 	  register int cnt = rnd(4);
1728. 
1729. 	  /* below checks for blindness added by GAN 10/30/86 */
1730. 	  if (!Blind)  {
1731. 		You("are momentarily blinded by a flash of light!");
1732. 		make_blinded((long)rn1(5,10),FALSE);
1733. 	  }  else
1734. 		You("hear a deafening roar!");
1735. 	  while(cnt--)
1736. 		(void) makemon((struct permonst *) 0, u.ux, u.uy);
1737. 	}
1738. 	else
1739. 	  switch (fate) {
1740. 
1741. 	     case 10:
1742. 	     case 11:
1743. 		      /* sometimes nothing happens */
1744. 			break;
1745. 	     case 12: /* a flash of fire */
1746. 		        dofiretrap();
1747. 			break;
1748. 
1749. 	     /* odd feelings */
1750. 	     case 13:	pline("A shiver runs up and down your %s!",
1751. 			      body_part(SPINE));
1752. 			break;
1753. 	     case 14:	You(Hallucination ?
1754. 				"hear the moon howling at you." :
1755. 				"hear distant howling.");
1756. 			break;
1757. 	     case 15:	You("suddenly yearn for %s.",
1758. 				Hallucination ? "Cleveland" :
1759. 						"your distant homeland");
1760. 			break;
1761. 	     case 16:   Your("pack shakes violently!");
1762. 			break;
1763. 	     case 17:	You(Hallucination ?
1764. 				"smell hamburgers." :
1765. 				"smell charred flesh.");
1766. 			break;
1767. 
1768. 	     /* very occasionally something nice happens. */
1769. 
1770. 	     case 19:
1771. 		    /* tame nearby monsters */
1772. 		   {   register int i,j;
1773. 		       register struct monst *mtmp;
1774. 
1775. 		       /* below pline added by GAN 10/30/86 */
1776. 		       (void) adjattrib(A_CHA,1,FALSE);
1777. 		       for(i = -1; i <= 1; i++) for(j = -1; j <= 1; j++) {
1778. 			   if(!isok(u.ux+i, u.uy+j)) continue;
1779. 			   mtmp = m_at(u.ux+i, u.uy+j);
1780. 			   if(mtmp)
1781. 			       (void) tamedog(mtmp, (struct obj *)0);
1782. 		       }
1783. 		       break;
1784. 		   }
1785. 
1786. 	     case 20:
1787. 		    /* uncurse stuff */
1788. 		   {  register struct obj *obj;
1789. 
1790. 			/* below plines added by GAN 10/30/86 */
1791. 			You(Hallucination ?
1792. 				"feel in touch with the Universal Oneness." :
1793. 				"feel like someone is helping you.");
1794. 			for(obj = invent; obj ; obj = obj->nobj)
1795. 			       if(obj->owornmask || obj->otyp == LOADSTONE)
1796. 					uncurse(obj);
1797. 		       if(Punished) unpunish();
1798. 		       break;
1799. 		   }
1800. 	     default: break;
1801. 	  }
1802. }
1803. 
1804. void
1805. water_damage(obj,force)
1806. register struct obj *obj;
1807. register boolean force;
1808. {
1809. 	/* Scrolls, spellbooks, potions, weapons and
1810. 	   pieces of armor may get affected by the water */
1811. 	for(; obj; obj = obj->nobj) {
1812. 
1813. 		(void) snuff_lit(obj);
1814. 
1815. 		if(obj->greased) {
1816. 			if (force || !rn2(2)) obj->greased = 0;
1817. 		} else if(Is_container(obj) && !Is_box(obj) &&
1818. 			(obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) {
1819. 			water_damage(obj->cobj,force);
1820. 		} else if(obj->oclass == SCROLL_CLASS && (force || rn2(12) > Luck)
1821. #ifdef MAIL
1822. 			  && obj->otyp != SCR_MAIL
1823. #endif
1824. 			  ) {
1825. 			obj->otyp = SCR_BLANK_PAPER;
1826. 		} else if(obj->oclass == SPBOOK_CLASS && (force || rn2(12) > Luck)) {
1827. 			if (obj->otyp == SPE_BOOK_OF_THE_DEAD)
1828. 				pline("Steam rises from %s.", the(xname(obj)));
1829. 			else obj->otyp = SPE_BLANK_PAPER;
1830. 		} else if(obj->oclass == POTION_CLASS && (force || rn2(12) > Luck)) {
1831. 			if (obj->spe == -1) {
1832. 				obj->otyp = POT_WATER;
1833. 				obj->blessed = obj->cursed = 0;
1834. 				obj->spe = 0;
1835. 			} else obj->spe--;
1836. 		} else if(is_rustprone(obj) && obj->oeroded < MAX_ERODE &&
1837. 			  !(obj->oerodeproof || (obj->blessed && !rnl(4))) &&
1838. 			  (force || rn2(12) > Luck)) {
1839. 			/* all metal stuff and armor except body armor
1840. 			   protected by oilskin cloak */
1841. 			if(obj->oclass != ARMOR_CLASS || obj != uarm ||
1842. 			   !uarmc || uarmc->otyp != OILSKIN_CLOAK ||
1843.  			   (uarmc->cursed && !rn2(3)))
1844. 				obj->oeroded++;
1845. 		}
1846. 	}
1847. }
1848. 
1849. /*
1850.  * This function is potentially expensive - rolling
1851.  * inventory list multiple times.  Luckily it's seldom needed.
1852.  * Returns TRUE if disrobing made player unencumbered enough to
1853.  * crawl out of the current predicament.
1854.  */
1855. static boolean
1856. emergency_disrobe(lostsome)
1857. boolean *lostsome;
1858. {
1859. 	int invc = inv_cnt();
1860. 
1861. 	while (near_capacity() > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) {
1862. 		register struct obj *obj, *otmp = (struct obj *)0;
1863. 		register int i = rn2(invc);
1864. 
1865. 		for (obj = invent; obj; obj = obj->nobj) {
1866. 			/*
1867. 			 * Undroppables are: body armor, boots, gloves,
1868. 			 * amulets, and rings because of the time and effort
1869. 			 * in removing them + loadstone and other cursed stuff
1870. 			 * for obvious reasons.
1871. 			 */
1872. 			if (!(obj->otyp == LOADSTONE ||
1873. 			      obj == uamul || obj == uleft || obj == uright ||
1874. 			      obj == ublindf || obj == uarm || obj == uarmc ||
1875. 			      obj == uarmg || obj == uarmf ||
1876. #ifdef TOURIST
1877. 			      obj == uarmu ||
1878. #endif
1879. 			      (obj->cursed && (obj == uarmh || obj == uarms)) ||
1880. 			      welded(obj)))
1881. 				otmp = obj;
1882. 			/* reached the mark and found some stuff to drop? */
1883. 			if (--i < 0 && otmp) break;
1884. 
1885. 			/* else continue */
1886. 		}
1887. 
1888. 		/* nothing to drop and still overweight */
1889. 		if (!otmp) return(FALSE);
1890. 
1891. 		if (otmp == uarmh) (void) Helmet_off();
1892. 		else if (otmp == uarms) (void) Shield_off();
1893. 		else if (otmp == uwep) setuwep((struct obj *)0);
1894. 		*lostsome = TRUE;
1895. 		dropx(otmp);
1896. 		invc--;
1897. 	}
1898. 	return(TRUE);
1899. }
1900. 
1901. /*
1902.  *  return(TRUE) == player relocated
1903.  */
1904. boolean
1905. drown()
1906. {
1907. 	boolean inpool_ok = FALSE, crawl_ok;
1908. 	int i, x, y;
1909. 
1910. 	/* happily wading in the same contiguous pool */
1911. 	if (u.uinwater && is_pool(u.ux-u.dx,u.uy-u.dy) &&
1912. 	   Magical_breathing) {
1913. 		/* water effects on objects every now and then */
1914. 		if (!rn2(5)) inpool_ok = TRUE;
1915. 		else return(FALSE);
1916. 	}
1917. 
1918. 	if (!u.uinwater) {
1919. 	    You("%s into the water!",
1920. 		Is_waterlevel(&u.uz) ? "plunge" : "fall");
1921. #ifdef POLYSELF
1922. 	    if(!is_swimmer(uasmon))
1923. #endif
1924. 		if (!Is_waterlevel(&u.uz))
1925. 		    You("sink like %s.",
1926. 			Hallucination ? "the Titanic" : "a rock");
1927. 	}
1928. 
1929. 	water_damage(invent,FALSE);
1930. 
1931. #ifdef POLYSELF
1932. 	if(u.umonnum == PM_GREMLIN && rn2(3)) {
1933. 		struct monst *mtmp;
1934. 		if(mtmp = cloneu()) {
1935. 			mtmp->mhpmax = (u.mhmax /= 2);
1936. 			You("multiply.");
1937. 		}
1938. 	}
1939. 
1940. 	if(is_swimmer(uasmon)) return(FALSE);
1941. #endif
1942. 	if (inpool_ok) return(FALSE);
1943. #ifdef WALKIES
1944. 	if ((i = number_leashed()) > 0) {
1945. 		pline("The leash%s slip%s loose.",
1946. 			(i > 1) ? "es" : "",
1947. 			(i > 1) ? "" : "s");
1948. 		unleash_all();
1949. 	}
1950. #endif
1951. 	if (Magical_breathing) {
1952. 		pline("But wait!");
1953. 		Your("lungs start acting like gills.");
1954. 		if (!Is_waterlevel(&u.uz))
1955. 			Your("%s the bottom.",Hallucination ? "keel hits" : "feet touch");
1956. 		if (Punished) placebc();
1957. 		u.uinwater = 1;
1958. 		under_water(1);
1959. 		return(FALSE);
1960. 	}
1961. 	if((Teleportation || can_teleport(uasmon)) &&
1962. 	   (Teleport_control || rn2(3) < Luck+2)) {
1963. 		You("attempt a teleport spell.");	/* utcsri!carroll */
1964. 		(void) dotele();
1965. 		if(!is_pool(u.ux,u.uy))
1966. 			return(TRUE);
1967. 	}
1968. 	crawl_ok = FALSE;
1969. 	/* look around for a place to crawl to */
1970. 	for (i = 0; i < 100; i++) {
1971. 		x = rn1(3,u.ux - 1);
1972. 		y = rn1(3,u.uy - 1);
1973. 		if (teleok(x,y,TRUE)) {
1974. 			crawl_ok = TRUE;
1975. 			goto crawl;
1976. 		}
1977. 	}
1978. 	/* one more scan */
1979. 	for (x = u.ux - 1; x <= u.ux + 1; x++)
1980. 		for (y = u.uy - 1; y <= u.uy + 1; y++)
1981. 			if (teleok(x,y,TRUE)) {
1982. 				crawl_ok = TRUE;
1983. 				goto crawl;
1984. 			}
1985. crawl:;
1986. 	if (crawl_ok) {
1987. 		boolean lost = FALSE;
1988. 		/* time to do some strip-tease... */
1989. 		boolean succ = Is_waterlevel(&u.uz) ? TRUE :
1990. 				emergency_disrobe(&lost);
1991. 
1992. 		You("try to crawl out of the water.");
1993. 		if (lost)
1994. 			You("dump some of your gear to lose weight...");
1995. 		if (succ) {
1996. 			pline("Pheew!  That was close.");
1997. 			teleds(x,y);
1998. 			return(TRUE);
1999. 		}
2000. 		/* still too much weight */
2001. 		pline("But in vain.");
2002. 	}
2003. 	u.uinwater = 1;
2004. 	You("drown.");
2005. 	killer_format = KILLED_BY_AN;
2006. 	killer = (levl[u.ux][u.uy].typ == POOL || Is_medusa_level(&u.uz)) ?
2007. 	    "pool of water" : "moat";
2008. 	done(DROWNING);
2009. 	/* oops, we're still alive.  better get out of the water. */
2010. 	if (!safe_teleds())
2011. 		while (1) {
2012. 			pline("You're still drowning.");
2013. 			done(DROWNING);
2014. 		}
2015. 	u.uinwater = 0;
2016. 	You("find yourself back %s.",Is_waterlevel(&u.uz) ?
2017. 		"in an air bubble" : "on dry land");
2018. 	return(TRUE);
2019. }
2020. 
2021. void
2022. drain_en(n)
2023. register int n;
2024. {
2025. 	if (!u.uenmax) return;
2026. 	You("feel your magical energy drain away!");
2027. 	u.uen -= n;
2028. 	if(u.uen < 0)  {
2029. 		u.uenmax += u.uen;
2030. 		if(u.uenmax < 0) u.uenmax = 0;
2031. 		u.uen = 0;
2032. 	}
2033. 	flags.botl = 1;
2034. }
2035. 
2036. int
2037. dountrap()	/* disarm a trapped object */
2038. {
2039. #ifdef POLYSELF
2040. 	if(nohands(uasmon)) {
2041. 	    pline("And just how do you expect to do that?");
2042. 	    return(0);
2043. 	}
2044. #endif
2045. 	return untrap(FALSE);
2046. }
2047. 
2048. int
2049. untrap(force)
2050. boolean force;
2051. {
2052. 	register struct obj *otmp;
2053. 	register boolean confused = (Confusion > 0 || Hallucination > 0);
2054. 	register int x,y;
2055. 	int ch;
2056. 	struct trap *ttmp;
2057. 	struct monst *mtmp;
2058. 	boolean trap_skipped = FALSE;
2059. 
2060. 	if(!getdir(NULL)) return(0);
2061. 	x = u.ux + u.dx;
2062. 	y = u.uy + u.dy;
2063. 
2064. 	if(!u.dx && !u.dy) {
2065. 	    for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
2066. 		if(Is_box(otmp)) {
2067. 		    pline("There is %s here.", doname(otmp));
2068. 
2069. 		    switch (ynq("Check for traps?")) {
2070. 			case 'q': return(0);
2071. 			case 'n': continue;
2072. 		    }
2073. 
2074. 		    if((otmp->otrapped && (force || (!confused
2075. 				&& rn2(MAXULEV + 1 - (int)u.ulevel) < 10)))
2076. 		       || (!force && confused && !rn2(3))) {
2077. 			You("find a trap on %s!", the(xname(otmp)));
2078. 			exercise(A_WIS, TRUE);
2079. 
2080. 			switch (ynq("Disarm it?")) {
2081. 			    case 'q': return(1);
2082. 			    case 'n': trap_skipped = TRUE;  continue;
2083. 			}
2084. 
2085. 			if(otmp->otrapped) {
2086. 			    exercise(A_DEX, TRUE);
2087. 			    ch = ACURR(A_DEX) + u.ulevel;
2088. 			    if (pl_character[0] == 'R') ch *= 2;
2089. 			    if(!force && (confused || Fumbling ||
2090. 				rnd(75+level_difficulty()/2) > ch)) {
2091. 				(void) chest_trap(otmp, FINGER, TRUE);
2092. 			    } else {
2093. 				You("disarm it!");
2094. 				otmp->otrapped = 0;
2095. 			    }
2096. 			} else pline("That %s was not trapped.", doname(otmp));
2097. 			return(1);
2098. 		    } else {
2099. 			You("find no traps on %s.", the(xname(otmp)));
2100. 			return(1);
2101. 		    }
2102. 		}
2103. 	    if ((ttmp = t_at(x,y)) && ttmp->tseen)
2104. 		You("cannot disable this trap.");
2105. 	    else
2106. 		You(trap_skipped ? "find no other traps here."
2107. 				 : "know of no traps here.");
2108. 	    return(0);
2109. 	}
2110. 
2111. 	if ((mtmp = m_at(x,y))				&&
2112. 		mtmp->m_ap_type == M_AP_FURNITURE	&&
2113. 		(mtmp->mappearance == S_hcdoor ||
2114. 			mtmp->mappearance == S_vcdoor)	&&
2115. 		!Protection_from_shape_changers)	 {
2116. 
2117. 	    stumble_onto_mimic(mtmp);
2118. 	    return(1);
2119. 	}
2120. 
2121. 	if (!IS_DOOR(levl[x][y].typ)) {
2122. 	    if ((ttmp = t_at(x,y)) && ttmp->tseen)
2123. 		You("cannot disable that trap.");
2124. 	    else
2125. 		You("know of no traps there.");
2126. 	    return(0);
2127. 	}
2128. 
2129. 	switch (levl[x][y].doormask) {
2130. 	    case D_NODOOR:
2131. 		You("%s no door there.", Blind ? "feel" : "see");
2132. 		return(0);
2133. 	    case D_ISOPEN:
2134. 		pline("This door is safely open.");
2135. 		return(0);
2136. 	    case D_BROKEN:
2137. 		pline("This door is broken.");
2138. 		return(0);
2139. 	}
2140. 
2141. 	if ((levl[x][y].doormask & D_TRAPPED
2142. 	     && (force ||
2143. 		 (!confused && rn2(MAXULEV - (int)u.ulevel + 11) < 10)))
2144. 	    || (!force && confused && !rn2(3))) {
2145. 		You("find a trap on the door!");
2146. 		exercise(A_WIS, TRUE);
2147. 		if (ynq("Disarm it?") != 'y') return(1);
2148. 		if (levl[x][y].doormask & D_TRAPPED) {
2149. 		    ch = 15 +
2150. 			 (pl_character[0] == 'R') ? u.ulevel*3 :
2151. 			 u.ulevel;
2152. 		    exercise(A_DEX, TRUE);
2153. 		    if(!force && (confused || Fumbling || 
2154. 		                     rnd(75+level_difficulty()/2) > ch)) {
2155. 			    You("set it off!");
2156. 			    b_trapped("door");
2157. 		    } else
2158. 			    You("disarm it!");
2159. 		    levl[x][y].doormask &= ~D_TRAPPED;
2160. 		} else pline("This door was not trapped.");
2161. 		return(1);
2162. 	} else {
2163. 		You("find no traps on the door.");
2164. 		return(1);
2165. 	}
2166. }
2167. 
2168. /* only called when the player is doing something to the chest directly */
2169. boolean
2170. chest_trap(obj, bodypart, disarm)
2171. register struct obj *obj;
2172. register int bodypart;
2173. boolean disarm;
2174. {
2175. 	register struct obj *otmp = obj, *otmp2;
2176. 	char	buf[80];
2177. 	const char *msg;
2178. 
2179. 	You(disarm ? "set it off!" : "trigger a trap!");
2180. 	display_nhwindow(WIN_MESSAGE, FALSE);
2181. 	if (Luck > -13 && rn2(13+Luck) > 7) {	/* saved by luck */
2182. 	    /* trap went off, but good luck prevents damage */
2183. 	    switch (rn2(13)) {
2184. 		case 12:
2185. 		case 11:  msg = "explosive charge is a dud";  break;
2186. 		case 10:
2187. 		case  9:  msg = "electric charge is grounded";  break;
2188. 		case  8:
2189. 		case  7:  msg = "flame fizzles out";  break;
2190. 		case  6:
2191. 		case  5:
2192. 		case  4:  msg = "poisoned needle misses";  break;
2193. 		case  3:
2194. 		case  2:
2195. 		case  1:
2196. 		case  0:  msg = "gas cloud blows away";  break;
2197. 		default:  impossible("chest disarm bug");  msg = NULL;  break;
2198. 	    }
2199. 	    if (msg) pline("But luckily the %s!", msg);
2200. 	} else {
2201. 	    switch(rn2(20) ? ((Luck >= 13) ? 0 : rn2(13-Luck)) : rn2(26)) {
2202. 		case 25:
2203. 		case 24:
2204. 		case 23:
2205. 		case 22:
2206. 		case 21: {
2207. 		          register struct monst *shkp;
2208. 			  long loss = 0L;
2209. 			  boolean costly, insider;
2210. 			  register xchar ox = obj->ox, oy = obj->oy;
2211. 
2212. #ifdef GCC_WARN
2213. 			  shkp = (struct monst *) 0;
2214. #endif
2215. 			  /* the obj location need not be that of player */
2216. 			  costly = (costly_spot(ox, oy) && 
2217. 				   (shkp = shop_keeper(*in_rooms(ox, oy,
2218. 				    SHOPBASE))) != (struct monst *)0);
2219. 			  insider = (*u.ushops && inside_shop(u.ux, u.uy) &&
2220. 				    *in_rooms(ox, oy, SHOPBASE) == *u.ushops);
2221. 
2222. 			  pline("%s explodes!", The(xname(obj)));
2223. 			  Sprintf(buf, "exploding %s", xname(obj));
2224. 
2225. 			  if(costly)
2226. 			      loss += stolen_value(obj, ox, oy,
2227. 						(boolean)shkp->mpeaceful, TRUE);
2228. 			  delete_contents(obj);
2229. 			  for(otmp = level.objects[u.ux][u.uy];
2230. 							otmp; otmp = otmp2) {
2231. 			      otmp2 = otmp->nexthere;
2232. 			      if(costly)
2233. 			          loss += stolen_value(otmp, otmp->ox, 
2234. 					  otmp->oy, (boolean)shkp->mpeaceful,
2235. 					  TRUE);
2236. 			      delobj(otmp);
2237. 			  }
2238. 			  exercise(A_STR, FALSE);
2239. 			  losehp(d(6,6), buf, KILLED_BY_AN);
2240. 			  if(costly && loss) {
2241. 			      if(insider)
2242. 			      You("owe %ld zorkmids for objects destroyed.",
2243. 				                              loss);
2244. 			      else {
2245.   		                  You("caused %ld zorkmids worth of damage!",
2246. 			                                      loss);
2247. 			          make_angry_shk(shkp, ox, oy);
2248. 			      }
2249. 			  }
2250. 			  wake_nearby();
2251. 			  return TRUE;
2252. 			}
2253. 		case 20:
2254. 		case 19:
2255. 		case 18:
2256. 		case 17:
2257. 			pline("A cloud of noxious gas billows from %s.",
2258. 			      the(xname(obj)));
2259. 			poisoned("gas cloud", A_STR, "cloud of poison gas",15);
2260. 			exercise(A_CON, FALSE);
2261. 			break;
2262. 		case 16:
2263. 		case 15:
2264. 		case 14:
2265. 		case 13:
2266. 			You("feel a needle prick your %s.",body_part(bodypart));
2267. 			poisoned("needle", A_CON, "poison needle",10);
2268. 			exercise(A_CON, FALSE);
2269. 			break;
2270. 		case 12:
2271. 		case 11:
2272. 		case 10:
2273. 		case 9:
2274. 			pline("A tower of flame erupts from %s!",
2275. 			      the(xname(obj)));
2276. 			if(Fire_resistance) {
2277. 			    shieldeff(u.ux, u.uy);
2278. 			    You("don't seem to be affected.");
2279. 			} else	losehp(d(4, 6), "tower of flame", KILLED_BY_AN);
2280. 			destroy_item(SCROLL_CLASS, AD_FIRE);
2281. 			destroy_item(SPBOOK_CLASS, AD_FIRE);
2282. 			destroy_item(POTION_CLASS, AD_FIRE);
2283. 			break;
2284. 		case 8:
2285. 		case 7:
2286. 		case 6:
2287. 			You("are jolted by a surge of electricity!");
2288. 			if(Shock_resistance)  {
2289. 			    shieldeff(u.ux, u.uy);
2290. 			    You("don't seem to be affected.");
2291. 			} else	losehp(d(4, 4), "electric shock", KILLED_BY_AN);
2292. 			destroy_item(RING_CLASS, AD_ELEC);
2293. 			destroy_item(WAND_CLASS, AD_ELEC);
2294. 			break;
2295. 		case 5:
2296. 		case 4:
2297. 		case 3:
2298. 			pline("Suddenly you are frozen in place!");
2299. 			nomul(-d(5, 6));
2300. 			exercise(A_DEX, FALSE);
2301. 			nomovemsg = "You can move again.";
2302. 			break;
2303. 		case 2:
2304. 		case 1:
2305. 		case 0:
2306. 			pline("A cloud of %s gas billows from %s",
2307. 			      hcolor(), the(xname(obj)));
2308. 			if(!Stunned)
2309. 			    if (Hallucination)
2310. 				pline("What a groovy feeling!");
2311. 			    else
2312. 				You("stagger and your vision blurs...");
2313. 			make_stunned(HStun + rn1(7, 16),FALSE);
2314. 			make_hallucinated(HHallucination + rn1(5, 16),FALSE,0L);
2315. 			break;
2316. 		default: impossible("bad chest trap");
2317. 			break;
2318. 	    }
2319. 	    bot();			/* to get immediate botl re-display */
2320. 	}
2321. 	otmp->otrapped = 0;		/* these traps are one-shot things */
2322. 
2323. 	return FALSE;
2324. }
2325. 
2326. #endif /* OVLB */
2327. #ifdef OVL0
2328. 
2329. struct trap *
2330. t_at(x,y)
2331. register int x, y;
2332. {
2333. 	register struct trap *trap = ftrap;
2334. 	while(trap) {
2335. 		if(trap->tx == x && trap->ty == y) return(trap);
2336. 		trap = trap->ntrap;
2337. 	}
2338. 	return((struct trap *)0);
2339. }
2340. 
2341. #endif /* OVL0 */
2342. #ifdef OVLB
2343. 
2344. void
2345. deltrap(trap)
2346. register struct trap *trap;
2347. {
2348. 	register struct trap *ttmp;
2349. 
2350. 	if(trap == ftrap)
2351. 		ftrap = ftrap->ntrap;
2352. 	else {
2353. 		for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ;
2354. 		ttmp->ntrap = trap->ntrap;
2355. 	}
2356. 	dealloc_trap(trap);
2357. }
2358. 
2359. /* used for doors.  can be used for anything else that opens. */
2360. void
2361. b_trapped(item)
2362. register const char *item;
2363. {
2364. 	register int lvl = level_difficulty();
2365. 	int dmg = rnd(5 + (lvl<5 ? lvl : 2+lvl/2));
2366. 
2367. 	pline("KABOOM!!  %s was booby-trapped!", The(item));
2368. 	if (u.ulevel < 4 && lvl < 3 && !rnl(3))
2369. 		You("are shaken, but luckily unhurt.");		
2370. 	else losehp(dmg, "explosion", KILLED_BY_AN);
2371. 	exercise(A_STR, FALSE);
2372. 	make_stunned(HStun + dmg, TRUE);
2373. }
2374. 
2375. /* Monster is hit by trap. */
2376. /* Note: doesn't work if both obj and d_override are null */
2377. STATIC_OVL boolean
2378. thitm(tlev, mon, obj, d_override)
2379. register int tlev;
2380. register struct monst *mon;
2381. register struct obj *obj;
2382. int d_override;
2383. {
2384. 	register int strike;
2385. 	register boolean trapkilled = FALSE;
2386. 
2387. 	if (d_override) strike = 1;
2388. 	else if (obj) strike = (find_mac(mon) + tlev + obj->spe <= rnd(20));
2389. 	else strike = (find_mac(mon) + tlev <= rnd(20));
2390. 
2391. 	/* Actually more accurate than thitu, which doesn't take
2392. 	 * obj->spe into account.
2393. 	 */
2394. 	if(!strike) {
2395. 		if (cansee(mon->mx, mon->my))
2396. 			pline("%s is almost hit by %s!", Monnam(mon),
2397. 								doname(obj));
2398. 	} else {
2399. 		int dam = 1;
2400. 
2401. 		if (obj && cansee(mon->mx, mon->my))
2402. 			pline("%s is hit by %s!", Monnam(mon), doname(obj));
2403. 		if (d_override) dam = d_override;
2404. 		else if (obj) {
2405. 			dam = dmgval(obj, mon->data);
2406. 			if (dam < 1) dam = 1;
2407. 		}
2408. 		if ((mon->mhp -= dam) <= 0) {
2409. 			int xx = mon->mx;
2410. 			int yy = mon->my;
2411. 
2412. 			monkilled(mon, "", AD_PHYS);
2413. 			newsym(xx, yy);
2414. 			trapkilled = TRUE;
2415. 		}
2416. 	}
2417. 	if (obj && (!strike || d_override)) {
2418. 		place_object(obj, mon->mx, mon->my);
2419. 		obj->nobj = fobj;
2420. 		fobj = obj;
2421. 		stackobj(fobj);
2422. 	} else if (obj) dealloc_obj(obj);
2423. 
2424. 	return trapkilled;
2425. }
2426. 
2427. boolean
2428. unconscious()
2429. {
2430. 	return (multi < 0 && (!nomovemsg ||
2431. 		u.usleep ||
2432. 		!strncmp(nomovemsg,"You regain con", 15) ||
2433. 		!strncmp(nomovemsg,"You are consci", 15)));
2434. }
2435. 
2436. static char lava_killer[] = "molten lava";
2437. 
2438. boolean
2439. lava_effects()
2440. {
2441.     register struct obj *obj, *obj2;
2442.     int dmg;
2443. 
2444.     if (!Fire_resistance) {
2445. 	if(Wwalking) {
2446. 	    dmg = d(6,6);
2447. 	    pline("The lava here burns you!");
2448. 	    if(dmg < u.uhp) {
2449. 		losehp(dmg, lava_killer, KILLED_BY);
2450. 		goto burn_stuff;
2451. 	    }
2452. 	} else
2453. 	    You("fall into the lava!");
2454. 
2455. 	for(obj = invent; obj; obj = obj2) {
2456. 	    obj2 = obj->nobj;
2457. 	    if(is_organic(obj) && !obj->oerodeproof) {
2458. 		if(obj->owornmask) {
2459. 		    if(obj == uarm) (void) Armor_gone();
2460. 		    else if(obj == uarmc) (void) Cloak_off();
2461. 		    else if(obj == uarmh) (void) Helmet_off();
2462. 		    else if(obj == uarms) (void) Shield_off();
2463. 		    else if(obj == uarmg) (void) Gloves_off();
2464. 		    else if(obj == uarmf) (void) Boots_off();
2465. #ifdef TOURIST
2466. 		    else if(obj == uarmu) setnotworn(obj);
2467. #endif
2468. 		    else if(obj == uleft) Ring_gone(obj);
2469. 		    else if(obj == uright) Ring_gone(obj);
2470. 		    else if(obj == ublindf) Blindf_off(obj);
2471. 		    else if(obj == uwep) uwepgone();
2472. 		    if(Lifesaved
2473. #ifdef WIZARD
2474. 		       || wizard
2475. #endif
2476. 		       ) Your("%s into flame!", aobjnam(obj, "burst"));
2477. 		}
2478. 		useup(obj);
2479. 	    }
2480. 	}
2481. 
2482. 	/* s/he died... */
2483. 	u.uhp = -1;
2484. 	killer_format = KILLED_BY;
2485. 	killer = lava_killer;
2486. 	You("burn to a crisp...");
2487. 	done(BURNING);
2488. 	if (!safe_teleds())
2489. 		while (1) {
2490. 			pline("You're still burning.");
2491. 			done(BURNING);
2492. 		}
2493. 	You("find yourself back on solid ground.");
2494. 	return(TRUE);
2495.     }
2496. 
2497.     if (!Wwalking) {
2498. 	u.utrap = rn1(4, 4) + (rn1(4, 12) << 8);
2499. 	u.utraptype = TT_LAVA;
2500. 	You("sink into the lava, but it doesn't burn you!");
2501.     }
2502.     /* just want to burn boots, not all armor; destroy_item doesn't work on
2503.        armor anyway */
2504. burn_stuff:
2505.     if(uarmf && !uarmf->oerodeproof && is_organic(uarmf)) {
2506. 	/* save uarmf value because Boots_off() sets uarmf to NULL */
2507. 	obj = uarmf;
2508. 	Your("%s burst into flame!", xname(obj));
2509. 	(void) Boots_off();
2510. 	useup(obj);
2511.     }
2512.     destroy_item(SCROLL_CLASS, AD_FIRE);
2513.     destroy_item(SPBOOK_CLASS, AD_FIRE);
2514.     destroy_item(POTION_CLASS, AD_FIRE);
2515.     return(FALSE);
2516. }
2517. 
2518. #endif /* OVLB */
2519. 
2520. /*trap.c*/