]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.trap.c
Add RCS identifiers, remove some completely useless RCS logs and patchkit
[bsdgames-darwin.git] / hack / hack.trap.c
1 /*
2 * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
3 */
4
5 #ifndef lint
6 static char rcsid[] = "$Id: hack.trap.c,v 1.2 1993/08/02 17:19:32 mycroft Exp $";
7 #endif /* not lint */
8
9 #include "hack.h"
10
11 extern struct monst *makemon();
12
13 char vowels[] = "aeiou";
14
15 char *traps[] = {
16 " bear trap",
17 "n arrow trap",
18 " dart trap",
19 " trapdoor",
20 " teleportation trap",
21 " pit",
22 " sleeping gas trap",
23 " piercer",
24 " mimic"
25 };
26
27 struct trap *
28 maketrap(x,y,typ)
29 register x,y,typ;
30 {
31 register struct trap *ttmp;
32
33 ttmp = newtrap();
34 ttmp->ttyp = typ;
35 ttmp->tseen = 0;
36 ttmp->once = 0;
37 ttmp->tx = x;
38 ttmp->ty = y;
39 ttmp->ntrap = ftrap;
40 ftrap = ttmp;
41 return(ttmp);
42 }
43
44 dotrap(trap) register struct trap *trap; {
45 register int ttype = trap->ttyp;
46
47 nomul(0);
48 if(trap->tseen && !rn2(5) && ttype != PIT)
49 pline("You escape a%s.", traps[ttype]);
50 else {
51 trap->tseen = 1;
52 switch(ttype) {
53 case SLP_GAS_TRAP:
54 pline("A cloud of gas puts you to sleep!");
55 nomul(-rnd(25));
56 break;
57 case BEAR_TRAP:
58 if(Levitation) {
59 pline("You float over a bear trap.");
60 break;
61 }
62 u.utrap = 4 + rn2(4);
63 u.utraptype = TT_BEARTRAP;
64 pline("A bear trap closes on your foot!");
65 break;
66 case PIERC:
67 deltrap(trap);
68 if(makemon(PM_PIERCER,u.ux,u.uy)) {
69 pline("A piercer suddenly drops from the ceiling!");
70 if(uarmh)
71 pline("Its blow glances off your helmet.");
72 else
73 (void) thitu(3,d(4,6),"falling piercer");
74 }
75 break;
76 case ARROW_TRAP:
77 pline("An arrow shoots out at you!");
78 if(!thitu(8,rnd(6),"arrow")){
79 mksobj_at(ARROW, u.ux, u.uy);
80 fobj->quan = 1;
81 }
82 break;
83 case TRAPDOOR:
84 if(!xdnstair) {
85 pline("A trap door in the ceiling opens and a rock falls on your head!");
86 if(uarmh) pline("Fortunately, you are wearing a helmet!");
87 losehp(uarmh ? 2 : d(2,10),"falling rock");
88 mksobj_at(ROCK, u.ux, u.uy);
89 fobj->quan = 1;
90 stackobj(fobj);
91 if(Invisible) newsym(u.ux, u.uy);
92 } else {
93 register int newlevel = dlevel + 1;
94 while(!rn2(4) && newlevel < 29)
95 newlevel++;
96 pline("A trap door opens up under you!");
97 if(Levitation || u.ustuck) {
98 pline("For some reason you don't fall in.");
99 break;
100 }
101
102 goto_level(newlevel, FALSE);
103 }
104 break;
105 case DART_TRAP:
106 pline("A little dart shoots out at you!");
107 if(thitu(7,rnd(3),"little dart")) {
108 if(!rn2(6))
109 poisoned("dart","poison dart");
110 } else {
111 mksobj_at(DART, u.ux, u.uy);
112 fobj->quan = 1;
113 }
114 break;
115 case TELEP_TRAP:
116 if(trap->once) {
117 deltrap(trap);
118 newsym(u.ux,u.uy);
119 vtele();
120 } else {
121 newsym(u.ux,u.uy);
122 tele();
123 }
124 break;
125 case PIT:
126 if(Levitation) {
127 pline("A pit opens up under you!");
128 pline("You don't fall in!");
129 break;
130 }
131 pline("You fall into a pit!");
132 u.utrap = rn1(6,2);
133 u.utraptype = TT_PIT;
134 losehp(rnd(6),"fall into a pit");
135 selftouch("Falling, you");
136 break;
137 default:
138 impossible("You hit a trap of type %u", trap->ttyp);
139 }
140 }
141 }
142
143 mintrap(mtmp) register struct monst *mtmp; {
144 register struct trap *trap = t_at(mtmp->mx, mtmp->my);
145 register int wasintrap = mtmp->mtrapped;
146
147 if(!trap) {
148 mtmp->mtrapped = 0; /* perhaps teleported? */
149 } else if(wasintrap) {
150 if(!rn2(40)) mtmp->mtrapped = 0;
151 } else {
152 register int tt = trap->ttyp;
153 int in_sight = cansee(mtmp->mx,mtmp->my);
154 extern char mlarge[];
155
156 if(mtmp->mtrapseen & (1 << tt)) {
157 /* he has been in such a trap - perhaps he escapes */
158 if(rn2(4)) return(0);
159 }
160 mtmp->mtrapseen |= (1 << tt);
161 switch (tt) {
162 case BEAR_TRAP:
163 if(index(mlarge, mtmp->data->mlet)) {
164 if(in_sight)
165 pline("%s is caught in a bear trap!",
166 Monnam(mtmp));
167 else
168 if(mtmp->data->mlet == 'o')
169 pline("You hear the roaring of an angry bear!");
170 mtmp->mtrapped = 1;
171 }
172 break;
173 case PIT:
174 /* there should be a mtmp/data -> floating */
175 if(!index("EywBfk'& ", mtmp->data->mlet)) { /* ab */
176 mtmp->mtrapped = 1;
177 if(in_sight)
178 pline("%s falls in a pit!", Monnam(mtmp));
179 }
180 break;
181 case SLP_GAS_TRAP:
182 if(!mtmp->msleep && !mtmp->mfroz) {
183 mtmp->msleep = 1;
184 if(in_sight)
185 pline("%s suddenly falls asleep!",
186 Monnam(mtmp));
187 }
188 break;
189 case TELEP_TRAP:
190 rloc(mtmp);
191 if(in_sight && !cansee(mtmp->mx,mtmp->my))
192 pline("%s suddenly disappears!",
193 Monnam(mtmp));
194 break;
195 case ARROW_TRAP:
196 if(in_sight) {
197 pline("%s is hit by an arrow!",
198 Monnam(mtmp));
199 }
200 mtmp->mhp -= 3;
201 break;
202 case DART_TRAP:
203 if(in_sight) {
204 pline("%s is hit by a dart!",
205 Monnam(mtmp));
206 }
207 mtmp->mhp -= 2;
208 /* not mondied here !! */
209 break;
210 case TRAPDOOR:
211 if(!xdnstair) {
212 mtmp->mhp -= 10;
213 if(in_sight)
214 pline("A trap door in the ceiling opens and a rock hits %s!", monnam(mtmp));
215 break;
216 }
217 if(mtmp->data->mlet != 'w'){
218 fall_down(mtmp);
219 if(in_sight)
220 pline("Suddenly, %s disappears out of sight.", monnam(mtmp));
221 return(2); /* no longer on this level */
222 }
223 break;
224 case PIERC:
225 break;
226 default:
227 impossible("Some monster encountered a strange trap.");
228 }
229 }
230 return(mtmp->mtrapped);
231 }
232
233 selftouch(arg) char *arg; {
234 if(uwep && uwep->otyp == DEAD_COCKATRICE){
235 pline("%s touch the dead cockatrice.", arg);
236 pline("You turn to stone.");
237 killer = objects[uwep->otyp].oc_name;
238 done("died");
239 }
240 }
241
242 float_up(){
243 if(u.utrap) {
244 if(u.utraptype == TT_PIT) {
245 u.utrap = 0;
246 pline("You float up, out of the pit!");
247 } else {
248 pline("You float up, only your leg is still stuck.");
249 }
250 } else
251 pline("You start to float in the air!");
252 }
253
254 float_down(){
255 register struct trap *trap;
256 pline("You float gently to the ground.");
257 if(trap = t_at(u.ux,u.uy))
258 switch(trap->ttyp) {
259 case PIERC:
260 break;
261 case TRAPDOOR:
262 if(!xdnstair || u.ustuck) break;
263 /* fall into next case */
264 default:
265 dotrap(trap);
266 }
267 pickup(1);
268 }
269
270 vtele() {
271 #include "def.mkroom.h"
272 register struct mkroom *croom;
273 for(croom = &rooms[0]; croom->hx >= 0; croom++)
274 if(croom->rtype == VAULT) {
275 register x,y;
276
277 x = rn2(2) ? croom->lx : croom->hx;
278 y = rn2(2) ? croom->ly : croom->hy;
279 if(teleok(x,y)) {
280 teleds(x,y);
281 return;
282 }
283 }
284 tele();
285 }
286
287 tele() {
288 extern coord getpos();
289 coord cc;
290 register int nux,nuy;
291
292 if(Teleport_control) {
293 pline("To what position do you want to be teleported?");
294 cc = getpos(1, "the desired position"); /* 1: force valid */
295 /* possible extensions: introduce a small error if
296 magic power is low; allow transfer to solid rock */
297 if(teleok(cc.x, cc.y)){
298 teleds(cc.x, cc.y);
299 return;
300 }
301 pline("Sorry ...");
302 }
303 do {
304 nux = rnd(COLNO-1);
305 nuy = rn2(ROWNO);
306 } while(!teleok(nux, nuy));
307 teleds(nux, nuy);
308 }
309
310 teleds(nux, nuy)
311 register int nux,nuy;
312 {
313 if(Punished) unplacebc();
314 unsee();
315 u.utrap = 0;
316 u.ustuck = 0;
317 u.ux = nux;
318 u.uy = nuy;
319 setsee();
320 if(Punished) placebc(1);
321 if(u.uswallow){
322 u.uswldtim = u.uswallow = 0;
323 docrt();
324 }
325 nomul(0);
326 if(levl[nux][nuy].typ == POOL && !Levitation)
327 drown();
328 (void) inshop();
329 pickup(1);
330 if(!Blind) read_engr_at(u.ux,u.uy);
331 }
332
333 teleok(x,y) register int x,y; { /* might throw him into a POOL */
334 return( isok(x,y) && !IS_ROCK(levl[x][y].typ) && !m_at(x,y) &&
335 !sobj_at(ENORMOUS_ROCK,x,y) && !t_at(x,y)
336 );
337 /* Note: gold is permitted (because of vaults) */
338 }
339
340 dotele() {
341 extern char pl_character[];
342
343 if(
344 #ifdef WIZARD
345 !wizard &&
346 #endif WIZARD
347 (!Teleportation || u.ulevel < 6 ||
348 (pl_character[0] != 'W' && u.ulevel < 10))) {
349 pline("You are not able to teleport at will.");
350 return(0);
351 }
352 if(u.uhunger <= 100 || u.ustr < 6) {
353 pline("You miss the strength for a teleport spell.");
354 return(1);
355 }
356 tele();
357 morehungry(100);
358 return(1);
359 }
360
361 placebc(attach) int attach; {
362 if(!uchain || !uball){
363 impossible("Where are your chain and ball??");
364 return;
365 }
366 uball->ox = uchain->ox = u.ux;
367 uball->oy = uchain->oy = u.uy;
368 if(attach){
369 uchain->nobj = fobj;
370 fobj = uchain;
371 if(!carried(uball)){
372 uball->nobj = fobj;
373 fobj = uball;
374 }
375 }
376 }
377
378 unplacebc(){
379 if(!carried(uball)){
380 freeobj(uball);
381 unpobj(uball);
382 }
383 freeobj(uchain);
384 unpobj(uchain);
385 }
386
387 level_tele() {
388 register int newlevel;
389 if(Teleport_control) {
390 char buf[BUFSZ];
391
392 do {
393 pline("To what level do you want to teleport? [type a number] ");
394 getlin(buf);
395 } while(!digit(buf[0]) && (buf[0] != '-' || !digit(buf[1])));
396 newlevel = atoi(buf);
397 } else {
398 newlevel = 5 + rn2(20); /* 5 - 24 */
399 if(dlevel == newlevel)
400 if(!xdnstair) newlevel--; else newlevel++;
401 }
402 if(newlevel >= 30) {
403 if(newlevel > MAXLEVEL) newlevel = MAXLEVEL;
404 pline("You arrive at the center of the earth ...");
405 pline("Unfortunately it is here that hell is located.");
406 if(Fire_resistance) {
407 pline("But the fire doesn't seem to harm you.");
408 } else {
409 pline("You burn to a crisp.");
410 dlevel = maxdlevel = newlevel;
411 killer = "visit to the hell";
412 done("burned");
413 }
414 }
415 if(newlevel < 0) {
416 newlevel = 0;
417 pline("You are now high above the clouds ...");
418 if(Levitation) {
419 pline("You float gently down to earth.");
420 done("escaped");
421 }
422 pline("Unfortunately, you don't know how to fly.");
423 pline("You fall down a few thousand feet and break your neck.");
424 dlevel = 0;
425 killer = "fall";
426 done("died");
427 }
428
429 goto_level(newlevel, FALSE); /* calls done("escaped") if newlevel==0 */
430 }
431
432 drown()
433 {
434 pline("You fall into a pool!");
435 pline("You can't swim!");
436 if(rn2(3) < u.uluck+2) {
437 /* most scrolls become unreadable */
438 register struct obj *obj;
439
440 for(obj = invent; obj; obj = obj->nobj)
441 if(obj->olet == SCROLL_SYM && rn2(12) > u.uluck)
442 obj->otyp = SCR_BLANK_PAPER;
443 /* we should perhaps merge these scrolls ? */
444
445 pline("You attempt a teleport spell."); /* utcsri!carroll */
446 (void) dotele();
447 if(levl[u.ux][u.uy].typ != POOL) return;
448 }
449 pline("You drown ...");
450 killer = "pool of water";
451 done("drowned");
452 }