Source:NetHack 2.3e/trap.c

From NetHackWiki
Jump to navigation Jump to search

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

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

Screenshots and source code from Hack are used under the CWI license.

1.    /*	SCCS Id: @(#)trap.c	2.3	87/12/16
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    
4.    #include	<stdio.h>
5.    #include	"hack.h"
6.    
7.    extern struct monst *makemon();
8.    extern struct obj *mksobj_at();
9.    
10.   #ifdef KAA
11.   extern char *Xmonnam();
12.   extern char *nomovemsg;
13.   #endif
14.   
15.   char vowels[] = "aeiou";
16.   
17.   char *traps[] = {
18.   	"",
19.   	" bear trap",
20.   	"n arrow trap",
21.   	" dart trap",
22.   	" trapdoor",
23.   	" teleportation trap",
24.   	" pit",
25.   	" sleeping gas trap",
26.   	" piercer",
27.   	" mimic"
28.   #ifdef NEWTRAPS
29.   	," magic trap"
30.   	," squeaky board"
31.   #endif
32.   #ifdef SPIDERS
33.   	," web"
34.   #endif
35.   #ifdef NEWCLASS
36.   	," spiked pit"
37.   	," level teleporter"
38.   #endif
39.   #ifdef SPELLS
40.   	," anti-magic field" 
41.   #endif
42.   #ifdef KAA
43.   	," rust trap"
44.   # ifdef RPH
45.   	," polymorph trap"
46.   # endif
47.   #endif
48.   #ifdef SAC
49.   	," land mine"
50.   #endif
51.   };
52.   
53.   struct trap *
54.   maketrap(x,y,typ)
55.   register x,y,typ;
56.   {
57.   	register struct trap *ttmp;
58.   
59.   	ttmp = newtrap();
60.   	ttmp->ttyp = typ;
61.   	ttmp->tseen = 0;
62.   	ttmp->once = 0;
63.   	ttmp->tx = x;
64.   	ttmp->ty = y;
65.   	ttmp->ntrap = ftrap;
66.   	ftrap = ttmp;
67.   	return(ttmp);
68.   }
69.   
70.   dotrap(trap) register struct trap *trap; {
71.   	register int ttype = trap->ttyp;
72.   	register struct monst *mtmp;
73.   
74.   	nomul(0);
75.   	if(trap->tseen && !rn2(5) && !(ttype == PIT
76.   #ifdef NEWCLASS
77.   	   || ttype == SPIKED_PIT
78.   #endif
79.   #ifdef SPELLS
80.   	   || ttype == ANTI_MAGIC
81.   #endif
82.   		))
83.   		pline("You escape a%s.", traps[ttype]);
84.   	else {
85.   		trap->tseen = 1;
86.   		switch(ttype) {
87.   		case SLP_GAS_TRAP:
88.   			pline("A cloud of gas puts you to sleep!");
89.   			nomul(-rnd(25));
90.   			break;
91.   		case BEAR_TRAP:
92.   			if(Levitation) {
93.   				pline("You float over a bear trap.");
94.   				break;
95.   			}
96.   			u.utrap = 4 + rn2(4);
97.   			u.utraptype = TT_BEARTRAP;
98.   			pline("A bear trap closes on your foot!");
99.   			if(u.usym=='o') pline("You howl in anger!");
100.  			break;
101.  		case PIERC:
102.  			deltrap(trap);
103.  			if(mtmp=makemon(PM_PIERCER,u.ux,u.uy)) {
104.  			  pline("%s suddenly drops from the ceiling!", Xmonnam(mtmp));
105.  			  if(uarmh)
106.  				pline("Its blow glances off your helmet.");
107.  			  else
108.  				(void) thitu(3,d(4,6),"falling piercer");
109.  			}
110.  			break;
111.  		case ARROW_TRAP:
112.  			pline("An arrow shoots out at you!");
113.  			if(!thitu(8,rnd(6),"arrow")){
114.  				mksobj_at(ARROW, u.ux, u.uy);
115.  				fobj->quan = 1;
116.  			}
117.  			break;
118.  		case TRAPDOOR:
119.  			if(!xdnstair) {
120.  pline("A trap door in the ceiling opens and a rock falls on your head!");
121.  if(uarmh) pline("Fortunately, you are wearing a helmet!");
122.  			    losehp(uarmh ? 2 : d(2,10),"falling rock");
123.  			    mksobj_at(ROCK, u.ux, u.uy);
124.  			    fobj->quan = 1;
125.  			    stackobj(fobj);
126.  			    if(Invisible) newsym(u.ux, u.uy);
127.  			} else {
128.  			    register int newlevel = dlevel + 1;
129.  				while(!rn2(4) && newlevel < 29)
130.  					newlevel++;
131.  				pline("A trap door opens up under you!");
132.  				if(Levitation || u.ustuck) {
133.  				pline("For some reason you don't fall in.");
134.  					break;
135.  				}
136.  				fflush(stdout);
137.  				goto_level(newlevel, FALSE);
138.  			}
139.  			break;
140.  		case DART_TRAP:
141.  			pline("A little dart shoots out at you!");
142.  			if(thitu(7,rnd(3),"little dart")) {
143.  			    if(!rn2(6))
144.  				poisoned("dart","poison dart");
145.  			} else {
146.  				mksobj_at(DART, u.ux, u.uy);
147.  				fobj->quan = 1;
148.  			}
149.  			break;
150.  		case TELEP_TRAP:
151.  			if(trap->once) {
152.  				deltrap(trap);
153.  				newsym(u.ux,u.uy);
154.  				vtele();
155.  			} else {
156.  				newsym(u.ux,u.uy);
157.  				tele();
158.  			}
159.  			break;
160.  #ifdef KAA
161.  		case RUST_TRAP:
162.  			switch (rn2(5)) {
163.  			case 0:
164.  				pline("A gush of water hits you on the head!");
165.  				if (uarmh) {
166.  				    if (uarmh->rustfree)
167.  					pline("Your helmet is not affected!");
168.  				    else if (uarmh->spe > -6) {
169.  					pline("Your helmet rusts!");
170.  					uarmh->spe--;
171.  				    } else
172.  					pline("Your helmet looks quite rusted now.");
173.  				}
174.  				break;
175.  			case 1:
176.  				pline("A gush of water hits your left arm!");
177.  				if (uarms) {
178.  					pline("Your shield is not affected!");
179.  					break;
180.  				}
181.  				if (uwep && uwep->otyp == TWO_HANDED_SWORD) goto two_hand;
182.  				/* Two goto statements in a row--aaarrrgggh! */
183.  		glovecheck: if(uarmg) pline("Your gloves are not affected!");
184.  				break;
185.  			case 2:
186.  				pline("A gush of water hits your right arm!");
187.  		two_hand: corrode_weapon();
188.  				goto glovecheck;
189.  			default:
190.  				pline("A gush of water hits you!");
191.  				if (uarm) {
192.  				    if (uarm->rustfree ||
193.  					uarm->otyp >= STUDDED_LEATHER_ARMOR) 
194.  					    pline("Your %s not affected!",
195.  						  aobjnam(uarm,"are"));
196.  				    else if(uarm->spe > -6) {
197.  					    pline("Your %s!",
198.  						  aobjnam(uarm,"corrode"));
199.  					    uarm->spe--;
200.  				    } else
201.  					    pline("Your %s quite rusted now.",
202.  						  aobjnam(uarm, "look"));
203.  				}
204.  			}
205.  			break;
206.  #endif
207.  		case PIT:
208.  			if (Levitation || index("EyBfk'&",u.usym)) {
209.  				pline("A pit opens up under you!");
210.  				pline("You don't fall in!");
211.  				break;
212.  			}
213.  			pline("You fall into a pit!");
214.  			u.utrap = rn1(6,2);
215.  			u.utraptype = TT_PIT;
216.  			losehp(rnd(6),"fall into a pit");
217.  			selftouch("Falling, you");
218.  			break;
219.  #ifdef NEWCLASS
220.  		case SPIKED_PIT:
221.  			if (Levitation || index("EyBfk'&",u.usym)) {
222.  				pline("A pit opens up under you!");
223.  				pline("You don't fall in!");
224.  				pline("There are spikes in that pit!!!");
225.  				break;
226.  			}
227.  			pline("You fall into a pit!");
228.  			pline("You land on a set of sharp iron spikes!");
229.  			u.utrap = rn1(6,2);
230.  			u.utraptype = TT_PIT;
231.  			losehp(rnd(10),"fall onto iron spikes");
232.  			if(!rn2(6)) poisoned("spikes","poison spikes");
233.  			selftouch("Falling, you");
234.  			break;
235.  		case LEVEL_TELEP:
236.  			if (!Blind)	pline("You are momentarily blinded by a flash of light");
237.  			else		pline("You are momentarily disoriented.");
238.  			deltrap(trap);
239.  			newsym(u.ux,u.uy);
240.  			level_tele();
241.  			break;
242.  #endif
243.  #ifdef SPELLS
244.  		case ANTI_MAGIC:
245.  			pline("You feel your magical energy drain away!");
246.  			u.uen -= (rnd(u.ulevel) + 1);
247.  			if(u.uen < 0)  {
248.  				u.uenmax += u.uen;
249.  				if(u.uenmax < 0) u.uenmax = 0;
250.  				u.uen = 0;
251.  			}
252.  			flags.botl = 1;
253.  			break;
254.  #endif
255.  #if defined(RPH) && defined(KAA)
256.  		case POLY_TRAP:
257.  			    pline("You feel a change coming over you.");
258.  			    polyself();
259.  			    deltrap(trap);
260.  			    break;
261.  #endif
262.  #ifdef NEWTRAPS
263.  		case MGTRP:
264.  			/* A magic trap. */
265.  			domagictrap();
266.  			break;
267.  		case SQBRD: {
268.  #include      "edog.h"
269.  			register struct monst *mtmp = fmon;
270.  			/* Stepped on a squeaky board. */
271.  			pline("A board underfoot gives off a loud squeak!");
272.  			/* Wake up nearby monsters. */
273.  		       while(mtmp) {
274.  			 if(dist(mtmp->mx,mtmp->my) < u.ulevel*20) {
275.  			       if(mtmp->msleep)
276.  				       mtmp->msleep = 0;
277.  			       if(mtmp->mtame)
278.  				       EDOG(mtmp)->whistletime = moves;
279.  			 }
280.  			 mtmp = mtmp->nmon;
281.  		       }
282.  		}
283.  			break;
284.  #endif
285.  #ifdef SPIDERS
286.  	       case WEB:
287.  
288.  		       /* Our luckless adventurer has stepped into a web. */
289.  
290.  		       pline("You've stumbled into a spider web!");
291.  		       u.utraptype = TT_WEB;
292.  
293.  		       /* Time stuck in the web depends on your strength. */
294.  
295.  		       if (u.ustr == 3) u.utrap = rn1(6,6);
296.  		       else if (u.ustr < 6) u.utrap = rn1(6,4);
297.  		       else if (u.ustr < 9) u.utrap = rn1(4,4);
298.  		       else if (u.ustr < 12) u.utrap = rn1(4,2);
299.  		       else if (u.ustr < 15) u.utrap = rn1(2,2);
300.  		       else if (u.ustr < 18) u.utrap = rnd(2);
301.  		       else if (u.ustr < 69) u.utrap = 1;
302.  		       else {
303.  			       u.utrap = 0;
304.  			       pline("You tear through the web!");
305.  			       deltrap(trap);
306.  			    }
307.  		       break;
308.  #endif
309.  #ifdef SAC
310.  		case LANDMINE: {
311.  			register struct monst *mtmp = fmon;
312.  
313.  			pline("KAABLAMM!!!  You stepped on a land mine!");
314.  			losehp(rnd(16), "land mine");
315.  			set_wounded_legs(LEFT_SIDE, 40 + rnd(35));
316.  			set_wounded_legs(RIGHT_SIDE, 40 + rnd(35));
317.  			/* wake everything on the level */
318.  			while(mtmp) {
319.  				if(mtmp->msleep)
320.  					mtmp->msleep = 0;
321.  				mtmp = mtmp->nmon;
322.  			}
323.  			deltrap(t_at(u.ux, u.uy)); /* mines only explode once */
324.  			break;
325.  		}
326.  #endif /* SAC */
327.  		default:
328.  			impossible("You hit a trap of type %u", trap->ttyp);
329.  		}
330.  	}
331.  }
332.  
333.  mintrap(mtmp) register struct monst *mtmp; {
334.  	register struct trap *trap = t_at(mtmp->mx, mtmp->my);
335.  	register int wasintrap = mtmp->mtrapped;
336.  
337.  	if(!trap) {
338.  		mtmp->mtrapped = 0;	/* perhaps teleported? */
339.  	} else if(wasintrap) {
340.  		if(!rn2(40)) mtmp->mtrapped = 0;
341.  	} else {
342.  	    register int tt = trap->ttyp;
343.  #ifdef DGK
344.  	/* A bug fix for dumb messages by ab@unido.
345.  	 */
346.  	    int in_sight = cansee(mtmp->mx,mtmp->my)
347.  			   && (!mtmp->minvis || See_invisible);
348.  #else
349.  	    int in_sight = cansee(mtmp->mx,mtmp->my);
350.  #endif
351.  	    extern char mlarge[];
352.  
353.  	    if(mtmp->mtrapseen & (1 << tt)) {
354.  		/* he has been in such a trap - perhaps he escapes */
355.  		if(rn2(4)) return(0);
356.  	    }
357.  	    mtmp->mtrapseen |= (1 << tt);
358.  	    switch (tt) {
359.  		case BEAR_TRAP:
360.  			if(index(mlarge, mtmp->data->mlet)) {
361.  				if(in_sight)
362.  				  pline("%s is caught in a bear trap!",
363.  					Monnam(mtmp));
364.  				else
365.  				  if(mtmp->data->mlet == 'o')
366.  			    pline("You hear the roaring of an angry bear!");
367.  				mtmp->mtrapped = 1;
368.  			}
369.  			break;
370.  #ifdef KAA
371.  # ifdef RPH
372.    		case POLY_TRAP:
373.  		    if(!resist(mtmp, '/', 0, NOTELL))
374.  			newcham(mtmp,&mons[rn2(CMNUM)]);
375.  		    break;
376.  # endif
377.  		case RUST_TRAP:
378.  			if(in_sight)
379.  				pline("A gush of water hits %s!",monnam(mtmp));
380.  			break;
381.  #endif
382.  		case PIT:
383.  #ifdef NEWCLASS
384.  		case SPIKED_PIT:
385.  #endif
386.  			/* there should be a mtmp/data -> floating */
387.  			if(!index("EywBIfk'& ", mtmp->data->mlet)) { /* ab */
388.  				mtmp->mtrapped = 1;
389.  				if(in_sight)
390.  				  pline("%s falls into a pit!", Monnam(mtmp));
391.  			}
392.  			break;
393.  		case SLP_GAS_TRAP:
394.  			if(!mtmp->msleep && !mtmp->mfroz) {
395.  				mtmp->msleep = 1;
396.  				if(in_sight)
397.  				  pline("%s suddenly falls asleep!",
398.  					Monnam(mtmp));
399.  			}
400.  			break;
401.  		case TELEP_TRAP:
402.  #ifdef NEWCLASS
403.  		case LEVEL_TELEP:
404.  #endif
405.  			rloc(mtmp);
406.  			if(in_sight && !cansee(mtmp->mx,mtmp->my))
407.  				pline("%s suddenly disappears!",
408.  					Monnam(mtmp));
409.  			break;
410.  		case ARROW_TRAP:
411.  			if(in_sight)
412.  				pline("%s is hit by an arrow!",	Monnam(mtmp));
413.  			mtmp->mhp -= 3;
414.  			break;
415.  		case DART_TRAP:
416.  			if(in_sight)
417.  				pline("%s is hit by a dart!", Monnam(mtmp));
418.  			mtmp->mhp -= 2;
419.  			/* not mondied here !! */
420.  			break;
421.  		case TRAPDOOR:
422.  			if(!xdnstair) {
423.  				mtmp->mhp -= 10;
424.  				if(in_sight)
425.  pline("A trap door in the ceiling opens and a rock hits %s!", monnam(mtmp));
426.  				break;
427.  			}
428.  			if(!index("EywBIfk", mtmp->data->mlet)){
429.  				fall_down(mtmp);
430.  				if(in_sight)
431.  		pline("Suddenly, %s disappears out of sight.", monnam(mtmp));
432.  				return(2);	/* no longer on this level */
433.  			}
434.  			break;
435.  		case PIERC:
436.  			break;
437.  #ifdef NEWTRAPS
438.  		case MGTRP:
439.  			/* A magic trap.  Monsters immune. */
440.  			break;
441.  		case SQBRD: {
442.  			register struct monst *ztmp = fmon;
443.  			
444.  			if(index("EyBIfk", mtmp->data->mlet)) break;
445.  			/* Stepped on a squeaky board. */
446.  			if (in_sight)
447.  			   pline("%s steps on a squeaky board.", Monnam(mtmp));
448.  			else
449.  			   pline("You hear a distant squeak.");
450.  			/* Wake up nearby monsters. */
451.  		       while(ztmp) {
452.  			 if(dist2(mtmp->mx,mtmp->my,ztmp->mx,ztmp->my) < 40)
453.  			       if(ztmp->msleep) ztmp->msleep = 0;
454.  			 ztmp = ztmp->nmon;
455.  		       }
456.  			break;
457.  		}
458.  #endif
459.  #ifdef SPIDERS
460.  	       case WEB:
461.  		       /* Monster in a web. */
462.  			/* in_sight check and confused bear by Eric Backus */
463.  		       if(mtmp->data->mlet != 's') {
464.  			 if(in_sight)
465.  				pline("%s is caught in a web!", Monnam(mtmp));
466.  			  else
467.  			    if(mtmp->data->mlet == 'o')
468.  			      pline("You hear the roaring of a confused bear!");
469.  			 mtmp->mtrapped = 1;
470.  		       }
471.  		      break;
472.  #endif
473.  #ifdef SPELLS
474.  		case ANTI_MAGIC:	break;
475.  #endif
476.  #ifdef SAC
477.  		case LANDMINE: {
478.  			register struct monst *mntmp = fmon;
479.  
480.  			if(rn2(3))
481.  				break; /* monsters usually don't set it off */
482.  			if(in_sight)
483.  				pline("KAABLAMM!!! %s steps on a land mine!",
484.  				      Monnam(mtmp));
485.  			else
486.  				pline("Kaablamm! You hear an explosion in the distance!");
487.  			mtmp->mhp -= rn2(16);
488.  			deltrap(t_at(mtmp->mx, mtmp->my));
489.  			/* wake everything on the level */
490.  			while(mntmp) {
491.  				if(mntmp->msleep)
492.  					mntmp->msleep = 0;
493.  				mntmp = mntmp->nmon;
494.  			}
495.  			break;
496.  		}
497.  #endif
498.  		default:
499.  			impossible("Some monster encountered a strange trap of type %d.",tt);
500.  	    }
501.  	}
502.  	return(mtmp->mtrapped);
503.  }
504.  
505.  selftouch(arg) char *arg; {
506.  	if(uwep && uwep->otyp == DEAD_COCKATRICE){
507.  		pline("%s touch the dead cockatrice.", arg);
508.  		pline("You turn to stone.");
509.  		pline("You die...");
510.  		killer = objects[uwep->otyp].oc_name;
511.  		done("died");
512.  	}
513.  }
514.  
515.  float_up(){
516.  	if(u.utrap) {
517.  		if(u.utraptype == TT_PIT) {
518.  			u.utrap = 0;
519.  			pline("You float up, out of the pit!");
520.  		} else {
521.  			pline("You float up, only your leg is still stuck.");
522.  		}
523.  	} else
524.  		if (Hallucination)
525.  			pline("Oh wow!  You're floating in the air!");
526.  		else
527.  			pline("You start to float in the air!");
528.  }
529.  
530.  float_down(){
531.  	register struct trap *trap;
532.  	
533.  	/* check for falling into pool - added by GAN 10/20/86 */
534.  	if(IS_POOL(levl[u.ux][u.uy].typ) && !Levitation)
535.  		drown();
536.  
537.  	pline("You float gently to the ground.");
538.  	if(trap = t_at(u.ux,u.uy))
539.  		switch(trap->ttyp) {
540.  		case PIERC:
541.  			break;
542.  		case TRAPDOOR:
543.  			if(!xdnstair || u.ustuck) break;
544.  			/* fall into next case */
545.  		default:
546.  			dotrap(trap);
547.  	}
548.  	pickup(1);
549.  }
550.  
551.  #include "mkroom.h"
552.  
553.  vtele() {
554.  	register struct mkroom *croom;
555.  
556.  	for(croom = &rooms[0]; croom->hx >= 0; croom++)
557.  	    if(croom->rtype == VAULT) {
558.  		register x,y;
559.  
560.  		x = rn2(2) ? croom->lx : croom->hx;
561.  		y = rn2(2) ? croom->ly : croom->hy;
562.  		if(teleok(x,y)) {
563.  		    teleds(x,y);
564.  		    return;
565.  		}
566.  	    }
567.  	tele();
568.  }
569.  
570.  #ifdef BVH
571.  int has_amulet() {
572.      register struct  obj *otmp;
573.  
574.      for(otmp = invent; otmp; otmp = otmp->nobj)
575.  	if(otmp->olet == AMULET_SYM && otmp->spe >= 0)
576.  	    return(1);
577.      return(0);
578.  }
579.  #endif
580.  
581.  tele() {
582.  	coord cc;
583.  	register int nux,nuy;
584.  
585.  #ifdef BVH
586.  	if(has_amulet() && rn2(3)) {
587.  	    pline("You feel disoriented for a moment.");
588.  	    return;
589.  	}
590.  #endif
591.  	if(Teleport_control) {
592.  #ifdef KAA
593.  	    if (multi < 0 && (!nomovemsg ||
594.  			      !strncmp(nomovemsg,"You awake", 9) ||
595.  			      !strncmp(nomovemsg,"You regain con", 15) ||
596.  			      !strncmp(nomovemsg,"You are consci", 15)))
597.   
598.  		pline("Being unconscious, you cannot control your teleport.");
599.  	    else {
600.  #endif
601.  	
602.  		    pline("To what position do you want to be teleported?");
603.  		    getpos(&cc, 1, "the desired position"); /* 1: force valid */
604.  		    /* possible extensions: introduce a small error if
605.  		       magic power is low; allow transfer to solid rock */
606.  		    if(teleok(cc.x, cc.y)){
607.  			teleds(cc.x, cc.y);
608.  			return;
609.  		    }
610.  		    pline("Sorry ...");
611.  #ifdef KAA
612.  		}
613.  #endif
614.  	}
615.  	do {
616.  		nux = rnd(COLNO-1);
617.  		nuy = rn2(ROWNO);
618.  	} while(!teleok(nux, nuy));
619.  	teleds(nux, nuy);
620.  }
621.  
622.  teleds(nux, nuy)
623.  register int nux,nuy;
624.  {
625.  	if(Punished) unplacebc();
626.  	unsee();
627.  	u.utrap = 0;
628.  	u.ustuck = 0;
629.  	u.ux = nux;
630.  	u.uy = nuy;
631.  	setsee();
632.  	if(Punished) placebc(1);
633.  	if(u.uswallow){
634.  		u.uswldtim = u.uswallow = 0;
635.  		docrt();
636.  	}
637.  	nomul(0);
638.  	if(IS_POOL(levl[nux][nuy].typ) && !Levitation)
639.  		drown();
640.  	(void) inshop();
641.  	pickup(1);
642.  	read_engr_at(u.ux,u.uy);
643.  }
644.  
645.  teleok(x,y) register int x,y; {	/* might throw him into a POOL
646.  				 * removed by GAN 10/20/86
647.  				 */
648.  #ifdef STUPID
649.  	boolean	tmp1, tmp2, tmp3;
650.  	tmp1 = isok(x,y) && !IS_ROCK(levl[x][y].typ) && !m_at(x,y);
651.  	tmp2 = !sobj_at(ENORMOUS_ROCK,x,y) && !t_at(x,y);
652.  	tmp3 = !(IS_POOL(levl[x][y].typ) && !Levitation);
653.  	return(tmp1 && tmp2 && tmp3);
654.  #else
655.  	return( isok(x,y) && !IS_ROCK(levl[x][y].typ) && !m_at(x,y) &&
656.  		!sobj_at(ENORMOUS_ROCK,x,y) && !t_at(x,y) &&
657.  		!(IS_POOL(levl[x][y].typ) && !Levitation)
658.  	);
659.  #endif
660.  	/* Note: gold is permitted (because of vaults) */
661.  }
662.  
663.  dotele() {
664.  	extern char pl_character[];
665.  
666.  	if((!index("LNt",u.usym)) &&
667.  #ifdef WIZARD
668.  	   !wizard &&
669.  #endif
670.  		      (!Teleportation || u.ulevel < 6 ||
671.  			(pl_character[0] != 'W' && u.ulevel < 10))) {
672.  		pline("You are not able to teleport at will.");
673.  		return(0);
674.  	}
675.  	if(u.uhunger <= 100 || u.ustr < 6) {
676.  		pline("You miss the strength for a teleport spell.");
677.  #ifdef WIZARD
678.  		if(!wizard)
679.  #endif
680.  		return(1);
681.  	}
682.  	tele();
683.  	morehungry(100);
684.  	return(1);
685.  }
686.  
687.  placebc(attach) int attach; {
688.  	if(!uchain || !uball){
689.  		impossible("Where are your chain and ball??");
690.  		return;
691.  	}
692.  	uball->ox = uchain->ox = u.ux;
693.  	uball->oy = uchain->oy = u.uy;
694.  	if(attach){
695.  		uchain->nobj = fobj;
696.  		fobj = uchain;
697.  		if(!carried(uball)){
698.  			uball->nobj = fobj;
699.  			fobj = uball;
700.  		}
701.  	}
702.  }
703.  
704.  unplacebc(){
705.  	if(!carried(uball)){
706.  		freeobj(uball);
707.  		unpobj(uball);
708.  	}
709.  	freeobj(uchain);
710.  	unpobj(uchain);
711.  }
712.  
713.  level_tele() {
714.  register int newlevel;
715.  
716.  #ifdef BVH
717.  	if(has_amulet() && rn2(5)) {
718.  	    pline("You feel very disoriented for a moment.");
719.  	    return;
720.  	}
721.  #endif
722.  	if(Teleport_control) {
723.  	    char buf[BUFSZ];
724.  
725.  	    do {
726.  	      pline("To what level do you want to teleport? [type a number] ");
727.  	      getlin(buf);
728.  	    } while(!digit(buf[0]) && (buf[0] != '-' || !digit(buf[1])));
729.  	    newlevel = atoi(buf);
730.  	} else {
731.  #ifdef DGKMOD
732.  	    newlevel = rn2(5) | !Fire_resistance ? rnd(dlevel + 3) : 30;
733.  #else
734.  	    newlevel = rnd(dlevel + 3);			/* 5 - 24 */
735.  #endif
736.  	    if(dlevel == newlevel)
737.  		if(!xdnstair) newlevel--; else newlevel++;
738.  	}
739.  	if(newlevel >= 30) {
740.  	    if(newlevel > MAXLEVEL) newlevel = MAXLEVEL;
741.  	    pline("You arrive at the center of the earth ...");
742.  	    pline("Unfortunately it is here that hell is located.");
743.  #ifdef DGK
744.  	    fflush(stdout);
745.  #endif
746.  	    if(Fire_resistance) {
747.  		pline("But the fire doesn't seem to harm you.");
748.  	    } else {
749.  		pline("You burn to a crisp.");
750.  		pline("You die...");
751.  		dlevel = maxdlevel = newlevel;
752.  		killer = "visit to hell";
753.  		done("burned");
754.  	    }
755.  	}
756.  	if(newlevel < 0) {
757.  		if(newlevel <= -10) {
758.  			pline("You arrive in heaven.");
759.  			pline("\"You are here a bit early, but we'll let you in.\"");
760.  			killer = "visit to heaven";
761.  			done("died");
762.  		} else	if (newlevel == -9) {
763.  			pline("You feel deliriously happy. ");
764.  			pline("(In fact, you're on Cloud 9!) ");
765.  			more();
766.  		} else	newlevel = 0;
767.  	    pline("You are now high above the clouds ...");
768.  	    if(Levitation) {
769.  		pline("You float gently down to earth.");
770.  		done("escaped");
771.  	    }
772.  	    pline("Unfortunately, you don't know how to fly.");
773.  	    pline("You plummet a few thousand feet to your death.");
774.  	    dlevel = 0;
775.  	    killer = "long fall";
776.  	    done("died");
777.  	}
778.  
779.  	goto_level(newlevel, FALSE); /* calls done("escaped") if newlevel==0 */
780.  }
781.  
782.  #ifdef NEWTRAPS
783.  
784.  domagictrap()
785.  {
786.  	register int fate = rnd(20);
787.  
788.  	/* What happened to the poor sucker? */
789.  
790.  	if (fate < 10) {
791.  
792.  	  /* Most of the time, it creates some monsters. */
793.  	  register int cnt = rnd(4);
794.  
795.  	  /* below checks for blindness added by GAN 10/30/86 */
796.  	  if (!Blind)  {
797.  		pline("You are momentarily blinded by a flash of light!");
798.  		Blinded += rn1(5,10);
799.  		seeoff(0);
800.  	  }  else
801.  		pline("You hear a deafening roar!");
802.  	  while(cnt--)
803.  	   (void) makemon((struct permonst *) 0, u.ux, u.uy);
804.  	}
805.  	else
806.  	  switch (fate) {
807.  
808.  	     case 10:
809.  	     case 11:
810.  		      /* sometimes nothing happens */
811.  			break;
812.  	     case 12:
813.  		      /* a flash of fire */
814.  		      {
815.  			register int num;
816.  			
817.  			/* changed to be in conformance with
818.  			 * SCR_FIRE by GAN 11/02/86
819.  			 */
820.  			
821.  			pline("A tower of flame bursts from the floor!");
822.  			if(Fire_resistance)
823.  				pline("You are uninjured.");
824.  			else {
825.  				num = rnd(6);
826.  				u.uhpmax -= num;
827.  				losehp(num,"a burst of flame");
828.  				break;
829.  			}
830.  		      }
831.  
832.  	     /* odd feelings */
833.  	     case 13:   pline("A shiver runs up and down your spine!");
834.  			break;
835.  	     case 14:   pline("You hear distant howling.");
836.  			break;
837.  	     case 15:   pline("You suddenly yearn for your distant homeland.");
838.  			break;
839.  	     case 16:   pline("Your pack shakes violently!");
840.  			break;
841.  
842.  	     /* very occasionally something nice happens. */
843.  
844.  	     case 19:
845.  		    /* tame nearby monsters */
846.  		   {   register int i,j;
847.  		       register boolean confused = (Confusion != 0);
848.  		       register int bd = confused ? 5 : 1;
849.  		       register struct monst *mtmp;
850.  
851.  		       /* below pline added by GAN 10/30/86 */
852.  		       pline("You feel charismatic.");
853.  		       for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
854.  		       if(mtmp = m_at(u.ux+i, u.uy+j))
855.  			       (void) tamedog(mtmp, (struct obj *) 0);
856.  		       break;
857.  		   }
858.  
859.  	     case 20:
860.  		    /* uncurse stuff */
861.  		   {  register struct obj *obj;
862.  		      register boolean confused = (Confusion != 0);
863.  
864.  			/* below plines added by GAN 10/30/86 */
865.  			if (confused)
866.  			    if (Hallucination)
867.  				pline("You feel the power of the Force against you!");
868.  			    else
869.  				pline("You feel like you need some help.");
870.  			else
871.  			    if (Hallucination)
872.  				pline("You feel in touch with the Universal Oneness.");
873.  			    else
874.  				pline("You feel like someone is helping you.");
875.  		       for(obj = invent; obj ; obj = obj->nobj)
876.  			       if(obj->owornmask)
877.  				       obj->cursed = confused;
878.  		       if(Punished && !confused) {
879.  			       Punished = 0;
880.  			       freeobj(uchain);
881.  			       unpobj(uchain);
882.  			       free((char *) uchain);
883.  			       uball->spe = 0;
884.  			       uball->owornmask &= ~W_BALL;
885.  			       uchain = uball = (struct obj *) 0;
886.  		       }
887.  		       break;
888.  		   }
889.  	     default: break;
890.  	  }
891.  }
892.  #endif /* NEWTRAPS /**/
893.  
894.  drown()
895.  {
896.  	pline("You fall into a pool!");
897.  	pline("You can't swim!");
898.  	if(
899.  #ifdef WIZARD
900.  	wizard ||
901.  #endif
902.  	rn2(3) < u.uluck+2) {
903.  		/* most scrolls become unreadable */
904.  		register struct obj *obj;
905.  
906.  		for(obj = invent; obj; obj = obj->nobj)
907.  			if(obj->olet == SCROLL_SYM && rn2(12) > u.uluck)
908.  				obj->otyp = SCR_BLANK_PAPER;
909.  		/* we should perhaps merge these scrolls ? */
910.  
911.  		pline("You attempt a teleport spell.");	/* utcsri!carroll */
912.  		(void) dotele();
913.  		if(!IS_POOL(levl[u.ux][u.uy].typ)) return;
914.  	}
915.  	pline("You drown.");
916.  	pline("You die...");
917.  	killer = "pool of water";
918.  	done("drowned");
919.  }