home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 2_3 / trap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-20  |  20.9 KB  |  920 lines

  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. }
  920.