home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / HACKSRC.ZIP / TRAP.C < prev    next >
C/C++ Source or Header  |  1985-10-16  |  11KB  |  459 lines

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