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

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* eat.c - version 1.0.3 */
  3.  
  4. #include    "hack.h"
  5. char POISONOUS[] = "ADKSVabhks";
  6. extern char *nomovemsg;
  7. extern int (*afternmv)();
  8. extern int (*occupation)();
  9. extern char *occtxt;
  10. extern struct obj *splitobj(), *addinv();
  11.  
  12. /* hunger texts used on bottom line (each 8 chars long) */
  13. #define    SATIATED    0
  14. #define NOT_HUNGRY    1
  15. #define    HUNGRY        2
  16. #define    WEAK        3
  17. #define    FAINTING    4
  18. #define FAINTED        5
  19. #define STARVED        6
  20.  
  21. char *hu_stat[] = {
  22.     "Satiated",
  23.     "        ",
  24.     "Hungry  ",
  25.     "Weak    ",
  26.     "Fainting",
  27.     "Fainted ",
  28.     "Starved "
  29. };
  30.  
  31. init_uhunger(){
  32.     u.uhunger = 900;
  33.     u.uhs = NOT_HUNGRY;
  34. }
  35.  
  36. #define    TTSZ    SIZE(tintxts)
  37. struct { char *txt; int nut; } tintxts[] = {
  38.     "It contains first quality peaches - what a surprise!",    40,
  39.     "It contains salmon - not bad!",    60,
  40.     "It contains apple juice - perhaps not what you hoped for.", 20,
  41.     "It contains some nondescript substance, tasting awfully.", 500,
  42.     "It contains rotten meat. You vomit.", -50,
  43.     "It turns out to be empty.",    0
  44. };
  45.  
  46. static struct {
  47.     struct obj *tin;
  48.     int usedtime, reqtime;
  49. } tin;
  50.  
  51. opentin(){
  52.     register int r;
  53.  
  54.     if(!carried(tin.tin))        /* perhaps it was stolen? */
  55.         return(0);        /* %% probably we should use tinoid */
  56.     if(tin.usedtime++ >= 50) {
  57.         pline("You give up your attempt to open the tin.");
  58.         return(0);
  59.     }
  60.     if(tin.usedtime < tin.reqtime)
  61.         return(1);        /* still busy */
  62.  
  63.     pline("You succeed in opening the tin.");
  64.     useup(tin.tin);
  65.     r = rn2(2*TTSZ);
  66.     if(r < TTSZ){
  67.         pline(tintxts[r].txt);
  68.         lesshungry(tintxts[r].nut);
  69.         if(r == 1)    /* SALMON */ {
  70.         Glib = rnd(15);
  71.         pline("Eating salmon made your fingers very slippery.");
  72.         }
  73.     } else {
  74.         pline("It contains spinach - this makes you feel like Popeye!");
  75.         lesshungry(600);
  76.         if(u.ustr < 118)
  77.         u.ustr += rnd( ((u.ustr < 17) ? 19 : 118) - u.ustr);
  78.         if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
  79.         flags.botl = 1;
  80.     }
  81.     return(0);
  82. }
  83.  
  84. Meatdone(){
  85.     u.usym = '@';
  86.     prme();
  87. }
  88.  
  89. doeat(){
  90.     register struct obj *otmp;
  91.     register struct objclass *ftmp;
  92.     register tmp;
  93.  
  94.     /* Is there some food (probably a heavy corpse) here on the ground? */
  95.     if(!Levitation)
  96.     for(otmp = fobj; otmp; otmp = otmp->nobj) {
  97.         if(otmp->ox == u.ux && otmp->oy == u.uy &&
  98.            otmp->olet == FOOD_SYM) {
  99.             pline("There %s %s here; eat %s? [ny] ",
  100.                 (otmp->quan == 1) ? "is" : "are",
  101.                 doname(otmp),
  102.                 (otmp->quan == 1) ? "it" : "one");
  103.             if(readchar() == 'y') {
  104.                 if(otmp->quan != 1)
  105.                     (void) splitobj(otmp, 1);
  106.                 freeobj(otmp);
  107.                 addtobill(otmp);
  108.                 otmp = addinv(otmp);
  109.                 goto gotit;
  110.             }
  111.         }
  112.     }
  113.     otmp = getobj("%", "eat");
  114.     if(!otmp) return(0);
  115. gotit:
  116.     if(otmp->otyp == TIN){
  117.         if(uwep) {
  118.             switch(uwep->otyp) {
  119.             case CAN_OPENER:
  120.                 tmp = 1;
  121.                 break;
  122.             case DAGGER:
  123.             case CRYSKNIFE:
  124.                 tmp = 3;
  125.                 break;
  126.             case PICK_AXE:
  127.             case AXE:
  128.                 tmp = 6;
  129.                 break;
  130.             default:
  131.                 goto no_opener;
  132.             }
  133.             pline("Using your %s you try to open the tin.",
  134.                 aobjnam(uwep, (char *) 0));
  135.         } else {
  136.         no_opener:
  137.             pline("It is not so easy to open this tin.");
  138.             if(Glib) {
  139.                 pline("The tin slips out of your hands.");
  140.                 if(otmp->quan > 1) {
  141.                     register struct obj *obj;
  142.                     extern struct obj *splitobj();
  143.  
  144.                     obj = splitobj(otmp, 1);
  145.                     if(otmp == uwep) setuwep(obj);
  146.                 }
  147.                 dropx(otmp);
  148.                 return(1);
  149.             }
  150.             tmp = 10 + rn2(1 + 500/((int)(u.ulevel + u.ustr)));
  151.         }
  152.         tin.reqtime = tmp;
  153.         tin.usedtime = 0;
  154.         tin.tin = otmp;
  155.         occupation = opentin;
  156.         occtxt = "opening the tin";
  157.         return(1);
  158.     }
  159.     ftmp = &objects[otmp->otyp];
  160.     multi = -ftmp->oc_delay;
  161.     if(otmp->otyp >= CORPSE && eatcorpse(otmp)) goto eatx;
  162. #ifdef DGK
  163.     if(!rn2(7) && otmp->otyp != FORTUNE_COOKIE && otmp->otyp != DEAD_LIZARD) {
  164. #else
  165.     if(!rn2(7) && otmp->otyp != FORTUNE_COOKIE) {
  166. #endif DGK
  167.         pline("Blecch!  Rotten food!");
  168.         if(!rn2(4)) {
  169.             pline("You feel rather light headed.");
  170.             Confusion += d(2,4);
  171.         } else if(!rn2(4)&& !Blind) {
  172.             pline("Everything suddenly goes dark.");
  173.             Blind = d(2,10);
  174.             seeoff(0);
  175.         } else if(!rn2(3)) {
  176.             if(Blind)
  177.               pline("The world spins and you slap against the floor.");
  178.             else
  179.               pline("The world spins and goes dark.");
  180.             nomul(-rnd(10));
  181.             nomovemsg = "You are conscious again.";
  182.         }
  183.         lesshungry(ftmp->nutrition / 4);
  184.     } else {
  185.         if(u.uhunger >= 1500) {
  186.             pline("You choke over your food.");
  187.             pline("You die...");
  188.             killer = ftmp->oc_name;
  189.             done("choked");
  190.         }
  191.         switch(otmp->otyp){
  192.         case FOOD_RATION:
  193.             if(u.uhunger <= 200)
  194.                 pline("That food really hit the spot!");
  195.             else if(u.uhunger <= 700)
  196.                 pline("That satiated your stomach!");
  197. #ifdef DGK
  198.     /* Have lesshungry() report when you're nearly full so all eating
  199.      * warns when you're about to choke.
  200.      */
  201.             lesshungry(ftmp->nutrition);
  202. #else
  203.             else {
  204.     pline("You're having a hard time getting all that food down.");
  205.                 multi -= 2;
  206.             }
  207.             lesshungry(ftmp->nutrition);
  208.             if(multi < 0) nomovemsg = "You finished your meal.";
  209. #endif DGK
  210.             break;
  211.         case TRIPE_RATION:
  212.             pline("Yak - dog food!");
  213.             more_experienced(1,0);
  214.             flags.botl = 1;
  215.             if(rn2(2)){
  216.                 pline("You vomit.");
  217.                 morehungry(20);
  218.                 if(Sick) {
  219.                     Sick = 0;    /* David Neves */
  220.                     pline("What a relief!");
  221.                 }
  222.             } else    lesshungry(ftmp->nutrition);
  223.             break;
  224.         default:
  225.             if(otmp->otyp >= CORPSE)
  226.             pline("That %s tasted terrible!",ftmp->oc_name);
  227.             else
  228.             pline("That %s was delicious!",ftmp->oc_name);
  229.             lesshungry(ftmp->nutrition);
  230. #ifdef DGK
  231.             /* Relief from cockatrices -dgk */
  232.             if (otmp->otyp == DEAD_LIZARD) {
  233.                 if (Stoned) {
  234.                     Stoned = 0;
  235.                     pline("You feel more limber!");
  236.                 }
  237.                 if (Confusion > 2)
  238.                     Confusion = 2;
  239.             }
  240. #else
  241.             if(otmp->otyp == DEAD_LIZARD && (Confusion > 2))
  242.                 Confusion = 2;
  243. #endif DGK
  244.             else
  245. #ifdef QUEST
  246.             if(otmp->otyp == CARROT && !Blind){
  247.                 u.uhorizon++;
  248.                 setsee();
  249.                 pline("Your vision improves.");
  250.             } else
  251. #endif QUEST
  252.             if(otmp->otyp == FORTUNE_COOKIE) {
  253.               if(Blind) {
  254.                 pline("This cookie has a scrap of paper inside!");
  255.                 pline("What a pity, that you cannot read it!");
  256.               } else
  257.                 outrumor();
  258.             } else
  259.             if(otmp->otyp == LUMP_OF_ROYAL_JELLY) {
  260.                 /* This stuff seems to be VERY healthy! */
  261.                 if(u.ustrmax < 118) u.ustrmax++;
  262.                 if(u.ustr < u.ustrmax) u.ustr++;
  263.                 u.uhp += rnd(20);
  264.                 if(u.uhp > u.uhpmax) {
  265.                     if(!rn2(17)) u.uhpmax++;
  266.                     u.uhp = u.uhpmax;
  267.                 }
  268.                 heal_legs();
  269.             }
  270.             break;
  271.         }
  272.     }
  273. eatx:
  274.     if(multi<0 && !nomovemsg){
  275.         static char msgbuf[BUFSZ];
  276.         (void) sprintf(msgbuf, "You finished eating the %s.",
  277.                 ftmp->oc_name);
  278.         nomovemsg = msgbuf;
  279.     }
  280.     useup(otmp);
  281.     return(1);
  282. }
  283.  
  284. /* called in main.c */
  285. gethungry(){
  286.     --u.uhunger;
  287.     if(moves % 2) {
  288.         if(Regeneration) u.uhunger--;
  289.         if(Hunger) u.uhunger--;
  290.         /* a3:  if(Hunger & LEFT_RING) u.uhunger--;
  291.             if(Hunger & RIGHT_RING) u.uhunger--;
  292.            etc. */
  293.     }
  294.     if(moves % 20 == 0) {            /* jimt@asgb */
  295.         if(uleft) u.uhunger--;
  296.         if(uright) u.uhunger--;
  297.     }
  298.     newuhs(TRUE);
  299. }
  300.  
  301. /* called after vomiting and after performing feats of magic */
  302. morehungry(num) register num; {
  303.     u.uhunger -= num;
  304.     newuhs(TRUE);
  305. }
  306.  
  307. /* called after eating something (and after drinking fruit juice) */
  308. lesshungry(num) register num; {
  309.     u.uhunger += num;
  310. #ifdef DGK
  311.     /* Have lesshungry() report when you're nearly full so all eating
  312.      * warns when you're about to choke.
  313.      */
  314.     if (u.uhunger >= 1500) {
  315.         pline("You're having a hard time getting all of it down.");
  316.         multi -= 2;
  317.         nomovemsg = "You're finally finished.";
  318.     }
  319. #endif DGK
  320.     newuhs(FALSE);
  321. }
  322.  
  323. unfaint(){
  324.     u.uhs = FAINTING;
  325.     flags.botl = 1;
  326. }
  327.  
  328. newuhs(incr) boolean incr; {
  329.     register int newhs, h = u.uhunger;
  330.  
  331.     newhs = (h > 1000) ? SATIATED :
  332.         (h > 150) ? NOT_HUNGRY :
  333.         (h > 50) ? HUNGRY :
  334.         (h > 0) ? WEAK : FAINTING;
  335.  
  336.     if(newhs == FAINTING) {
  337.         if(u.uhs == FAINTED)
  338.             newhs = FAINTED;
  339.         if(u.uhs <= WEAK || rn2(20-u.uhunger/10) >= 19) {
  340.             if(u.uhs != FAINTED && multi >= 0 /* %% */) {
  341.                 pline("You faint from lack of food.");
  342.                 nomul(-10+(u.uhunger/10));
  343.                 nomovemsg = "You regain consciousness.";
  344.                 afternmv = unfaint;
  345.                 newhs = FAINTED;
  346.             }
  347.         } else
  348.         if(u.uhunger < -(int)(200 + 25*u.ulevel)) {
  349.             u.uhs = STARVED;
  350.             flags.botl = 1;
  351.             bot();
  352.             pline("You die from starvation.");
  353.             done("starved");
  354.         }
  355.     }
  356.  
  357.     if(newhs != u.uhs) {
  358.         if(newhs >= WEAK && u.uhs < WEAK)
  359.             losestr(1);    /* this may kill you -- see below */
  360.         else
  361.         if(newhs < WEAK && u.uhs >= WEAK && u.ustr < u.ustrmax)
  362.             losestr(-1);
  363.         switch(newhs){
  364.         case HUNGRY:
  365.             pline((!incr) ? "You only feel hungry now." :
  366.                   (u.uhunger < 145) ? "You feel hungry." :
  367.                 "You are beginning to feel hungry.");
  368.             break;
  369.         case WEAK:
  370.             pline((!incr) ? "You feel weak now." :
  371.                   (u.uhunger < 45) ? "You feel weak." :
  372.                 "You are beginning to feel weak.");
  373.             break;
  374.         }
  375.         u.uhs = newhs;
  376.         flags.botl = 1;
  377.         if(u.uhp < 1) {
  378.             pline("You die from hunger and exhaustion.");
  379.             killer = "exhaustion";
  380.             done("starved");
  381.         }
  382.     }
  383. }
  384.  
  385. #define    CORPSE_I_TO_C(otyp)    (char) ((otyp >= DEAD_ACID_BLOB)\
  386.              ?  'a' + (otyp - DEAD_ACID_BLOB)\
  387.              :    '@' + (otyp - DEAD_HUMAN))
  388. poisonous(otmp)
  389. register struct obj *otmp;
  390. {
  391.     return(index(POISONOUS, CORPSE_I_TO_C(otmp->otyp)) != 0);
  392. }
  393.  
  394. /* returns 1 if some text was printed */
  395. eatcorpse(otmp) register struct obj *otmp; {
  396. register char let = CORPSE_I_TO_C(otmp->otyp);
  397. register tp = 0;
  398.     if(let != 'a' && moves > otmp->age + 50 + rn2(100)) {
  399.         tp++;
  400.         pline("Ulch -- that meat was tainted!");
  401.         pline("You get very sick.");
  402.         Sick = 10 + rn2(10);
  403.         u.usick_cause = objects[otmp->otyp].oc_name;
  404.     } else if(index(POISONOUS, let) && rn2(5)){
  405.         tp++;
  406.         pline("Ecch -- that must have been poisonous!");
  407.         if(!Poison_resistance){
  408.             losestr(rnd(4));
  409.             losehp(rnd(15), "poisonous corpse");
  410.         } else
  411.             pline("You don't seem affected by the poison.");
  412.     } else if(index("ELNOPQRUuxz", let) && rn2(5)){
  413.         tp++;
  414.         pline("You feel sick.");
  415.         losehp(rnd(8), "cadaver");
  416.     }
  417.     switch(let) {
  418.     case 'L':
  419.     case 'N':
  420.     case 't':
  421.         Teleportation |= INTRINSIC;
  422.         break;
  423.     case 'W':
  424.         pluslvl();
  425.         break;
  426.     case 'n':
  427.         u.uhp = u.uhpmax;
  428.         flags.botl = 1;
  429.         /* fall into next case */
  430.     case '@':
  431.         pline("You cannibal! You will be sorry for this!");
  432.         /* not tp++; */
  433.         /* fall into next case */
  434.     case 'd':
  435.         Aggravate_monster |= INTRINSIC;
  436.         break;
  437.     case 'I':
  438.         if(!Invis) {
  439.             Invis = 50+rn2(100);
  440.             if(!See_invisible)
  441.                 newsym(u.ux, u.uy);
  442.         } else {
  443.             Invis |= INTRINSIC;
  444.             See_invisible |= INTRINSIC;
  445.         }
  446.         /* fall into next case */
  447.     case 'y':
  448. #ifdef QUEST
  449.         u.uhorizon++;
  450. #endif QUEST
  451.         /* fall into next case */
  452.     case 'B':
  453.         Confusion = 50;
  454.         break;
  455.     case 'D':
  456.         Fire_resistance |= INTRINSIC;
  457.         break;
  458.     case 'E':
  459.         Telepat |= INTRINSIC;
  460.         break;
  461.     case 'F':
  462.     case 'Y':
  463.         Cold_resistance |= INTRINSIC;
  464.         break;
  465.     case 'k':
  466.     case 's':
  467.         Poison_resistance |= INTRINSIC;
  468.         break;
  469.     case 'c':
  470.         pline("You turn to stone.");
  471.         killer = "dead cockatrice";
  472.         done("died");
  473.         /* NOTREACHED */
  474.     case 'a':
  475.       if(Stoned) {
  476.           pline("What a pity - you just destroyed a future piece of art!");
  477.           tp++;
  478.           Stoned = 0;
  479.       }
  480.       break;
  481.     case 'M':
  482.       pline("You cannot resist the temptation to mimic a treasure chest.");
  483.       tp++;
  484.       nomul(-30);
  485.       afternmv = Meatdone;
  486.       nomovemsg = "You now again prefer mimicking a human.";
  487.       u.usym = '$';
  488.       prme();
  489.       break;
  490.     }
  491.     return(tp);
  492. }
  493.