Source:Hack 1.0/hack.trap.c

From NetHackWiki
Jump to: navigation, search

Below is the full text to hack.trap.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.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.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
2.    
3.    #include	"hack.h"
4.    #include	"def.trap.h"
5.    
6.    extern struct monst *makemon();
7.    
8.    char vowels[] = "aeiou";
9.    
10.   char *traps[] = {
11.   	" bear trap",
12.   	"n arrow trap",
13.   	" dart trap",
14.   	" trapdoor",
15.   	" teleportation trap",
16.   	" pit",
17.   	" sleeping gas trap",
18.   	" piercer",
19.   	" mimic"
20.   };
21.   
22.   dotrap(trap) register struct gen *trap; {
23.   	nomul(0);
24.   	if(trap->gflag&SEEN && !rn2(5))
25.   		pline("You escape a%s.",traps[trap->gflag&037]);
26.   	else {
27.   		trap->gflag |= SEEN;
28.   		switch(trap->gflag & ~SEEN) {
29.   		case SLP_GAS_TRAP:
30.   			pline("A cloud of gas puts you to sleep!");
31.   			nomul(-rnd(25));
32.   			break;
33.   		case BEAR_TRAP:
34.   			if(Levitation) {
35.   				pline("You float over a bear trap.");
36.   				break;
37.   			}
38.   			u.utrap = 4 + rn2(4);
39.   			u.utraptype = TT_BEARTRAP;
40.   			pline("A bear trap closes on your foot!");
41.   			break;
42.   		case PIERC:
43.   			deltrap(trap);
44.   			if(makemon(PM_PIERC,u.ux,u.uy)) {
45.   			  pline("A piercer suddenly drops from the ceiling!");
46.   			  if(uarmh)
47.   				pline("Its blow glances off your helmet.");
48.   			  else
49.   				(void) thitu(3,d(4,6),"falling piercer");
50.   			}
51.   			break;
52.   		case ARROW_TRAP:
53.   			pline("An arrow shoots out at you!");
54.   			if(!thitu(8,rnd(6),"arrow")){
55.   				mksobj_at(WEAPON_SYM, ARROW, u.ux, u.uy);
56.   				fobj->quan = 1;
57.   			}
58.   			break;
59.   		case TRAPDOOR:
60.   			if(!xdnstair) {
61.   pline("A trap door in the ceiling opens and a rock falls on your head!");
62.   if(uarmh) pline("Fortunately, you are wearing a helmet!");
63.   			losehp(uarmh ? 2 : d(2,10),"falling rock");
64.   			} else {
65.   			    register int newlevel = dlevel + 1;
66.   				while(!rn2(4) && newlevel < 29)
67.   					newlevel++;
68.   				pline("A trap door opens up under you!");
69.   				if(Levitation || u.ustuck) {
70.    				pline("For some reason you don't fall in.");
71.   					break;
72.   				}
73.   
74.   				goto_level(newlevel, FALSE);
75.   			}
76.   			break;
77.   		case DART_TRAP:
78.   			pline("A little dart shoots out at you!");
79.   			if(thitu(7,rnd(3),"little dart")) {
80.   			    if(!rn2(6))
81.   				poisoned("dart","poison dart");
82.   			} else {
83.   				mksobj_at(WEAPON_SYM, DART, u.ux, u.uy);
84.   				fobj->quan = 1;
85.   			}
86.   			break;
87.   		case TELEP_TRAP:
88.   			newsym(u.ux,u.uy);
89.   			tele();
90.   			break;
91.   		case PIT:
92.   			if(Levitation) {
93.   				pline("A pit opens up under you!");
94.   				pline("You don't fall in!");
95.   				break;
96.   			}
97.   			pline("You fall into a pit!");
98.   			u.utrap = rn1(6,2);
99.   			u.utraptype = TT_PIT;
100.  			losehp(rnd(6),"fall into a pit");
101.  			selftouch("Falling, you");
102.  			break;
103.  		default:
104.  			pline("You hit a trap of type %d",trap->gflag);
105.  			impossible();
106.  		}
107.  	}
108.  }
109.  
110.  mintrap(mtmp) register struct monst *mtmp; {
111.  	register struct gen *gen = g_at(mtmp->mx, mtmp->my, ftrap);
112.  	register int wasintrap = mtmp->mtrapped;
113.  
114.  	if(!gen) {
115.  		mtmp->mtrapped = 0;	/* perhaps teleported? */
116.  	} else if(wasintrap) {
117.   if(!rn2(40)) mtmp->mtrapped = 0;
118.  	} else {
119.  	    register int tt = (gen->gflag & ~SEEN);
120.  	    int in_sight = cansee(mtmp->mx,mtmp->my);
121.  	    extern char mlarge[];
122.  	    if(mtmp->mtrapseen & (1 << tt)) {
123.  		/* he has been in such a trap - perhaps he escapes */
124.  		if(rn2(4)) return(0);
125.  	    }
126.  	    mtmp->mtrapseen |= (1 << tt);
127.  	    switch (tt) {
128.  		case BEAR_TRAP:
129.  			if(index(mlarge, mtmp->data->mlet)) {
130.  				if(in_sight)
131.  				  pline("%s is caught in a bear trap!",
132.  					Monnam(mtmp));
133.  				else
134.  				  if(mtmp->data->mlet == 'o')
135.  			    pline("You hear the roaring of an angry bear!");
136.  				mtmp->mtrapped = 1;
137.  			}
138.  			break;
139.  		case PIT:
140.  			if(!index("Eyw", mtmp->data->mlet)) {
141.  				mtmp->mtrapped = 1;
142.  				if(in_sight)
143.  				  pline("%s falls in a pit!", Monnam(mtmp));
144.  			}
145.  			break;
146.  		case SLP_GAS_TRAP:
147.  			if(!mtmp->msleep && !mtmp->mfroz) {
148.  				mtmp->msleep = 1;
149.  				if(in_sight)
150.  				  pline("%s suddenly falls asleep!",
151.  					Monnam(mtmp));
152.  			}
153.  			break;
154.  		case TELEP_TRAP:
155.  			rloc(mtmp);
156.  			if(in_sight && !cansee(mtmp->mx,mtmp->my))
157.  				pline("%s suddenly disappears!",
158.  					Monnam(mtmp));
159.  			break;
160.  		case ARROW_TRAP:
161.  			if(in_sight) {
162.  				pline("%s is hit by an arrow!",
163.  					Monnam(mtmp));
164.  			}
165.  			mtmp->mhp -= 3;
166.  			break;
167.  		case DART_TRAP:
168.  			if(in_sight) {
169.  				pline("%s is hit by a dart!",
170.  					Monnam(mtmp));
171.  			}
172.  			mtmp->mhp -= 2;
173.  			/* not mondied here !! */
174.  			break;
175.  		case TRAPDOOR:
176.  			if(!xdnstair) {
177.  				mtmp->mhp -= 10;
178.  				if(in_sight)
179.  pline("A trap door in the ceiling opens and a rock hits %s!", monnam(mtmp));
180.  				break;
181.  			}
182.  			if(mtmp->data->mlet != 'w'){
183.  				fall_down(mtmp);
184.  				if(in_sight)
185.  		pline("Suddenly, %s disappears out of sight.", monnam(mtmp));
186.  				return(2);	/* no longer on this level */
187.  			}
188.  			break;
189.  		case PIERC:
190.  			break;
191.  		default:
192.  			pline("Some monster encountered an impossible trap.");
193.  			impossible();
194.  	    }
195.  	}
196.   return(mtmp->mtrapped);
197.  }
198.  
199.  selftouch(arg) char *arg; {
200.  	if(uwep && uwep->otyp == DEAD_COCKATRICE){
201.  		pline("%s touch the dead cockatrice.", arg);
202.  		pline("You turn to stone.");
203.  		killer = objects[uwep->otyp].oc_name;
204.  		done("died");
205.  	}
206.  }
207.  
208.  float_up(){
209.  	if(u.utrap) {
210.  		if(u.utraptype == TT_PIT) {
211.  			u.utrap = 0;
212.  			pline("You float up, out of the pit!");
213.  		} else {
214.   pline("You float up, only your leg is still stuck.");
215.  		}
216.  	} else
217.   pline("You start to float in the air!");
218.  }
219.  
220.  float_down(){
221.  	register struct gen *trap;
222.  	pline("You float gently to the ground.");
223.  	if(trap = g_at(u.ux,u.uy,ftrap))
224.  		switch(trap->gflag & 037) {
225.  		case PIERC:
226.  			break;
227.  		case TRAPDOOR:
228.  			if(!xdnstair || u.ustuck) break;
229.  			/* fall into next case */
230.  		default:
231.  			dotrap(trap);
232.  	}
233.   pickup();
234.  }
235.  
236.  tele()
237.  {
238.  extern coord getpos();
239.  coord cc;
240.  register int nux,nuy;
241.  	if(Teleport_control) {
242.  		pline("To what position do you want to be teleported?");
243.  		cc = getpos(1, "the desired position"); /* 1: force valid */
244.  		/* possible extensions: introduce a small error if
245.  		   magic power is low; allow transfer to solid rock */
246.  		if(teleok(cc.x, cc.y)){
247.  			nux = cc.x;
248.  			nuy = cc.y;
249.  			goto gotpos;
250.  		}
251.   pline("Sorry ...");
252.  	}
253.  	do {
254.  		nux = rnd(COLNO-1);
255.  		nuy = rn2(ROWNO);
256.  	} while(!teleok(nux, nuy));
257.  gotpos:
258.  	if(Punished) unplacebc();
259.  	unsee();
260.  	u.utrap = 0;
261.  	u.ustuck = 0;
262.  	u.ux = nux;
263.  	u.uy = nuy;
264.  	setsee();
265.  	if(Punished) placebc(1);
266.  	if(u.uswallow){
267.  		u.uswldtim = u.uswallow = 0;
268.  		docrt();
269.  	}
270.  	nomul(0);
271.  	(void) inshop();
272.  	pickup();
273.  	if(!Blind) read_engr_at(u.ux,u.uy);
274.  }
275.  
276.  teleok(x,y) register int x,y; {
277.  	return( isok(x,y) && levl[x][y].typ > DOOR && !m_at(x,y) &&
278.  		!sobj_at(ENORMOUS_ROCK,x,y) && !g_at(x,y,ftrap)
279.  	);
280.  	/* Note: gold is permitted (because of vaults) */
281.  }
282.  
283.  placebc(attach) int attach; {
284.  	if(!uchain || !uball){
285.  		pline("Where are your chain and ball??");
286.  		impossible();
287.  		return;
288.  	}
289.  	uball->ox = uchain->ox = u.ux;
290.  	uball->oy = uchain->oy = u.uy;
291.  	if(attach){
292.  		uchain->nobj = fobj;
293.  		fobj = uchain;
294.  		if(!carried(uball)){
295.  			uball->nobj = fobj;
296.  			fobj = uball;
297.  		}
298.  	}
299.  }
300.  
301.  unplacebc(){
302.  	if(!carried(uball)){
303.  		freeobj(uball);
304.  		unpobj(uball);
305.  	}
306.  	freeobj(uchain);
307.  	unpobj(uchain);
308.  }
309.  
310.  level_tele() {
311.  register int newlevel = 5 + rn2(20);	/* 5 - 24 */
312.  	if(dlevel == newlevel)
313.  		if(!xdnstair) newlevel--; else newlevel++;
314.  	goto_level(newlevel, FALSE);
315.  }