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