home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 1 / src / trap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-07-26  |  9.7 KB  |  448 lines

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