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

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* do.c - version 1.0.3 */
  3.  
  4. /* Contains code for 'd', 'D' (drop), '>', '<' (up, down) and 't' (throw) */
  5.  
  6. #include "hack.h"
  7.  
  8. extern struct obj *splitobj(), *addinv();
  9. extern boolean hmon();
  10. extern boolean level_exists[];
  11. extern struct monst youmonst;
  12. extern char *Doname();
  13. extern char *nomovemsg;
  14.  
  15. dodrop() {
  16.     return(drop(getobj("0$#", "drop")));
  17. }
  18.  
  19. static
  20. drop(obj) register struct obj *obj; {
  21.     if(!obj) return(0);
  22.     if(obj->olet == '$') {        /* pseudo object */
  23.         register long amount = OGOLD(obj);
  24.  
  25.         if(amount == 0)
  26.             pline("You didn't drop any gold pieces.");
  27.         else {
  28.             mkgold(amount, u.ux, u.uy);
  29.             pline("You dropped %ld gold piece%s.",
  30.                 amount, plur(amount));
  31.             if(Invisible) newsym(u.ux, u.uy);
  32.         }
  33.         free((char *) obj);
  34.         return(1);
  35.     }
  36.     if(obj->owornmask & (W_ARMOR | W_RING)){
  37.         pline("You cannot drop something you are wearing.");
  38.         return(0);
  39.     }
  40.     if(obj == uwep) {
  41.         if(uwep->cursed) {
  42.             pline("Your weapon is welded to your hand!");
  43.             return(0);
  44.         }
  45.         setuwep((struct obj *) 0);
  46.     }
  47.     pline("You dropped %s.", doname(obj));
  48.     dropx(obj);
  49.     return(1);
  50. }
  51.  
  52. /* Called in several places - should not produce texts */
  53. dropx(obj)
  54. register struct obj *obj;
  55. {
  56.     freeinv(obj);
  57.     dropy(obj);
  58. }
  59.  
  60. dropy(obj)
  61. register struct obj *obj;
  62. {
  63.     if(obj->otyp == CRYSKNIFE)
  64.         obj->otyp = WORM_TOOTH;
  65.     obj->ox = u.ux;
  66.     obj->oy = u.uy;
  67.     obj->nobj = fobj;
  68.     fobj = obj;
  69.     if(Invisible) newsym(u.ux,u.uy);
  70.     subfrombill(obj);
  71.     stackobj(obj);
  72. }
  73.  
  74. /* drop several things */
  75. doddrop() {
  76.     return(ggetobj("drop", drop, 0));
  77. }
  78.  
  79. dodown()
  80. {
  81.     if(u.ux != xdnstair || u.uy != ydnstair) {
  82.         pline("You can't go down here.");
  83.         return(0);
  84.     }
  85.     if(u.ustuck) {
  86.         pline("You are being held, and cannot go down.");
  87.         return(1);
  88.     }
  89.     if(Levitation) {
  90.         pline("You're floating high above the stairs.");
  91.         return(0);
  92.     }
  93.  
  94.     goto_level(dlevel+1, TRUE);
  95.     return(1);
  96. }
  97.  
  98. doup()
  99. {
  100.     if(u.ux != xupstair || u.uy != yupstair) {
  101.         pline("You can't go up here.");
  102.         return(0);
  103.     }
  104.     if(u.ustuck) {
  105.         pline("You are being held, and cannot go up.");
  106.         return(1);
  107.     }
  108.     if(!Levitation && inv_weight() + 5 > 0) {
  109.         pline("Your load is too heavy to climb the stairs.");
  110.         return(1);
  111.     }
  112.  
  113.     goto_level(dlevel-1, TRUE);
  114.     return(1);
  115. }
  116.  
  117. goto_level(newlevel, at_stairs)
  118. register int newlevel;
  119. register boolean at_stairs;
  120. {
  121.     register fd;
  122.     register boolean up = (newlevel < dlevel);
  123.  
  124.     if(newlevel <= 0) done("escaped");    /* in fact < 0 is impossible */
  125.     if(newlevel > MAXLEVEL) newlevel = MAXLEVEL;    /* strange ... */
  126.     if(newlevel == dlevel) return;          /* this can happen */
  127.  
  128.     glo(dlevel);
  129.     fd = creat(lock, FMASK);
  130.     if(fd < 0) {
  131.         /*
  132.          * This is not quite impossible: e.g., we may have
  133.          * exceeded our quota. If that is the case then we
  134.          * cannot leave this level, and cannot save either.
  135.          * Another possibility is that the directory was not
  136.          * writable.
  137.          */
  138.         pline("A mysterious force prevents you from going %s.",
  139.             up ? "up" : "down");
  140.         return;
  141.     }
  142.  
  143.     if(Punished) unplacebc();
  144.     u.utrap = 0;                /* needed in level_tele */
  145.     u.ustuck = 0;                /* idem */
  146.     keepdogs();
  147.     seeoff(1);
  148.     if(u.uswallow)                /* idem */
  149.         u.uswldtim = u.uswallow = 0;
  150.     flags.nscrinh = 1;
  151.     u.ux = FAR;                /* hack */
  152.     (void) inshop();            /* probably was a trapdoor */
  153.  
  154.     savelev(fd,dlevel);
  155.     (void) close(fd);
  156.  
  157.     dlevel = newlevel;
  158.     if(maxdlevel < dlevel)
  159.         maxdlevel = dlevel;
  160.     glo(dlevel);
  161.  
  162.     if(!level_exists[dlevel])
  163.         mklev();
  164.     else {
  165.         extern int hackpid;
  166.  
  167.         if((fd = open(lock,0)) < 0) {
  168.             pline("Cannot open %s .", lock);
  169.             pline("Probably someone removed it.");
  170.             done("tricked");
  171.         }
  172.         getlev(fd, hackpid, dlevel);
  173.         (void) close(fd);
  174.     }
  175.  
  176.     if(at_stairs) {
  177.         if(up) {
  178.         u.ux = xdnstair;
  179.         u.uy = ydnstair;
  180.         if(!u.ux) {        /* entering a maze from below? */
  181.             u.ux = xupstair;    /* this will confuse the player! */
  182.             u.uy = yupstair;
  183.         }
  184.         if(Punished && !Levitation){
  185.             pline("With great effort you climb the stairs.");
  186.             placebc(1);
  187.         }
  188.         } else {
  189.         u.ux = xupstair;
  190.         u.uy = yupstair;
  191.         if(inv_weight() + 5 > 0 || Punished){
  192.             pline("You fall down the stairs.");    /* %% */
  193.             losehp(rnd(3), "fall");
  194.             if(Punished) {
  195.                 if(uwep != uball && rn2(3)){
  196.                 pline("... and are hit by the iron ball.");
  197.                 losehp(rnd(20), "iron ball");
  198.                 }
  199.                 placebc(1);
  200.             }
  201.             selftouch("Falling, you");
  202.         }
  203.         }
  204.         { register struct monst *mtmp = m_at(u.ux, u.uy);
  205.           if(mtmp)
  206.         mnexto(mtmp);
  207.         }
  208.     } else {    /* trapdoor or level_tele */
  209.         do {
  210.         u.ux = rnd(COLNO-1);
  211.         u.uy = rn2(ROWNO);
  212.         } while(levl[u.ux][u.uy].typ != ROOM ||
  213.             m_at(u.ux,u.uy));
  214.         if(Punished){
  215.         if(uwep != uball && !up /* %% */ && rn2(5)){
  216.             pline("The iron ball falls on your head.");
  217.             losehp(rnd(25), "iron ball");
  218.         }
  219.         placebc(1);
  220.         }
  221.         selftouch("Falling, you");
  222.     }
  223.     (void) inshop();
  224.     initrack();
  225.  
  226.     losedogs();
  227.     { register struct monst *mtmp;
  228.       if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp);    /* riv05!a3 */
  229.     }
  230.     flags.nscrinh = 0;
  231.     setsee();
  232.     seeobjs();    /* make old cadavers disappear - riv05!a3 */
  233.     docrt();
  234.     pickup(1);
  235.     read_engr_at(u.ux,u.uy);
  236. }
  237.  
  238. donull() {
  239.     return(1);    /* Do nothing, but let other things happen */
  240. }
  241.  
  242. dopray() {
  243.     nomovemsg = "You finished your prayer.";
  244.     nomul(-3);
  245.     return(1);
  246. }
  247.  
  248. struct monst *bhit(), *boomhit();
  249. dothrow()
  250. {
  251.     register struct obj *obj;
  252.     register struct monst *mon;
  253.     register tmp;
  254.  
  255.     obj = getobj("#)", "throw");   /* it is also possible to throw food */
  256.                        /* (or jewels, or iron balls ... ) */
  257.     if(!obj || !getdir(1))           /* ask "in what direction?" */
  258.         return(0);
  259.     if(obj->owornmask & (W_ARMOR | W_RING)){
  260.         pline("You can't throw something you are wearing.");
  261.         return(0);
  262.     }
  263.  
  264.     u_wipe_engr(2);
  265.  
  266.     if(obj == uwep){
  267.         if(obj->cursed){
  268.             pline("Your weapon is welded to your hand.");
  269.             return(1);
  270.         }
  271.         if(obj->quan > 1)
  272.             setuwep(splitobj(obj, 1));
  273.         else
  274.             setuwep((struct obj *) 0);
  275.     }
  276.     else if(obj->quan > 1)
  277.         (void) splitobj(obj, 1);
  278.     freeinv(obj);
  279.     if(u.uswallow) {
  280.         mon = u.ustuck;
  281.         bhitpos.x = mon->mx;
  282.         bhitpos.y = mon->my;
  283.     } else if(u.dz) {
  284.       if(u.dz < 0) {
  285.         pline("%s hits the ceiling, then falls back on top of your head.",
  286.         Doname(obj));        /* note: obj->quan == 1 */
  287.         if(obj->olet == POTION_SYM)
  288.         potionhit(&youmonst, obj);
  289.         else {
  290.         if(uarmh) pline("Fortunately, you are wearing a helmet!");
  291.         losehp(uarmh ? 1 : rnd((int)(obj->owt)), "falling object");
  292.         dropy(obj);
  293.         }
  294.       } else {
  295.         pline("%s hits the floor.", Doname(obj));
  296.         if(obj->otyp == EXPENSIVE_CAMERA) {
  297.         pline("It is shattered in a thousand pieces!");
  298.         obfree(obj, Null(obj));
  299.         } else if(obj->otyp == EGG) {
  300.         pline("\"Splash!\"");
  301.         obfree(obj, Null(obj));
  302.         } else if(obj->olet == POTION_SYM) {
  303.         pline("The flask breaks, and you smell a peculiar odor ...");
  304.         potionbreathe(obj);
  305.         obfree(obj, Null(obj));
  306.         } else {
  307.         dropy(obj);
  308.         }
  309.       }
  310.       return(1);
  311.     } else if(obj->otyp == BOOMERANG) {
  312.         mon = boomhit(u.dx, u.dy);
  313.         if(mon == &youmonst) {        /* the thing was caught */
  314.             (void) addinv(obj);
  315.             return(1);
  316.         }
  317.     } else {
  318.         if(obj->otyp == PICK_AXE && shkcatch(obj))
  319.             return(1);
  320.  
  321.         mon = bhit(u.dx, u.dy, (obj->otyp == ICE_BOX) ? 1 :
  322.             (!Punished || obj != uball) ? 8 : !u.ustuck ? 5 : 1,
  323.             obj->olet,
  324.             (int (*)()) 0, (int (*)()) 0, obj);
  325.     }
  326.     if(mon) {
  327.         /* awake monster if sleeping */
  328.         wakeup(mon);
  329.  
  330.         if(obj->olet == WEAPON_SYM) {
  331.             tmp = -1+u.ulevel+mon->data->ac+abon();
  332.             if(obj->otyp < ROCK) {
  333.                 if(!uwep ||
  334.                     uwep->otyp != obj->otyp+(BOW-ARROW))
  335.                     tmp -= 4;
  336.                 else {
  337.                     tmp += uwep->spe;
  338.                 }
  339.             } else
  340.             if(obj->otyp == BOOMERANG) tmp += 4;
  341.             tmp += obj->spe;
  342.             if(u.uswallow || tmp >= rnd(20)) {
  343.                 if(hmon(mon,obj,1) == TRUE){
  344.                   /* mon still alive */
  345. #ifndef NOWORM
  346.                   cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp);
  347. #endif NOWORM
  348.                 } else mon = 0;
  349.                 /* weapons thrown disappear sometimes */
  350.                 if(obj->otyp < BOOMERANG && rn2(3)) {
  351.                     /* check bill; free */
  352.                     obfree(obj, (struct obj *) 0);
  353.                     return(1);
  354.                 }
  355.             } else miss(objects[obj->otyp].oc_name, mon);
  356.         } else if(obj->otyp == HEAVY_IRON_BALL) {
  357.             tmp = -1+u.ulevel+mon->data->ac+abon();
  358.             if(!Punished || obj != uball) tmp += 2;
  359.             if(u.utrap) tmp -= 2;
  360.             if(u.uswallow || tmp >= rnd(20)) {
  361.                 if(hmon(mon,obj,1) == FALSE)
  362.                     mon = 0;    /* he died */
  363.             } else miss("iron ball", mon);
  364.         } else if(obj->olet == POTION_SYM && u.ulevel > rn2(15)) {
  365.             potionhit(mon, obj);
  366.             return(1);
  367.         } else {
  368.             if(cansee(bhitpos.x,bhitpos.y))
  369.                 pline("You miss %s.",monnam(mon));
  370.             else pline("You miss it.");
  371.             if(obj->olet == FOOD_SYM && mon->data->mlet == 'd')
  372.                 if(tamedog(mon,obj)) return(1);
  373.             if(obj->olet == GEM_SYM && mon->data->mlet == 'u' &&
  374.                 !mon->mtame){
  375.              if(obj->dknown && objects[obj->otyp].oc_name_known){
  376.               if(objects[obj->otyp].g_val > 0){
  377.                 u.uluck += 5;
  378.                 goto valuable;
  379.               } else {
  380.                 pline("%s is not interested in your junk.",
  381.                 Monnam(mon));
  382.               }
  383.              } else { /* value unknown to @ */
  384.                 u.uluck++;
  385.             valuable:
  386.                 if(u.uluck > LUCKMAX)    /* dan@ut-ngp */
  387.                 u.uluck = LUCKMAX;
  388.                 pline("%s graciously accepts your gift.",
  389.                 Monnam(mon));
  390.                 mpickobj(mon, obj);
  391.                 rloc(mon);
  392.                 return(1);
  393.              }
  394.             }
  395.         }
  396.     }
  397.         /* the code following might become part of dropy() */
  398.     if(obj->otyp == CRYSKNIFE)
  399.         obj->otyp = WORM_TOOTH;
  400.     obj->ox = bhitpos.x;
  401.     obj->oy = bhitpos.y;
  402.     obj->nobj = fobj;
  403.     fobj = obj;
  404.     /* prevent him from throwing articles to the exit and escaping */
  405.     /* subfrombill(obj); */
  406.     stackobj(obj);
  407.     if(Punished && obj == uball &&
  408.         (bhitpos.x != u.ux || bhitpos.y != u.uy)){
  409.         freeobj(uchain);
  410.         unpobj(uchain);
  411.         if(u.utrap){
  412.             if(u.utraptype == TT_PIT)
  413.                 pline("The ball pulls you out of the pit!");
  414.             else {
  415.                 register long side =
  416.                 rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
  417.                 pline("The ball pulls you out of the bear trap.");
  418.                 pline("Your %s leg is severely damaged.",
  419.                 (side == LEFT_SIDE) ? "left" : "right");
  420.                 set_wounded_legs(side, 500+rn2(1000));
  421.                 losehp(2, "thrown ball");
  422.             }
  423.             u.utrap = 0;
  424.         }
  425.         unsee();
  426.         uchain->nobj = fobj;
  427.         fobj = uchain;
  428.         u.ux = uchain->ox = bhitpos.x - u.dx;
  429.         u.uy = uchain->oy = bhitpos.y - u.dy;
  430.         setsee();
  431.         (void) inshop();
  432.     }
  433.     if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y);
  434.     return(1);
  435. }
  436.  
  437. /* split obj so that it gets size num */
  438. /* remainder is put in the object structure delivered by this call */
  439. struct obj *
  440. splitobj(obj, num) register struct obj *obj; register int num; {
  441. register struct obj *otmp;
  442.     otmp = newobj(0);
  443.     *otmp = *obj;        /* copies whole structure */
  444.     otmp->o_id = flags.ident++;
  445.     otmp->onamelth = 0;
  446.     obj->quan = num;
  447.     obj->owt = weight(obj);
  448.     otmp->quan -= num;
  449.     otmp->owt = weight(otmp);    /* -= obj->owt ? */
  450.     obj->nobj = otmp;
  451.     if(obj->unpaid) splitbill(obj,otmp);
  452.     return(otmp);
  453. }
  454.  
  455. more_experienced(exp,rexp)
  456. register int exp, rexp;
  457. {
  458.     extern char pl_character[];
  459.  
  460.     u.uexp += exp;
  461.     u.urexp += 4*exp + rexp;
  462.     if(exp) flags.botl = 1;
  463.     if(u.urexp >= ((pl_character[0] == 'W') ? 1000 : 2000))
  464.         flags.beginner = 0;
  465. }
  466.  
  467. set_wounded_legs(side, timex)
  468. register long side;
  469. register int timex;
  470. {
  471.     if(!Wounded_legs || (Wounded_legs & TIMEOUT))
  472.         Wounded_legs |= side + timex;
  473.     else
  474.         Wounded_legs |= side;
  475. }
  476.  
  477. heal_legs()
  478. {
  479.     if(Wounded_legs) {
  480.         if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
  481.             pline("Your legs feel somewhat better.");
  482.         else
  483.             pline("Your leg feels somewhat better.");
  484.         Wounded_legs = 0;
  485.     }
  486. }
  487.