home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d190 / nethack.lha / NetHack / twee.zoo / hack.c < prev    next >
C/C++ Source or Header  |  1988-07-22  |  25KB  |  1,088 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2.  
  3. #include <stdio.h>
  4. #include "hack.h"
  5. #ifdef UNIX
  6. static    char    SCCS_Id[] = "@(#)hack.c 2.3\t88/02/18";
  7. #endif
  8. extern char news0();
  9. extern char *nomovemsg;
  10. extern char *exclam();
  11. extern struct obj *addinv();
  12. extern boolean hmon();
  13.  
  14. /* called on movement:
  15.     1. when throwing ball+chain far away
  16.     2. when teleporting
  17.     3. when walking out of a lit room
  18.  */
  19. unsee() {
  20.     register x,y;
  21.     register struct rm *lev;
  22.  
  23. /*
  24.     if(u.udispl){
  25.         u.udispl = 0;
  26.         newsym(u.udisx, u.udisy);
  27.     }
  28. */
  29. #ifndef QUEST
  30.     if(seehx){
  31.         seehx = 0;
  32.     } else
  33. #endif
  34.     for(x = u.ux-1; x < u.ux+2; x++)
  35.       for(y = u.uy-1; y < u.uy+2; y++) {
  36.         if(!isok(x, y)) continue;
  37.         lev = &levl[x][y];
  38.         if(!RM_LIT(*lev) && lev->scrsym == ROOM_SYM) {
  39.             lev->scrsym = STONE_SYM;
  40.             RM_SET_NEW(*lev);
  41.             on_scr(x,y);
  42.         }
  43.     }
  44. }
  45.  
  46. /* called:
  47.     in apply.c:  seeoff(0)  - when taking a picture of yourself
  48.                 - when donning a blindfold
  49.     in do.c:     seeoff(0)  - blind after drinking potion
  50.     in do.c:     seeoff(1)  - go up or down the stairs
  51.     in eat.c:    seeoff(0)  - blind after eating rotten food
  52.     in mhitu.c:  seeoff(0)  - blinded by a yellow light
  53.     in mon.c:    seeoff(1)  - swallowed
  54.     in potion.c: seeoff(0)  - quaffing or sniffing a potion of blindness
  55.     in spell.c:  seeoff(0)  - due to a cursed spellbook
  56.     in trap.c:   seeoff(1)  - fall through trapdoor
  57.     in wizard.c: seeoff(0)  - hit by a cream pie.
  58.  */
  59. seeoff(mode)    /* 1 to redo @, 0 to leave them */
  60. {    /* 1 means misc movement, 0 means blindness */
  61.     register x,y;
  62.     register struct rm *lev;
  63.  
  64.     if(u.udispl && mode){
  65.         u.udispl = 0;
  66.         levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy);
  67.     }
  68. #ifndef QUEST
  69.     if(seehx) {
  70.         seehx = 0;
  71.     } else
  72. #endif
  73.     if(!mode) {
  74.         for(x = u.ux-1; x < u.ux+2; x++)
  75.             for(y = u.uy-1; y < u.uy+2; y++) {
  76.                 if(!isok(x, y)) continue;
  77.                 lev = &levl[x][y];
  78.                 if(!RM_LIT(*lev) && lev->scrsym == ROOM_SYM)
  79.                     RM_CLR_SEEN(*lev);
  80.             }
  81.     }
  82. }
  83.  
  84. static
  85. moverock() {
  86.     register xchar rx, ry;
  87.     register struct obj *otmp;
  88.     register struct trap *ttmp;
  89.     register struct monst *mtmp;
  90.     struct monst *m_at();
  91.  
  92.     while(otmp = sobj_at(ENORMOUS_ROCK, u.ux+u.dx, u.uy+u.dy)) {
  93.         rx = u.ux+2*u.dx;
  94.         ry = u.uy+2*u.dy;
  95.         nomul(0);
  96.         if(isok(rx,ry) && !IS_ROCK(RM_TYP(levl[rx][ry])) &&
  97.             (RM_TYP(levl[rx][ry]) != DOOR || !(u.dx && u.dy)) &&
  98.             !sobj_at(ENORMOUS_ROCK, rx, ry)) {
  99.             if((mtmp = m_at(rx,ry))) {
  100.                 if(canseemon(mtmp))
  101.                 pline("There's %s on the other side.", monnam(mtmp));
  102.                 else
  103.                 pline("You hear a monster behind the rock.");
  104.                 pline("Perhaps that's why you cannot move it.");
  105.                 goto cannot_push;
  106.             }
  107.             if(ttmp = t_at(rx,ry))
  108.                 switch(ttmp->ttyp) {
  109.                 case PIT:
  110.                 pline("You push the rock into a pit!");
  111.                 deltrap(ttmp);
  112.                 delobj(otmp);
  113.                 pline("It completely fills the pit!");
  114.                 continue;
  115.                 case TELEP_TRAP:
  116.                 pline("You push the rock and suddenly it disappears!");
  117.                 delobj(otmp);
  118.                 continue;
  119.                 }
  120.             if(RM_TYP(levl[rx][ry]) == POOL) {
  121.                 RM_SET_TYP(levl[rx][ry], ROOM);
  122.                 mnewsym(rx,ry);
  123.                 prl(rx,ry);
  124.                 pline("You push the rock into the water.");
  125.                 pline("Now you can cross the water!");
  126.                 delobj(otmp);
  127.                 continue;
  128.             }
  129.             otmp->ox = rx;
  130.             otmp->oy = ry;
  131.             /* pobj(otmp); */
  132.             if(cansee(rx,ry)) atl(rx,ry,otmp->olet);
  133.             if(Invisible) newsym(u.ux+u.dx, u.uy+u.dy);
  134.  
  135.             { static long lastmovetime;
  136.             /* note: this var contains garbage initially and
  137.                after a restore */
  138.             if(moves > lastmovetime+2 || moves < lastmovetime)
  139.             pline("With great effort you move the enormous rock.");
  140.             lastmovetime = moves;
  141.             }
  142.         } else {
  143.             pline("You try to move the enormous rock, but in vain.");
  144.         cannot_push:
  145. #ifdef KAA
  146.             if (u.usym=='9') {
  147. # ifdef DGKMOD
  148.             if(!flags.pickup)
  149.                 pline("You easily can push it aside.");
  150.             else
  151. # endif
  152.                 pline("However, you easily can pick it up.");
  153.             break;
  154.             }
  155. #endif
  156.             if((!invent || inv_weight()+90 <= 0) &&
  157.             (!u.dx || !u.dy || (IS_ROCK(RM_TYP(levl[u.ux][u.uy+u.dy]))
  158.                     && IS_ROCK(RM_TYP(levl[u.ux+u.dx][u.uy]))))){
  159.             pline("However, you can squeeze yourself into a small opening.");
  160.             break;
  161.             } else
  162.             return (-1);
  163.         }
  164.     }
  165.     return (0);
  166. }
  167.  
  168. domove()
  169. {
  170.     register struct monst *mtmp;
  171.     register struct rm *tmpr,*ust;
  172.     struct trap *trap;
  173.  
  174.     u_wipe_engr(rnd(5));
  175.  
  176.     if(inv_weight() > 0){
  177.         pline("You collapse under your load.");
  178.         nomul(0);
  179.         return;
  180.     }
  181.     if(u.uswallow) {
  182.         u.dx = u.dy = 0;
  183.         u.ux = u.ustuck->mx;
  184.         u.uy = u.ustuck->my;
  185.     } else {
  186.         if(Confusion) {
  187.             do {
  188.                 confdir();
  189.             } while(!isok(u.ux+u.dx, u.uy+u.dy) ||
  190.                 IS_ROCK(RM_TYP(levl[u.ux+u.dx][u.uy+u.dy])));
  191.         }
  192.         if(!isok(u.ux+u.dx, u.uy+u.dy)){
  193.             nomul(0);
  194.             return;
  195.         }
  196.     }
  197.  
  198.     ust = &levl[u.ux][u.uy];
  199.     u.ux0 = u.ux;
  200.     u.uy0 = u.uy;
  201.     if(!u.uswallow && (trap = t_at(u.ux+u.dx, u.uy+u.dy)) && trap->tseen)
  202.         nomul(0);
  203.     if(u.ustuck && !u.uswallow && (u.ux+u.dx != u.ustuck->mx ||
  204.         u.uy+u.dy != u.ustuck->my)) {
  205.         if(dist(u.ustuck->mx, u.ustuck->my) > 2){
  206.             /* perhaps it fled (or was teleported or ... ) */
  207.             u.ustuck = 0;
  208.         } else {
  209.             if(Blind) pline("You cannot escape from it!");
  210.             else pline("You cannot escape from %s!",
  211.                 monnam(u.ustuck));
  212.             nomul(0);
  213.             return;
  214.         }
  215.     }
  216.     if(u.uswallow || (mtmp = m_at(u.ux+u.dx,u.uy+u.dy))) {
  217.     /* attack monster */
  218.  
  219. #ifdef SAFE_ATTACK
  220.         /* Don't attack if you're running */
  221.         if (flags.run && !mtmp->mimic
  222.         && (Blind ? Telepat : (!mtmp->minvis || See_invisible))) {
  223.             nomul(0);
  224.             flags.move = 0;
  225.             return;
  226.         }
  227. #endif
  228.         nomul(0);
  229.         gethungry();
  230.         if(multi < 0) return;   /* we just fainted */
  231.  
  232.         /* try to attack; note that it might evade */
  233.         if(attack(u.uswallow ? u.ustuck : mtmp))
  234.             return;
  235.     }
  236.     /* not attacking an animal, so we try to move */
  237.     if(u.utrap) {
  238.         if(u.utraptype == TT_PIT) {
  239.             pline("You are still in a pit.");
  240.             u.utrap--;
  241. #ifdef SPIDERS
  242.         } else if (u.utraptype == TT_WEB) {
  243.             pline("You are stuck to the web.");
  244.             u.utrap--;
  245. #endif
  246.         } else {
  247.             pline("You are caught in a bear trap.");
  248.             if((u.dx && u.dy) || !rn2(5)) u.utrap--;
  249.         }
  250.         return;
  251.     }
  252.     tmpr = &levl[u.ux+u.dx][u.uy+u.dy];
  253.     if(IS_ROCK(RM_TYP(*tmpr)) ||
  254.        (u.dx && u.dy && (RM_TYP(*tmpr) == DOOR || RM_TYP(*ust) == DOOR))){
  255.         flags.move = 0;
  256.         nomul(0);
  257.         return;
  258.     }
  259.     if(moverock() < 0) return;
  260.     if(u.dx && u.dy && IS_ROCK(RM_TYP(levl[u.ux][u.uy+u.dy])) &&
  261.         IS_ROCK(RM_TYP(levl[u.ux+u.dx][u.uy])) &&
  262.         invent && inv_weight()+40 > 0) {
  263.         pline("You are carrying too much to get through.");
  264.         nomul(0);
  265.         return;
  266.     }
  267.     if(Punished &&
  268.        DIST(u.ux+u.dx, u.uy+u.dy, uchain->ox, uchain->oy) > 2){
  269.         if(carried(uball)) {
  270.             movobj(uchain, u.ux, u.uy);
  271.             goto nodrag;
  272.         }
  273.  
  274.         if(DIST(u.ux+u.dx, u.uy+u.dy, uball->ox, uball->oy) < 3){
  275.             /* leave ball, move chain under/over ball */
  276.             movobj(uchain, uball->ox, uball->oy);
  277.             goto nodrag;
  278.         }
  279.  
  280.         if(inv_weight() + (int) uball->owt/2 > 0) {
  281.             pline("You cannot %sdrag the heavy iron ball.",
  282.             invent ? "carry all that and also " : "");
  283.             nomul(0);
  284.             return;
  285.         }
  286.  
  287.         movobj(uball, uchain->ox, uchain->oy);
  288.         unpobj(uball);          /* BAH %% */
  289.         uchain->ox = u.ux;
  290.         uchain->oy = u.uy;
  291.         nomul(-2);
  292.         nomovemsg = "";
  293.     nodrag: ;
  294.     }
  295.     u.ux += u.dx;
  296.     u.uy += u.dy;
  297.     if(flags.run) {
  298.         if(RM_TYP(*tmpr) == DOOR ||
  299.         (xupstair == u.ux && yupstair == u.uy) ||
  300.         (xdnstair == u.ux && ydnstair == u.uy)
  301. #ifdef FOUNTAINS
  302.         || IS_FOUNTAIN(RM_TYP(levl[u.ux][u.uy]))
  303. #endif
  304. #ifdef NEWCLASS
  305.         || IS_THRONE(RM_TYP(levl[u.ux][u.uy]))
  306. #endif
  307. #ifdef SINKS
  308.         || IS_SINK(RM_TYP(levl[u.ux][u.uy]))
  309. #endif
  310.         )
  311.             nomul(0);
  312.     }
  313.  
  314. #ifdef SINKS
  315.     if(IS_SINK(RM_TYP(levl[u.ux][u.uy])) && Levitation)
  316.         dosinkfall();
  317. #endif
  318.     if(RM_TYP(*tmpr) == POOL && !Levitation)
  319.         drown();        /* not necessarily fatal */
  320.  
  321. /*
  322.     if(u.udispl) {
  323.         u.udispl = 0;
  324.         newsym(u.ux0,u.uy0);
  325.     }
  326. */
  327.     if(!Blind) {
  328. #ifdef QUEST
  329.         setsee();
  330. #else
  331.         if(RM_LIT(*ust)) {
  332.             if(RM_LIT(*tmpr)) {
  333.                 if(RM_TYP(*tmpr) == DOOR)
  334.                     prl1(u.ux+u.dx,u.uy+u.dy);
  335.                 else if(RM_TYP(*ust) == DOOR)
  336.                     nose1(u.ux0-u.dx,u.uy0-u.dy);
  337.             } else {
  338.                 unsee();
  339.                 prl1(u.ux+u.dx,u.uy+u.dy);
  340.             }
  341.         } else {
  342.             if(RM_LIT(*tmpr)) setsee();
  343.             else {
  344.                 prl1(u.ux+u.dx,u.uy+u.dy);
  345.                 if(RM_TYP(*tmpr) == DOOR) {
  346.                     if(u.dy) {
  347.                         prl(u.ux-1,u.uy);
  348.                         prl(u.ux+1,u.uy);
  349.                     } else {
  350.                         prl(u.ux,u.uy-1);
  351.                         prl(u.ux,u.uy+1);
  352.                     }
  353.                 }
  354.             }
  355.             nose1(u.ux0-u.dx,u.uy0-u.dy);
  356.         }
  357. #endif /* QUEST /**/
  358.     } else {
  359.         pru();
  360.     }
  361.     if(!flags.nopick) pickup(1);
  362.     if(trap) dotrap(trap);          /* fall into pit, arrow trap, etc. */
  363.     (void) inshop();
  364.     if(!Blind) read_engr_at(u.ux,u.uy);
  365. }
  366.  
  367. movobj(obj, ox, oy)
  368. register struct obj *obj;
  369. register int ox, oy;
  370. {
  371.     /* Some dirty programming to get display right */
  372.     freeobj(obj);
  373.     unpobj(obj);
  374.     obj->nobj = fobj;
  375.     fobj = obj;
  376.     obj->ox = ox;
  377.     obj->oy = oy;
  378. }
  379.  
  380. dopickup(){
  381.     /* uswallow case added by GAN 01/29/87 */
  382.     if(u.uswallow)  {
  383.         pline("You pick up %s's tongue.",monnam(u.ustuck));
  384.         pline("But it's kind of slimy, so you drop it.");
  385.         return(1);
  386.     }
  387.     if(!g_at(u.ux,u.uy) && !o_at(u.ux,u.uy)) {
  388.         pline("There is nothing here to pick up.");
  389.         return(0);
  390.     }
  391.     if(Levitation) {
  392.         pline("You cannot reach the floor.");
  393.         return(1);
  394.     }
  395.     pickup(0);
  396.     return(1);
  397. }
  398.  
  399. pickup(all)
  400. {
  401.     register struct gold *gold;
  402.     register struct obj *obj, *obj2;
  403.     register int wt;
  404.     char buf[BUFSZ];
  405.     register char *ip;
  406.     register char sym;
  407.     register int oletct = 0, iletct = 0;
  408.     char olets[20], ilets[20];
  409.  
  410.     if(Levitation) return;
  411. #ifdef DGKMOD
  412.     if (all && !flags.pickup) {
  413.         int ct = 0;
  414.  
  415.         for (obj = fobj; obj; obj = obj->nobj)
  416.             if (obj->ox == u.ux && obj->oy == u.uy)
  417.                 if (!Punished || obj != uchain)
  418.                     ct++;
  419.         /* If gold is the only thing here, pick it up.
  420.          */
  421.         if (!ct && g_at(u.ux, u.uy)) {
  422.             if (flags.run) nomul(0);
  423.             while (gold = g_at(u.ux,u.uy)) {
  424.                 pline("%ld gold piece%s.", gold->amount,
  425.                     plur(gold->amount));
  426.                 u.ugold += gold->amount;
  427.                 flags.botl = 1;
  428.                 freegold(gold);
  429.             }
  430.             if (Invisible) newsym(u.ux,u.uy);
  431.         }
  432.  
  433.         /* If there are objects here, take a look.
  434.          */
  435.         if (ct) {
  436.             if (flags.run)
  437.                 nomul(0);
  438.             nscr();
  439.             if (ct < 5)
  440.                 dolook();
  441.             else
  442.                 pline("There are several objects here.");
  443.         }
  444.         return;
  445.     }
  446. #endif
  447.     while(gold = g_at(u.ux,u.uy)) {
  448.         pline("%ld gold piece%s.", gold->amount, plur(gold->amount));
  449.         u.ugold += gold->amount;
  450.         flags.botl = 1;
  451.         freegold(gold);
  452.         if(flags.run) nomul(0);
  453.         if(Invisible) newsym(u.ux,u.uy);
  454.     }
  455.     /* check for more than one object */
  456.     if(!all) {
  457.         register int ct = 0;
  458.  
  459.         for(obj = fobj; obj; obj = obj->nobj)
  460.             if(obj->ox == u.ux && obj->oy == u.uy) ct++;
  461.         if(g_at(u.ux,u.uy))
  462.             ct++;
  463.         if(ct < 2)
  464.             all++;
  465.         else
  466.             pline("There are several objects here.");
  467.     }
  468.  
  469.     /* added by GAN 10/24/86 to allow selective picking up */
  470.     if(!all)  {
  471.         register struct obj *otmp = fobj;
  472.  
  473.         if(g_at(u.ux,u.uy)) ilets[iletct++] = GOLD_SYM;
  474.         ilets[iletct] = 0;
  475.         while(otmp) {
  476.             if(!index(ilets, otmp->olet) &&
  477.                otmp->ox == u.ux && otmp->oy == u.uy)  {
  478.                 ilets[iletct++] = otmp->olet;
  479.                 ilets[iletct] = 0;
  480.             }
  481.             otmp = otmp->nobj;
  482.         }
  483.         if(iletct == 1)
  484.             strcpy(buf,ilets);
  485.         else  {
  486.             ilets[iletct++] = ' ';
  487.             ilets[iletct++] = 'a';
  488.             ilets[iletct++] = 'A';
  489.             ilets[iletct] = 0;
  490.  
  491.             if(iletct = 3)
  492.             pline("What kinds of thing do you want to pick up? [%s] ", ilets);
  493.             getlin(buf);
  494.             if(buf[0] == '\033') {
  495.                 clrlin();
  496.                 return;
  497.             }
  498. #ifdef KJSMODS
  499.             else if(!buf[0]) strcpy(buf,"A");
  500. #endif
  501.         }
  502.         ip = buf;
  503.         olets[0] = 0;
  504.         while(sym = *ip++){
  505.             /* new A function (selective all) added by
  506.              * GAN 01/09/87
  507.              */
  508.             if(sym == 'A')  {
  509.                 for(oletct = 0; ilets[oletct] != ' '; oletct++)
  510.                     olets[oletct] = ilets[oletct];
  511.                 olets[oletct] = 0;
  512.                 break;
  513.             }
  514.             if(sym == ' ') continue;
  515.             if(sym == 'a') all++; else
  516.             if(index(ilets, sym)){
  517.                 if(!index(olets, sym)){
  518.                     olets[oletct++] = sym;
  519.                     olets[oletct] = 0;
  520.                 }
  521.             }
  522.             else pline("There are no %c's here.", sym);
  523.         }
  524.     }
  525.  
  526.     if(all || index(olets, GOLD_SYM))
  527.         while(gold = g_at(u.ux,u.uy)) {
  528.             pline("%ld gold piece%s.", gold->amount,
  529.                plur(gold->amount));
  530.             u.ugold += gold->amount;
  531.             flags.botl = 1;
  532.             freegold(gold);
  533.             if(flags.run) nomul(0);
  534.             if(Invis) newsym(u.ux,u.uy);
  535.     }
  536.  
  537.  
  538.     for(obj = fobj; obj; obj = obj2) {
  539.         obj2 = obj->nobj;    /* perhaps obj will be picked up */
  540.         if(obj->ox == u.ux && obj->oy == u.uy) {
  541.         if(flags.run) nomul(0);
  542.  
  543.         if(!all)  {
  544.             char c;
  545.  
  546.             if(!index(olets,obj->olet)) continue;
  547.  
  548.             pline("Pick up %s ? [ynaq]", doname(obj));
  549.             while(!index("ynaq ", (c = readchar())))
  550.                 bell();
  551.             if(c == 'q') return;
  552.             if(c == 'n') continue;
  553.             if(c == 'a') all = 1;
  554.         }
  555.  
  556.         if(obj->otyp == DEAD_COCKATRICE && !uarmg && u.usym != 'c') {
  557.             pline("Touching the dead cockatrice is a fatal mistake.");
  558.             pline("You turn to stone.");
  559.             pline("You die...");
  560.             killer = "cockatrice cadaver";
  561.             done("died");
  562.         }
  563.  
  564.         if(obj->otyp == SCR_SCARE_MONSTER){
  565.           if(!obj->spe) obj->spe = 1;
  566.           else {
  567.             /* Note: perhaps the 1st pickup failed: you cannot
  568.             carry anymore, and so we never dropped it -
  569.             lets assume that treading on it twice also
  570.             destroys the scroll */
  571.             pline("The scroll turns to dust as you pick it up.");
  572. #ifdef KAA
  573.             if(!(objects[SCR_SCARE_MONSTER].oc_name_known) &&
  574.                !(objects[SCR_SCARE_MONSTER].oc_uname))
  575.                 docall(obj);
  576. #endif
  577.             delobj(obj);
  578.             continue;
  579.           }
  580.         }
  581.  
  582.         /* do not pick up uchain */
  583.         if(Punished && obj == uchain)
  584.             continue;
  585.  
  586.  
  587.         wt = inv_weight() + obj->owt;
  588.         if(wt > 0) {
  589.             if(obj->quan > 1) {
  590.                 /* see how many we can lift */
  591.                 extern struct obj *splitobj();
  592.                 int savequan = obj->quan;
  593.                 int iw = inv_weight();
  594.                 int qq;
  595.                 for(qq = 1; qq < savequan; qq++){
  596.                     obj->quan = qq;
  597.                     if(iw + weight(obj) > 0)
  598.                         break;
  599.                 }
  600.                 obj->quan = savequan;
  601.                 qq--;
  602.                 /* we can carry qq of them */
  603.                 if(!qq) goto too_heavy;
  604.             pline("You can only carry %s of the %s lying here.",
  605.                     (qq == 1) ? "one" : "some",
  606.                     doname(obj));
  607.                 {
  608.                 register struct obj *obj3;
  609.  
  610.                 obj3 = splitobj(obj, qq);
  611.                 if(obj3->otyp == SCR_SCARE_MONSTER)
  612.                     if(obj3->spe) obj->spe = 0;
  613.                 }
  614.                 /* note: obj2 is set already, so well never
  615.                  * encounter the other half; if it should be
  616.                  * otherwise then write
  617.                  *    obj2 = splitobj(obj,qq);
  618.                  */
  619.                 goto lift_some;
  620.             }
  621.         too_heavy:
  622.             pline("There %s %s here, but %s.",
  623.                 (obj->quan == 1) ? "is" : "are",
  624.                 doname(obj),
  625.                 !invent ? "it is too heavy for you to lift"
  626.                 /* There is no such word as "anymore". KAA */
  627.                     : "you cannot carry any more");
  628.                 if(obj->otyp == SCR_SCARE_MONSTER)
  629.                     if(obj->spe) obj->spe = 0;
  630.             break;
  631.         }
  632.     lift_some:
  633.         if(inv_cnt() >= 52) {
  634.             pline("Your knapsack cannot accommodate any more items.");
  635.                 if(obj->otyp == SCR_SCARE_MONSTER)
  636.                     if(obj->spe) obj->spe = 0;
  637.             break;
  638.         }
  639.         freeobj(obj);
  640.         if(Invisible) newsym(u.ux,u.uy);
  641.         addtobill(obj);       /* sets obj->unpaid if necessary */
  642.         if(wt > -5) pline("You have a little trouble lifting");
  643.         { int pickquan = obj->quan;
  644.           int mergquan;
  645. #ifdef KAA
  646.         if(!Blind) if(obj->olet != WEAPON_SYM) obj->dknown = 1;
  647. #else
  648.         if(!Blind) obj->dknown = 1;     /* this is done by prinv(),
  649.                  but addinv() needs it already for merging */
  650. #endif
  651.         obj = addinv(obj);    /* might merge it with other objects */
  652.           mergquan = obj->quan;
  653.           obj->quan = pickquan; /* to fool prinv() */
  654.         prinv(obj);
  655.           obj->quan = mergquan;
  656.         }
  657.         }
  658.     }
  659. }
  660.  
  661. /* stop running if we see something interesting */
  662. /* turn around a corner if that is the only way we can proceed */
  663. /* do not turn left or right twice */
  664. lookaround(){
  665. register x,y,i,x0,y0,m0,i0 = 9;
  666. register int corrct = 0, noturn = 0;
  667. register struct monst *mtmp;
  668. #ifdef LINT
  669.     /* suppress "used before set" message */
  670.     x0 = y0 = 0;
  671. #endif
  672.     if(Blind || flags.run == 0) return;
  673.     if(flags.run == 1 && RM_TYP(levl[u.ux][u.uy]) == ROOM) return;
  674. #ifdef QUEST
  675.     if(u.ux0 == u.ux+u.dx && u.uy0 == u.uy+u.dy) goto stop;
  676. #endif
  677.     for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){
  678.         if(x == u.ux && y == u.uy) continue;
  679.         if(!RM_TYP(levl[x][y])) continue;
  680.         if((mtmp = m_at(x,y)) && !mtmp->mimic &&
  681.             (!mtmp->minvis || See_invisible)){
  682.             if(!mtmp->mtame || (x == u.ux+u.dx && y == u.uy+u.dy))
  683.                 goto stop;
  684.         } else mtmp = 0; /* invisible M cannot influence us */
  685.         if(x == u.ux-u.dx && y == u.uy-u.dy) continue;
  686.         {
  687.         register uchar sym = levl[x][y].scrsym;
  688.  
  689.         if (sym == VWALL_SYM || sym == HWALL_SYM
  690.             || sym == ROOM_SYM || sym == STONE_SYM
  691.             || IS_CORNER(sym))
  692.             continue;
  693.         else if (sym == DOOR_SYM) {
  694.             if(x != u.ux && y != u.uy) continue;
  695.             if(flags.run != 1) goto stop;
  696.             goto corr;
  697.         } else if (sym == CORR_SYM) {
  698.         corr:
  699.             if(flags.run == 1 || flags.run == 3) {
  700.                 i = DIST(x,y,u.ux+u.dx,u.uy+u.dy);
  701.                 if(i > 2) continue;
  702.                 if(corrct == 1 && DIST(x,y,x0,y0) != 1)
  703.                     noturn = 1;
  704.                 if(i < i0) {
  705.                     i0 = i;
  706.                     x0 = x;
  707.                     y0 = y;
  708.                     m0 = mtmp ? 1 : 0;
  709.                 }
  710.             }
  711.             corrct++;
  712.             continue;
  713.         } else if (sym == TRAP_SYM) {
  714.             if(flags.run == 1) goto corr;   /* if you must */
  715.             if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop;
  716.             continue;
  717.         } else {        /* e.g. objects or trap or stairs */
  718.             if(flags.run == 1) goto corr;
  719.             if(mtmp) continue;              /* d */
  720.         }
  721.         stop:
  722.             nomul(0);
  723.             return;
  724.         }
  725.     }
  726. #ifdef QUEST
  727.     if(corrct > 0 && (flags.run == 4 || flags.run == 5)) goto stop;
  728. #endif
  729.     if(corrct > 1 && flags.run == 2) goto stop;
  730.     if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 &&
  731.         (corrct == 1 || (corrct == 2 && i0 == 1))) {
  732.         /* make sure that we do not turn too far */
  733.         if(i0 == 2) {
  734.             if(u.dx == y0-u.uy && u.dy == u.ux-x0)
  735.             i = 2;        /* straight turn right */
  736.             else
  737.             i = -2;     /* straight turn left */
  738.         } else if(u.dx && u.dy) {
  739.             if((u.dx == u.dy && y0 == u.uy) ||
  740.             (u.dx != u.dy && y0 != u.uy))
  741.             i = -1;     /* half turn left */
  742.             else
  743.             i = 1;        /* half turn right */
  744.         } else {
  745.             if((x0-u.ux == y0-u.uy && !u.dy) ||
  746.             (x0-u.ux != y0-u.uy && u.dy))
  747.             i = 1;        /* half turn right */
  748.             else
  749.             i = -1;     /* half turn left */
  750.         }
  751.         i += u.last_str_turn;
  752.         if(i <= 2 && i >= -2) {
  753.             u.last_str_turn = i;
  754.             u.dx = x0-u.ux, u.dy = y0-u.uy;
  755.         }
  756.     }
  757. }
  758.  
  759. /* something like lookaround, but we are not running */
  760. /* react only to monsters that might hit us */
  761. monster_nearby() {
  762. register int x,y;
  763. register struct monst *mtmp;
  764.     if(!Blind)
  765.     for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){
  766.         if(x == u.ux && y == u.uy) continue;
  767.         if((mtmp = m_at(x,y)) && !mtmp->mimic && !mtmp->mtame &&
  768.             !mtmp->mpeaceful && !index("Ea", mtmp->data->mlet) &&
  769.             !mtmp->mfroz && !mtmp->msleep &&  /* aplvax!jcn */
  770.             (!mtmp->minvis || See_invisible))
  771.             return(1);
  772.     }
  773.     return(0);
  774. }
  775.  
  776. #ifdef QUEST
  777. cansee(x,y) xchar x,y; {
  778. register int dx,dy,adx,ady,sdx,sdy,dmax,d;
  779.     if(Blind) return(0);
  780.     if(!isok(x,y)) return(0);
  781.     d = dist(x,y);
  782.     if(d < 3) return(1);
  783.     if(d > u.uhorizon*u.uhorizon) return(0);
  784.     if(!RM_LIT(levl[x][y]))
  785.         return(0);
  786.     dx = x - u.ux;    adx = abs(dx);  sdx = sgn(dx);
  787.     dy = y - u.uy;    ady = abs(dy);  sdy = sgn(dy);
  788.     if(dx == 0 || dy == 0 || adx == ady){
  789.         dmax = (dx == 0) ? ady : adx;
  790.         for(d = 1; d <= dmax; d++)
  791.             if(!rroom(sdx*d,sdy*d))
  792.                 return(0);
  793.         return(1);
  794.     } else if(ady > adx){
  795.         for(d = 1; d <= ady; d++){
  796.             if(!rroom(sdx*( (d*adx)/ady ), sdy*d) ||
  797.                !rroom(sdx*( (d*adx-1)/ady+1 ), sdy*d))
  798.                 return(0);
  799.         }
  800.         return(1);
  801.     } else {
  802.         for(d = 1; d <= adx; d++){
  803.             if(!rroom(sdx*d, sdy*( (d*ady)/adx )) ||
  804.                !rroom(sdx*d, sdy*( (d*ady-1)/adx+1 )))
  805.                 return(0);
  806.         }
  807.         return(1);
  808.     }
  809. }
  810.  
  811. rroom(x,y) register int x,y; {
  812.     return(IS_ROOM(RM_TYP(levl[u.ux+x][u.uy+y])));
  813. }
  814.  
  815. #else
  816.  
  817. cansee(x,y) xchar x,y; {
  818.     if(Blind || u.uswallow) return(0);
  819.     if(dist(x,y) < 3) return(1);
  820.     if(RM_LIT(levl[x][y]) && seelx <= x && x <= seehx && seely <= y &&
  821.         y <= seehy) return(1);
  822.     return(0);
  823. }
  824. #endif /* QUEST /**/
  825.  
  826. sgn(a) register int a; {
  827.     return((a > 0) ? 1 : (a == 0) ? 0 : -1);
  828. }
  829.  
  830. #ifdef QUEST
  831. setsee()
  832. {
  833.     register x,y;
  834.  
  835.     if(Blind) {
  836.         pru();
  837.         return;
  838.     }
  839.     for(y = u.uy-u.uhorizon; y <= u.uy+u.uhorizon; y++)
  840.         for(x = u.ux-u.uhorizon; x <= u.ux+u.uhorizon; x++) {
  841.             if(cansee(x,y))
  842.                 prl(x,y);
  843.     }
  844. }
  845.  
  846. #else
  847.  
  848. setsee()
  849. {
  850.     register x,y;
  851.  
  852.     if(Blind) {
  853.         pru();
  854.         return;
  855.     }
  856.     if(!RM_LIT(levl[u.ux][u.uy])) {
  857.         seelx = u.ux-1;
  858.         seehx = u.ux+1;
  859.         seely = u.uy-1;
  860.         seehy = u.uy+1;
  861.     } else {
  862.         for(seelx = u.ux; RM_LIT(levl[seelx-1][u.uy]); seelx--);
  863.         for(seehx = u.ux; RM_LIT(levl[seehx+1][u.uy]); seehx++);
  864.         for(seely = u.uy; RM_LIT(levl[u.ux][seely-1]); seely--);
  865.         for(seehy = u.uy; RM_LIT(levl[u.ux][seehy+1]); seehy++);
  866.     }
  867.     for(y = seely; y <= seehy; y++)
  868.         for(x = seelx; x <= seehx; x++) {
  869.             prl(x,y);
  870.     }
  871.     if(!RM_LIT(levl[u.ux][u.uy])) seehx = 0; /* seems necessary elsewhere */
  872.     else {
  873.         if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1);
  874.         if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1);
  875.         if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y);
  876.         if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y);
  877.     }
  878. }
  879. #endif /* QUEST /**/
  880.  
  881. nomul(nval)
  882. register nval;
  883. {
  884. #ifdef DGKMOD
  885.     if(multi < nval) return;        /* This is a bug fix by ab@unido */
  886. #else
  887.     if(multi < 0) return;
  888. #endif
  889.     multi = nval;
  890.     flags.mv = flags.run = 0;
  891. }
  892.  
  893. abon()
  894. {
  895. #ifdef KAA
  896.     if (u.usym != '@') return(mons[u.umonnum].mlevel-3);
  897. #endif
  898.     if(u.ustr == 3) return(-3);
  899.     else if(u.ustr < 6) return(-2);
  900.     else if(u.ustr < 8) return(-1);
  901.     else if(u.ustr < 17) return(0);
  902.     else if(u.ustr < 69) return(1); /* up to 18/50 */
  903.     else if(u.ustr < 118) return(2);
  904.     else return(3);
  905. }
  906.  
  907. dbon()
  908. {
  909.     if (u.usym != '@') return(0);
  910.  
  911.     if(u.ustr < 6) return(-1);
  912.     else if(u.ustr < 16) return(0);
  913.     else if(u.ustr < 18) return(1);
  914.     else if(u.ustr == 18) return(2);        /* up to 18 */
  915.     else if(u.ustr < 94) return(3);         /* up to 18/75 */
  916.     else if(u.ustr < 109) return(4);        /* up to 18/90 */
  917.     else if(u.ustr < 118) return(5);        /* up to 18/99 */
  918.     else return(6);
  919. }
  920.  
  921. losestr(num)    /* may kill you; cause may be poison or monster like 'A' */
  922. register num;
  923. {
  924.     u.ustr -= num;
  925.     while(u.ustr < 3) {
  926.         u.ustr++;
  927.         u.uhp -= 6;
  928.         u.uhpmax -= 6;
  929.     }
  930.     flags.botl = 1;
  931. }
  932.  
  933. losehp(n,knam)
  934. register n;
  935. register char *knam;
  936. {
  937. #ifdef KAA
  938.     if (u.mtimedone) {
  939.         u.mh -= n;
  940.         if (u.mhmax < u.mh) u.mhmax = u.mh;
  941.         flags.botl = 1;
  942.         if (u.mh < 1) rehumanize();
  943.         return;
  944.     }
  945. #endif
  946.     u.uhp -= n;
  947.     if(u.uhp > u.uhpmax)
  948.         u.uhpmax = u.uhp;    /* perhaps n was negative */
  949.     flags.botl = 1;
  950.     if(u.uhp < 1) {
  951.         killer = knam;    /* the thing that killed you */
  952.         pline("You die...");
  953.         done("died");
  954.     }
  955. }
  956.  
  957. losehp_m(n,mtmp)
  958. register n;
  959. register struct monst *mtmp;
  960. {
  961. #ifdef KAA
  962.     if (u.mtimedone) {
  963.         u.mh -= n;
  964.         flags.botl = 1;
  965.         if (u.mh < 1) rehumanize();
  966.         return;
  967.     }
  968. #endif
  969.     u.uhp -= n;
  970.     flags.botl = 1;
  971.     if(u.uhp < 1)
  972.         done_in_by(mtmp);
  973. }
  974.  
  975. losexp()        /* hit by V or W */
  976. {
  977.     register num;
  978.     extern long newuexp();
  979.  
  980.     if (u.usym == 'V' || u.usym=='W') return;
  981.  
  982.     if(u.ulevel > 1)
  983.         pline("Goodbye level %u.", u.ulevel--);
  984.     else
  985.         u.uhp = -1;
  986.     num = rnd(10);
  987.     u.uhp -= num;
  988.     u.uhpmax -= num;
  989. #ifdef SPELLS
  990.     num = rnd(u.ulevel/2+1) + 1;            /* M. Stephenson */
  991.     u.uen -= num;
  992.     if (u.uen < 0)          u.uen = 0;
  993.     u.uenmax -= num;
  994.     if (u.uenmax < 0)       u.uenmax = 0;
  995. #endif
  996.     u.uexp = newuexp();
  997.     flags.botl = 1;
  998. }
  999.  
  1000. inv_weight(){
  1001. register struct obj *otmp = invent;
  1002. register int wt = (u.ugold + 500)/1000;
  1003. register int carrcap;
  1004. #ifdef KAA
  1005.     if (u.mtimedone) {
  1006.         if (u.usym == '9') carrcap = MAX_CARR_CAP * 4;
  1007.         else if (u.usym == 'N') carrcap = MAX_CARR_CAP;
  1008.         else if (mons[u.umonnum].mlevel <= 3)
  1009.             carrcap = 5*mons[u.umonnum].mlevel + 30;
  1010.         else carrcap = 5*mons[u.umonnum].mlevel + 100;
  1011.     }
  1012. #endif
  1013.     if(Levitation)                  /* pugh@cornell */
  1014.         carrcap = MAX_CARR_CAP;
  1015.     else {
  1016. #ifdef HARD
  1017.         carrcap = 5*(((u.ustr > 18) ? 20 : u.ustr) + u.ulevel);
  1018. #else
  1019.         carrcap = 5*u.ulevel;       /* New strength stewr 870807 */
  1020.         if (u.ustr < 19) carrcap += 5*u.ustr;
  1021.         if (u.ustr > 18) carrcap += u.ustr - 18 + 90;
  1022.         if (u.ustr > 68) carrcap += u.ustr - 68;
  1023.         if (u.ustr > 93) carrcap += u.ustr - 93;
  1024.         if (u.ustr > 108) carrcap += 2*(u.ustr - 108);
  1025.         if (u.ustr > 113) carrcap += 5*(u.ustr - 113);
  1026.         if (u.ustr == 118) carrcap += 100;
  1027. #endif
  1028.         if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP;
  1029.         if(Wounded_legs & LEFT_SIDE) carrcap -= 10;
  1030.         if(Wounded_legs & RIGHT_SIDE) carrcap -= 10;
  1031.     }
  1032.     while(otmp){
  1033.         wt += otmp->owt;
  1034.         otmp = otmp->nobj;
  1035.     }
  1036.     return(wt - carrcap);
  1037. }
  1038.  
  1039. inv_cnt(){
  1040. register struct obj *otmp = invent;
  1041. register int ct = 0;
  1042.     while(otmp){
  1043.         ct++;
  1044.         otmp = otmp->nobj;
  1045.     }
  1046.     return(ct);
  1047. }
  1048.  
  1049. long
  1050. newuexp()
  1051. {
  1052.     return(10*(1L << (u.ulevel-1)));
  1053. }
  1054.  
  1055. change_luck(n)
  1056.     register schar n;
  1057. {
  1058.     u.uluck += n;
  1059.     if (u.uluck < 0 && u.uluck < LUCKMIN)   u.uluck = LUCKMIN;
  1060.     if (u.uluck > 0 && u.uluck > LUCKMAX)   u.uluck = LUCKMAX;
  1061. }
  1062.  
  1063. #ifdef SINKS
  1064. dosinkfall() {
  1065. register struct obj *obj;
  1066.     pline("You crash to the floor!");
  1067.     losehp(rn2(15) + 3*u.ulevel,"fall onto a sink");
  1068.     for(obj=fobj; obj; obj=obj->nobj)
  1069.         if(obj->ox == u.ux && obj->oy == u.uy && obj->olet == WEAPON_SYM) {
  1070.         pline("You fell on %s.",doname(obj));
  1071.         losehp(rn2(3),"fall onto a sink");
  1072.         }
  1073.  
  1074.     Levitation += 1;
  1075.     if(uleft && uleft->otyp == RIN_LEVITATION) {
  1076.         obj = uleft;
  1077.         ringoff(obj);
  1078.         off_msg(obj);
  1079.     }
  1080.     if(uright && uright->otyp == RIN_LEVITATION) {
  1081.         obj = uright;
  1082.         ringoff(obj);
  1083.         off_msg(obj);
  1084.     }
  1085.     Levitation = 0;
  1086. }
  1087. #endif
  1088.