home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / eat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  47.7 KB  |  1,921 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)eat.c    3.1    93/05/19    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. /*#define DEBUG        /* uncomment to enable new eat code debugging */
  7.  
  8. #ifdef DEBUG
  9. # ifdef WIZARD
  10. #define debugpline    if (wizard) pline
  11. # else
  12. #define debugpline    pline
  13. # endif
  14. #endif
  15.  
  16. STATIC_PTR int NDECL(eatmdone);
  17. STATIC_PTR int NDECL(eatfood);
  18. STATIC_PTR int NDECL(opentin);
  19. STATIC_PTR int NDECL(unfaint);
  20.  
  21. #ifdef OVLB
  22. static void FDECL(choke, (struct obj *));
  23. static void NDECL(recalc_wt);
  24. static struct obj *FDECL(touchfood, (struct obj *));
  25. static void NDECL(do_reset_eat);
  26. static void FDECL(done_eating, (BOOLEAN_P));
  27. static void FDECL(cprefx, (int));
  28. static int FDECL(intrinsic_possible, (int,struct permonst *));
  29. static void FDECL(givit, (int,struct permonst *));
  30. static void FDECL(cpostfx, (int));
  31. static void FDECL(start_tin, (struct obj *));
  32. static int FDECL(eatcorpse, (struct obj *));
  33. static void FDECL(start_eating, (struct obj *));
  34. static void FDECL(fprefx, (struct obj *));
  35. static void FDECL(fpostfx, (struct obj *));
  36. static int NDECL(bite);
  37.  
  38. #ifdef POLYSELF
  39. static int FDECL(rottenfood, (struct obj *));
  40. static void NDECL(eatspecial);
  41. static void FDECL(eatring, (struct obj *));
  42. static const char * FDECL(foodword, (struct obj *));
  43. #else
  44. static int NDECL(rottenfood);
  45. #endif /* POLYSELF */
  46.  
  47. char corpsename[60];
  48. char msgbuf[BUFSZ];
  49.  
  50. #endif /* OVLB */
  51.  
  52. /* hunger texts used on bottom line (each 8 chars long) */
  53. #define SATIATED    0
  54. #define NOT_HUNGRY    1
  55. #define HUNGRY        2
  56. #define WEAK        3
  57. #define FAINTING    4
  58. #define FAINTED        5
  59. #define STARVED        6
  60.  
  61. #ifdef OVLB
  62.  
  63. const char *hu_stat[] = {
  64.     "Satiated",
  65.     "        ",
  66.     "Hungry  ",
  67.     "Weak    ",
  68.     "Fainting",
  69.     "Fainted ",
  70.     "Starved "
  71. };
  72.  
  73. #endif /* OVLB */
  74.  
  75. #ifndef OVLB
  76.  
  77. STATIC_DCL NEARDATA const char comestibles[];
  78. #ifdef POLYSELF
  79. STATIC_OVL NEARDATA const char allobj[];
  80. #endif /* POLYSELF */
  81.  
  82. #else
  83.  
  84. STATIC_OVL NEARDATA const char comestibles[] = { FOOD_CLASS, 0 };
  85.  
  86. #ifdef POLYSELF
  87. /* Gold must come first for getobj(). */
  88. STATIC_OVL NEARDATA const char allobj[] = {
  89.     GOLD_CLASS, WEAPON_CLASS, ARMOR_CLASS, POTION_CLASS, SCROLL_CLASS,
  90.     WAND_CLASS, RING_CLASS, AMULET_CLASS, FOOD_CLASS, TOOL_CLASS,
  91.     GEM_CLASS, ROCK_CLASS, BALL_CLASS, CHAIN_CLASS, SPBOOK_CLASS, 0 };
  92. #endif /* POLYSELF */
  93.  
  94. #endif /* OVLB */
  95. #ifdef OVL1
  96. # ifdef POLYSELF
  97.  
  98. boolean
  99. is_edible(obj)
  100. register struct obj *obj;
  101. {
  102.     if (metallivorous(uasmon) && is_metallic(obj))
  103.         return TRUE;
  104.     if (u.umonnum == PM_GELATINOUS_CUBE && is_organic(obj))
  105.         return TRUE;
  106.     return((boolean)(!!index(comestibles, obj->oclass)));
  107. }
  108. # endif /* POLYSELF */
  109. #endif /* OVL1 */
  110. #ifdef OVLB
  111.  
  112. void
  113. init_uhunger()
  114. {
  115.     u.uhunger = 900;
  116.     u.uhs = NOT_HUNGRY;
  117. }
  118.  
  119. static const struct { const char *txt; int nut; } tintxts[] = {
  120.     {"deep fried",     60},
  121.     {"pickled",     40},
  122.     {"soup made from", 20},
  123.     {"pureed",    500},
  124.     {"rotten",    -50},
  125.     {"homemade",     50},
  126.     {"", 0}
  127. };
  128. #define    TTSZ    SIZE(tintxts)
  129.  
  130. static NEARDATA struct {
  131.     struct    obj *tin;
  132.     int    usedtime, reqtime;
  133. } tin;
  134.  
  135. static NEARDATA struct {
  136.     struct    obj *piece;    /* the thing being eaten, or last thing that
  137.                  * was partially eaten, unless that thing was
  138.                  * a tin, which uses the tin structure above */
  139.     int    usedtime,    /* turns spent eating */
  140.         reqtime;    /* turns required to eat */
  141.     int    nmod;        /* coded nutrition per turn */
  142.     Bitfield(canchoke,1);    /* was satiated at beginning */
  143.     Bitfield(fullwarn,1);    /* have warned about being full */
  144.     Bitfield(eating,1);    /* victual currently being eaten */
  145.     Bitfield(doreset,1);    /* stop eating at end of turn */
  146. } victual;
  147.  
  148. STATIC_PTR
  149. int
  150. eatmdone()        /* called after mimicing is over */
  151. {
  152.     u.usym =
  153. #ifdef POLYSELF
  154.         u.mtimedone ? uasmon->mlet :
  155. #endif
  156.         S_HUMAN;
  157.     newsym(u.ux,u.uy);
  158.     return 0;
  159. }
  160.  
  161. /* Created by GAN 01/28/87
  162.  * Amended by AKP 09/22/87: if not hard, don't choke, just vomit.
  163.  * Amended by 3.  06/12/89: if not hard, sometimes choke anyway, to keep risk.
  164.  *          11/10/89: if hard, rarely vomit anyway, for slim chance.
  165.  */
  166. /*ARGSUSED*/
  167. static void
  168. choke(food)    /* To a full belly all food is bad. (It.) */
  169.     register struct obj *food;
  170. {
  171.     /* only happens if you were satiated */
  172.     if(u.uhs != SATIATED) return;
  173.  
  174.     if (pl_character[0] == 'K' && u.ualign.type == A_LAWFUL)
  175.         u.ualign.record--;    /* gluttony is unchivalrous */
  176.  
  177.     exercise(A_CON, FALSE);
  178.  
  179.     if (!rn2(20) || Breathless) {
  180.         You("stuff yourself and then vomit voluminously.");
  181.         morehungry(1000);    /* you just got *very* sick! */
  182.         vomit();
  183.     } else {
  184.         killer_format = KILLED_BY_AN;
  185.         /*
  186.          * Note all "killer"s below read "Choked on %s" on the
  187.          * high score list & tombstone.  So plan accordingly.
  188.          */
  189.         if(food) {
  190. #ifdef POLYSELF
  191.             You("choke over your %s.", foodword(food));
  192.             if (food->oclass == GOLD_CLASS) {
  193.                 killer_format = KILLED_BY;
  194.                 killer = "eating too rich a meal";
  195.             } else {
  196. #else
  197.                 You("choke over your food.");
  198. #endif
  199.                 killer = singular(food, xname);
  200. #ifdef POLYSELF
  201.             }
  202. #endif
  203.         } else {
  204.             You("choke over it.");
  205.             killer = "quick snack";
  206.         }
  207.         You("die...");
  208.         done(CHOKING);
  209.     }
  210. }
  211.  
  212. static void
  213. recalc_wt()    /* modify object wt. depending on time spent consuming it */
  214. {
  215.     register struct obj *piece = victual.piece;
  216.  
  217. #ifdef DEBUG
  218.     debugpline("Old weight = %d", piece->owt);
  219.     debugpline("Used time = %d, Req'd time = %d",
  220.         victual.usedtime, victual.reqtime);
  221. #endif
  222.     /* weight(piece) = weight of full item */
  223.     if(victual.usedtime)
  224.         piece->owt = eaten_stat(weight(piece), piece);
  225. #ifdef DEBUG
  226.     debugpline("New weight = %d", piece->owt);
  227. #endif
  228. }
  229.  
  230. void
  231. reset_eat()        /* called when eating interrupted by an event */
  232. {
  233.     /* we only set a flag here - the actual reset process is done after
  234.      * the round is spent eating.
  235.      */
  236.     if(victual.eating && !victual.doreset) {
  237. #ifdef DEBUG
  238.         debugpline("reset_eat...");
  239. #endif
  240.         victual.doreset = TRUE;
  241.     }
  242.     return;
  243. }
  244.  
  245. void
  246. bill_dummy_object(otmp)
  247. register struct obj *otmp;
  248. {
  249.     /* Create a dummy duplicate to put on bill.  The duplicate exists
  250.      * only in the billobjs chain.  This function is used when a store
  251.      * object is being altered, and a copy of the original is needed
  252.      * for billing purposes.
  253.      */
  254.     register struct obj *dummy;
  255.  
  256.     if(otmp->unpaid)
  257.         subfrombill(otmp, shop_keeper(*u.ushops));
  258.     dummy = newobj(otmp->onamelth);
  259.     *dummy = *otmp;
  260.     dummy->o_id = flags.ident++;
  261.     dummy->owt = weight(dummy);
  262.     if(otmp->onamelth)
  263.         (void)strncpy(ONAME(dummy),ONAME(otmp), (int)otmp->onamelth);
  264.     if(Is_candle(dummy)) dummy->lamplit = 0;
  265.     addtobill(dummy, FALSE, TRUE, TRUE);
  266. }
  267.  
  268. static struct obj *
  269. touchfood(otmp)
  270. register struct obj *otmp;
  271. {
  272.     if (otmp->quan > 1L) {
  273.         if(!carried(otmp))
  274.         (void) splitobj(otmp, 1L);
  275.         else
  276.         otmp = splitobj(otmp, otmp->quan - 1L);
  277. #ifdef DEBUG
  278.         debugpline("split object,");
  279. #endif
  280.     }
  281.  
  282.     if (!otmp->oeaten) {
  283.         if(((!carried(otmp) && costly_spot(otmp->ox, otmp->oy) &&
  284.          !otmp->no_charge)
  285.          || otmp->unpaid) &&
  286.          (otmp->otyp == CORPSE || objects[otmp->otyp].oc_delay > 1)) {
  287.         /* create a dummy duplicate to put on bill */
  288.         verbalize("You bit it, you bought it!");
  289.         bill_dummy_object(otmp);
  290.         otmp->no_charge = 1;    /* you now own this */
  291.         }
  292.         otmp->oeaten = (otmp->otyp == CORPSE ?
  293.                 (int)mons[otmp->corpsenm].cnutrit :
  294.                 objects[otmp->otyp].oc_nutrition);
  295.     }
  296.  
  297.     if (carried(otmp)) {
  298.         freeinv(otmp);
  299.         if(inv_cnt() >= 52)
  300.         dropy(otmp);
  301.         else
  302.         otmp = addinv(otmp); /* unlikely but a merge is possible */
  303.     }
  304.     return(otmp);
  305. }
  306.  
  307. /* When food decays, in the middle of your meal, we don't want to dereference
  308.  * any dangling pointers, so set it to null (which should still trigger
  309.  * do_reset_eat() at the beginning of eatfood()) and check for null pointers
  310.  * in do_reset_eat().
  311.  */
  312. void
  313. food_disappears(obj)
  314. register struct obj *obj;
  315. {
  316.     if (obj == victual.piece) victual.piece = (struct obj *)0;
  317. }
  318.  
  319. static void
  320. do_reset_eat() {
  321.  
  322. #ifdef DEBUG
  323.     debugpline("do_reset_eat...");
  324. #endif
  325.     if (victual.piece) {
  326.         victual.piece = touchfood(victual.piece);
  327.         recalc_wt();
  328.     }
  329.     victual.fullwarn = victual.eating = victual.doreset = FALSE;
  330.     /* Do not set canchoke to FALSE; if we continue eating the same object
  331.      * we need to know if canchoke was set when they started eating it the
  332.      * previous time.  And if we don't continue eating the same object
  333.      * canchoke always gets recalculated anyway.
  334.      */
  335.     stop_occupation();
  336. }
  337.  
  338. STATIC_PTR
  339. int
  340. eatfood()        /* called each move during eating process */
  341. {
  342.     if(!carried(victual.piece) && !obj_here(victual.piece, u.ux, u.uy)) {
  343.         /* maybe it was stolen? */
  344.         do_reset_eat();
  345.         return(0);
  346.     }
  347.     if(!victual.eating) return(0);
  348.  
  349.     if(++victual.usedtime <= victual.reqtime) {
  350.         if(bite()) return(0);
  351.         return(1);    /* still busy */
  352.     } else {    /* done */
  353.         done_eating(TRUE);
  354.         return(0);
  355.     }
  356. }
  357.  
  358. static void
  359. done_eating(message)
  360. boolean message;
  361. {
  362. #ifndef NO_SIGNAL
  363.     victual.piece->in_use = TRUE;
  364. #endif
  365.     if (nomovemsg) {
  366.         if (message) pline(nomovemsg);
  367.         nomovemsg = 0;
  368.     } else if (message)
  369.         You("finish eating %s.", the(singular(victual.piece, xname)));
  370.  
  371.     if(victual.piece->otyp == CORPSE)
  372.         cpostfx(victual.piece->corpsenm);
  373.     else
  374.         fpostfx(victual.piece);
  375.  
  376.     if (carried(victual.piece)) useup(victual.piece);
  377.     else useupf(victual.piece);
  378.     victual.piece = (struct obj *) 0;
  379.     victual.fullwarn = victual.eating = victual.doreset = FALSE;
  380. }
  381.  
  382. static void
  383. cprefx(pm)
  384. register int pm;
  385. {
  386.     if ((pl_character[0]=='E') ? is_elf(&mons[pm]) : is_human(&mons[pm])) {
  387. #ifdef POLYSELF
  388.         if (uasmon != &playermon) {
  389.             You("have a bad feeling deep inside.");
  390.         }
  391. #endif /* POLYSELF */
  392.         You("cannibal!  You will regret this!");
  393.         Aggravate_monster |= FROMOUTSIDE;
  394.     }
  395.  
  396.     switch(pm) {
  397.         case PM_LITTLE_DOG:
  398.         case PM_DOG:
  399.         case PM_LARGE_DOG:
  400.         case PM_KITTEN:
  401.         case PM_HOUSECAT:
  402.         case PM_LARGE_CAT:
  403.         You("feel that eating the %s was a bad idea.", mons[pm].mname);
  404.         Aggravate_monster |= FROMOUTSIDE;
  405.         break;
  406.         case PM_COCKATRICE:
  407.         case PM_MEDUSA:
  408. #ifdef POLYSELF
  409.         if(!resists_ston(uasmon))
  410.             if(!(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)))
  411. #endif
  412.             {
  413.             char *cruft;    /* killer is const char * */
  414.             killer_format = KILLED_BY;
  415.             killer = cruft = (char *)  /* sizeof "s" includes \0 */
  416.                     alloc((unsigned) strlen(mons[pm].mname)
  417.                         + sizeof " meat");
  418.             Sprintf(cruft, "%s meat", mons[pm].mname);
  419.             You("turn to stone.");
  420.             done(STONING);
  421.             }
  422.             break;
  423.         case PM_LIZARD:
  424.         /* Relief from cockatrices -dgk */
  425.         if (Stoned) {
  426.             Stoned = 0;
  427.             You("feel limber!");
  428.         }
  429.         break;
  430.         case PM_DEATH:
  431.         case PM_PESTILENCE:
  432.         case PM_FAMINE:
  433.         { char buf[BUFSZ];
  434.             pline("Eating that is instantly fatal.");
  435.             Sprintf(buf, "unwisely ate the body of %s",
  436.                 mons[pm].mname);
  437.             killer = buf;
  438.             killer_format = NO_KILLER_PREFIX;
  439.             done(DIED);
  440.             /* It so happens that since we know these monsters */
  441.             /* cannot appear in tins, victual.piece will always */
  442.             /* be what we want, which is not generally true. */
  443.             revive_corpse(victual.piece, 0, FALSE);
  444.             return;
  445.         }
  446.         default:
  447.         if(acidic(&mons[pm]) && Stoned) {
  448.             pline("What a pity - you just destroyed a future piece of art!");
  449.             Stoned = 0;
  450.         }
  451.     }
  452.     return;
  453. }
  454.  
  455.  
  456. /*
  457.  * If you add an intrinsic that can be gotten by eating a monster, add it
  458.  * to intrinsic_possible() and givit().  (It must already be in prop.h to
  459.  * be an intrinsic property.)
  460.  * It would be very easy to make the intrinsics not try to give you one
  461.  * that you already had by checking to see if you have it in
  462.  * intrinsic_possible() instead of givit().
  463.  */
  464.  
  465. /* intrinsic_possible() returns TRUE iff a monster can give an intrinsic. */
  466. static int
  467. intrinsic_possible(type, ptr)
  468. int type;
  469. register struct permonst *ptr;
  470. {
  471.     switch (type) {
  472.         case FIRE_RES:
  473. #ifdef DEBUG
  474.         if (ptr->mconveys & MR_FIRE) {
  475.             debugpline("can get fire resistance");
  476.             return(TRUE);
  477.         } else  return(FALSE);
  478. #else
  479.         return(ptr->mconveys & MR_FIRE);
  480. #endif
  481.         case SLEEP_RES:
  482. #ifdef DEBUG
  483.         if (ptr->mconveys & MR_SLEEP) {
  484.             debugpline("can get sleep resistance");
  485.             return(TRUE);
  486.         } else  return(FALSE);
  487. #else
  488.         return(ptr->mconveys & MR_SLEEP);
  489. #endif
  490.         case COLD_RES:
  491. #ifdef DEBUG
  492.         if (ptr->mconveys & MR_COLD) {
  493.             debugpline("can get cold resistance");
  494.             return(TRUE);
  495.         } else  return(FALSE);
  496. #else
  497.         return(ptr->mconveys & MR_COLD);
  498. #endif
  499.         case DISINT_RES:
  500. #ifdef DEBUG
  501.         if (ptr->mconveys & MR_DISINT) {
  502.             debugpline("can get disintegration resistance");
  503.             return(TRUE);
  504.         } else  return(FALSE);
  505. #else
  506.         return(ptr->mconveys & MR_DISINT);
  507. #endif
  508.         case SHOCK_RES:    /* shock (electricity) resistance */
  509. #ifdef DEBUG
  510.         if (ptr->mconveys & MR_ELEC) {
  511.             debugpline("can get shock resistance");
  512.             return(TRUE);
  513.         } else  return(FALSE);
  514. #else
  515.         return(ptr->mconveys & MR_ELEC);
  516. #endif
  517.         case POISON_RES:
  518. #ifdef DEBUG
  519.         if (ptr->mconveys & MR_POISON) {
  520.             debugpline("can get poison resistance");
  521.             return(TRUE);
  522.         } else  return(FALSE);
  523. #else
  524.         return(ptr->mconveys & MR_POISON);
  525. #endif
  526.         case TELEPORT:
  527. #ifdef DEBUG
  528.         if (can_teleport(ptr)) {
  529.             debugpline("can get teleport");
  530.             return(TRUE);
  531.         } else  return(FALSE);
  532. #else
  533.         return(can_teleport(ptr));
  534. #endif
  535.         case TELEPORT_CONTROL:
  536. #ifdef DEBUG
  537.         if (control_teleport(ptr)) {
  538.             debugpline("can get teleport control");
  539.             return(TRUE);
  540.         } else  return(FALSE);
  541. #else
  542.         return(control_teleport(ptr));
  543. #endif
  544.         case TELEPAT:
  545. #ifdef DEBUG
  546.         if (telepathic(ptr)) {
  547.             debugpline("can get telepathy");
  548.             return(TRUE);
  549.         } else  return(FALSE);
  550. #else
  551.         return(telepathic(ptr));
  552. #endif
  553.         default:
  554.         return(FALSE);
  555.     }
  556.     /*NOTREACHED*/
  557. }
  558.  
  559. /* givit() tries to give you an intrinsic based on the monster's level
  560.  * and what type of intrinsic it is trying to give you.
  561.  */
  562. static void
  563. givit(type, ptr)
  564. int type;
  565. register struct permonst *ptr;
  566. {
  567.     register int chance;
  568.  
  569. #ifdef DEBUG
  570.     debugpline("Attempting to give intrinsic %d", type);
  571. #endif
  572.     /* some intrinsics are easier to get than others */
  573.     switch (type) {
  574.         case POISON_RES:
  575.             if ((ptr == &mons[PM_KILLER_BEE] ||
  576.                     ptr == &mons[PM_SCORPION]) && !rn2(4))
  577.                 chance = 1;
  578.             else
  579.                 chance = 15;
  580.             break;
  581.         case TELEPORT:
  582.             chance = 10;
  583.             break;
  584.         case TELEPORT_CONTROL:
  585.             chance = 12;
  586.             break;
  587.         case TELEPAT:
  588.             chance = 1;
  589.             break;
  590.         default:
  591.             chance = 15;
  592.             break;
  593.     }
  594.  
  595.     if (ptr->mlevel <= rn2(chance))
  596.         return;        /* failed die roll */
  597.  
  598.     switch (type) {
  599.         case FIRE_RES:
  600. #ifdef DEBUG
  601.         debugpline("Trying to give fire resistance");
  602. #endif
  603.         if(!(HFire_resistance & FROMOUTSIDE)) {
  604.             You(Hallucination ? "be chillin'." :
  605.                 "feel a momentary chill.");
  606.             HFire_resistance |= FROMOUTSIDE;
  607.         }
  608.         break;
  609.         case SLEEP_RES:
  610. #ifdef DEBUG
  611.         debugpline("Trying to give sleep resistance");
  612. #endif
  613.         if(!(HSleep_resistance & FROMOUTSIDE)) {
  614.             You("feel wide awake.");
  615.             HSleep_resistance |= FROMOUTSIDE;
  616.         }
  617.         break;
  618.         case COLD_RES:
  619. #ifdef DEBUG
  620.         debugpline("Trying to give cold resistance");
  621. #endif
  622.         if(!(HCold_resistance & FROMOUTSIDE)) {
  623.             You("feel full of hot air.");
  624.             HCold_resistance |= FROMOUTSIDE;
  625.         }
  626.         break;
  627.         case DISINT_RES:
  628. #ifdef DEBUG
  629.         debugpline("Trying to give disintegration resistance");
  630. #endif
  631.         if(!(HDisint_resistance & FROMOUTSIDE)) {
  632.             You(Hallucination ?
  633.                 "feel totally together, man." :
  634.                 "feel very firm.");
  635.             HDisint_resistance |= FROMOUTSIDE;
  636.         }
  637.         break;
  638.         case SHOCK_RES:    /* shock (electricity) resistance */
  639. #ifdef DEBUG
  640.         debugpline("Trying to give shock resistance");
  641. #endif
  642.         if(!(HShock_resistance & FROMOUTSIDE)) {
  643.             if (Hallucination)
  644.                 You("feel grounded in reality.");
  645.             else
  646.                 Your("health currently feels amplified!");
  647.             HShock_resistance |= FROMOUTSIDE;
  648.         }
  649.         break;
  650.         case POISON_RES:
  651. #ifdef DEBUG
  652.         debugpline("Trying to give poison resistance");
  653. #endif
  654.         if(!(HPoison_resistance & FROMOUTSIDE)) {
  655.             You("feel healthy.");
  656.             HPoison_resistance |= FROMOUTSIDE;
  657.         }
  658.         break;
  659.         case TELEPORT:
  660. #ifdef DEBUG
  661.         debugpline("Trying to give teleport");
  662. #endif
  663.         if(!(HTeleportation & FROMOUTSIDE)) {
  664.             You(Hallucination ? "feel diffuse." :
  665.                 "feel very jumpy.");
  666.             HTeleportation |= FROMOUTSIDE;
  667.         }
  668.         break;
  669.         case TELEPORT_CONTROL:
  670. #ifdef DEBUG
  671.         debugpline("Trying to give teleport control");
  672. #endif
  673.         if(!(HTeleport_control & FROMOUTSIDE)) {
  674.             You(Hallucination ?
  675.                 "feel centered in your personal space." :
  676.                 "feel in control of yourself.");
  677.             HTeleport_control |= FROMOUTSIDE;
  678.         }
  679.         break;
  680.         case TELEPAT:
  681. #ifdef DEBUG
  682.         debugpline("Trying to give telepathy");
  683. #endif
  684.         if(!(HTelepat & FROMOUTSIDE)) {
  685.             You(Hallucination ?
  686.                 "feel in touch with the cosmos." :
  687.                 "feel a strange mental acuity.");
  688.             HTelepat |= FROMOUTSIDE;
  689.             /* If blind, make sure monsters show up. */
  690.             if (Blind) see_monsters();
  691.         }
  692.         break;
  693.         default:
  694. #ifdef DEBUG
  695.         debugpline("Tried to give an impossible intrinsic");
  696. #endif
  697.         break;
  698.     }
  699. }
  700.  
  701. static void
  702. cpostfx(pm)        /* called after completely consuming a corpse */
  703. register int pm;
  704. {
  705.     register int tmp = 0;
  706.  
  707.     switch(pm) {
  708.         case PM_WRAITH:
  709.         pluslvl();
  710.         break;
  711. #ifdef POLYSELF
  712.         case PM_HUMAN_WERERAT:
  713.         u.ulycn = PM_WERERAT;
  714.         break;
  715.         case PM_HUMAN_WEREJACKAL:
  716.         u.ulycn = PM_WEREJACKAL;
  717.         break;
  718.         case PM_HUMAN_WEREWOLF:
  719.         u.ulycn = PM_WEREWOLF;
  720.         break;
  721. #endif
  722.         case PM_NURSE:
  723.         u.uhp = u.uhpmax;
  724.         flags.botl = 1;
  725.         break;
  726.         case PM_STALKER:
  727.         if(!Invis) {
  728.             HInvis = rn1(100, 50);
  729.             if(!See_invisible)
  730.                 newsym(u.ux, u.uy);
  731.         } else {
  732.             register long oldprop = See_invisible;
  733.             if (!(HInvis & INTRINSIC)) You("feel hidden!");
  734.             HInvis |= FROMOUTSIDE;
  735.             HSee_invisible |= FROMOUTSIDE;
  736.             if (!oldprop)
  737.                 newsym(u.ux, u.uy);
  738.         }
  739.         /* fall into next case */
  740.         case PM_YELLOW_LIGHT:
  741.         /* fall into next case */
  742.         case PM_GIANT_BAT:
  743.         make_stunned(HStun + 30,FALSE);
  744.         /* fall into next case */
  745.         case PM_BAT:
  746.         make_stunned(HStun + 30,FALSE);
  747.         break;
  748.         case PM_GIANT_MIMIC:
  749.         tmp += 10;
  750.         /* fall into next case */
  751.         case PM_LARGE_MIMIC:
  752.         tmp += 20;
  753.         /* fall into next case */
  754.         case PM_SMALL_MIMIC:
  755.         tmp += 20;
  756.         if(u.usym == S_HUMAN) {
  757.             You("can't resist the temptation to mimic a pile of gold.");
  758.             nomul(-tmp);
  759.             afternmv = eatmdone;
  760.             if (pl_character[0]=='E')
  761.             nomovemsg = "You now prefer mimicking an elf again.";
  762.             else
  763.             nomovemsg = "You now prefer mimicking a human again.";
  764.             u.usym = 0; /* hack! no monster sym 0; use for gold */
  765.             newsym(u.ux,u.uy);
  766.         }
  767.         break;
  768.         case PM_QUANTUM_MECHANIC:
  769.         Your("velocity suddenly seems very uncertain!");
  770.         if (Fast & INTRINSIC) {
  771.             Fast &= ~INTRINSIC;
  772.             You("seem slower.");
  773.         } else {
  774.             Fast |= FROMOUTSIDE;
  775.             You("seem faster.");
  776.         }
  777.         break;
  778.         case PM_LIZARD:
  779.         if (HStun > 2)  make_stunned(2L,FALSE);
  780.         if (HConfusion > 2)  make_confused(2L,FALSE);
  781.         break;
  782.         case PM_CHAMELEON:
  783.         You("feel a change coming over you.");
  784. #ifdef POLYSELF
  785.         polyself();
  786. #else
  787.         newman();
  788. #endif
  789.         break;
  790.         case PM_MIND_FLAYER:
  791.         if (ABASE(A_INT) < ATTRMAX(A_INT)) {
  792.             if (!rn2(2)) {
  793.                 pline("Yum! That was real brain food!");
  794.                 (void) adjattrib(A_INT, 1, FALSE);
  795.                 break;    /* don't give them telepathy, too */
  796.             }
  797.         }
  798.         else {
  799.             pline("For some reason, that tasted bland.");
  800.         }
  801.         /* fall through to default case */
  802.         default: {
  803.         register struct permonst *ptr = &mons[pm];
  804.         int i, count;
  805.  
  806.         if(dmgtype(ptr, AD_STUN) || pm==PM_VIOLET_FUNGUS) {
  807.             pline ("Oh wow!  Great stuff!");
  808.             make_hallucinated(HHallucination + 200,FALSE,0L);
  809.         }
  810.         /* prevent polymorph abuse by killing/eating your offspring */
  811.         if(pm >= PM_BABY_GRAY_DRAGON && pm <= PM_BABY_YELLOW_DRAGON)
  812.             return;
  813.         if(is_giant(ptr)) gainstr((struct obj *)0, 0);
  814.  
  815.         /* Check the monster for all of the intrinsics.  If this
  816.          * monster can give more than one, pick one to try to give
  817.          * from among all it can give.
  818.          *
  819.          * If a monster can give 4 intrinsics then you have
  820.          * a 1/1 * 1/2 * 2/3 * 3/4 = 1/4 chance of getting the first,
  821.          * a 1/2 * 2/3 * 3/4 = 1/4 chance of getting the second,
  822.          * a 1/3 * 3/4 = 1/4 chance of getting the third,
  823.          * and a 1/4 chance of getting the fourth.
  824.          *
  825.          * And now a proof by induction:
  826.          * it works for 1 intrinsic (1 in 1 of getting it)
  827.          * for 2 you have a 1 in 2 chance of getting the second,
  828.          *    otherwise you keep the first
  829.          * for 3 you have a 1 in 3 chance of getting the third,
  830.          *    otherwise you keep the first or the second
  831.          * for n+1 you have a 1 in n+1 chance of getting the (n+1)st,
  832.          *    otherwise you keep the previous one.
  833.          * Elliott Kleinrock, October 5, 1990
  834.          */
  835.  
  836.          count = 0;    /* number of possible intrinsics */
  837.          tmp = 0;    /* which one we will try to give */
  838.          for (i = 1; i <= LAST_PROP; i++) {
  839.             if (intrinsic_possible(i, ptr)) {
  840.                 count++;
  841.                 /* a 1 in count chance of replacing the old
  842.                  * one with this one, and a count-1 in count
  843.                  * chance of keeping the old one.  (note
  844.                  * that 1 in 1 and 0 in 1 are what we want
  845.                  * for the first one
  846.                  */
  847.                 if (!rn2(count)) {
  848. #ifdef DEBUG
  849.                     debugpline("Intrinsic %d replacing %d",
  850.                                 i, tmp);
  851. #endif
  852.                     tmp = i;
  853.                 }
  854.             }
  855.          }
  856.  
  857.          /* if any found try to give them one */
  858.          if (count) givit(tmp, ptr);
  859.         }
  860.         break;
  861.     }
  862.     return;
  863. }
  864.  
  865. STATIC_PTR
  866. int
  867. opentin()        /* called during each move whilst opening a tin */
  868. {
  869.     register int r;
  870.  
  871.     if(!carried(tin.tin) && !obj_here(tin.tin, u.ux, u.uy))
  872.                     /* perhaps it was stolen? */
  873.         return(0);        /* %% probably we should use tinoid */
  874.     if(tin.usedtime++ >= 50) {
  875.         You("give up your attempt to open the tin.");
  876.         return(0);
  877.     }
  878.     if(tin.usedtime < tin.reqtime)
  879.         return(1);        /* still busy */
  880.     if(tin.tin->otrapped || 
  881.        (tin.tin->cursed && tin.tin->spe != -1 && !rn2(8))) {
  882.         b_trapped("tin", 0);
  883.         goto use_me;
  884.     }
  885.     You("succeed in opening the tin.");
  886.     if(tin.tin->spe != 1) {
  887.         if(tin.tin->corpsenm == -1) {
  888.         pline("It turns out to be empty.");
  889.         tin.tin->dknown = tin.tin->known = TRUE;
  890.         goto use_me;
  891.         }
  892.         r = tin.tin->cursed ? 4 :        /* Always rotten if cursed */
  893.             (tin.tin->spe == -1) ? 5 :    /* "homemade" if player made */
  894.             rn2(TTSZ-1);        /* else take your pick */
  895.         if (tin.tin->spe == -1 && !tin.tin->blessed && !rn2(7))
  896.         r = 4;                /* some homemade tins go bad */
  897.         pline("It smells like %s.", makeplural(
  898.           Hallucination ? rndmonnam() : mons[tin.tin->corpsenm].mname));
  899.         if (yn("Eat it?") == 'n') {
  900.         if (!Hallucination) tin.tin->dknown = tin.tin->known = TRUE;
  901.         if (flags.verbose) You("discard the open tin.");
  902.         goto use_me;
  903.         }
  904.         /* in case stop_occupation() was called on previous meal */
  905.         victual.piece = (struct obj *)0;
  906.         victual.fullwarn = victual.eating = victual.doreset = FALSE;
  907.  
  908.         You("consume %s %s.", tintxts[r].txt,
  909.             mons[tin.tin->corpsenm].mname);
  910.         tin.tin->dknown = tin.tin->known = TRUE;
  911.         cprefx(tin.tin->corpsenm); cpostfx(tin.tin->corpsenm);
  912.  
  913.         /* check for vomiting added by GAN 01/16/87 */
  914.         if(tintxts[r].nut < 0) make_vomiting((long)rn1(15,10), FALSE);
  915.         else lesshungry(tintxts[r].nut);
  916.  
  917.         if(r == 0) {            /* Deep Fried */
  918.             /* Assume !Glib, because you can't open tins when Glib. */
  919.         Glib += rnd(15);
  920.         pline("Eating deep fried food made your %s very slippery.",
  921.               makeplural(body_part(FINGER)));
  922.         }
  923.     } else {
  924.         if (tin.tin->cursed)
  925.         pline("It contains some decaying %s substance.",
  926.             Hallucination ? hcolor() : green);
  927.         else
  928.         pline("It contains spinach.");
  929.  
  930.         if (yn("Eat it?") == 'n') {
  931.         if (!Hallucination && !tin.tin->cursed)
  932.             tin.tin->dknown = tin.tin->known = TRUE;
  933.         if (flags.verbose)
  934.             You("discard the open tin.");
  935.         goto use_me;
  936.         }
  937.         if (!tin.tin->cursed)
  938.         pline("This makes you feel like %s!",
  939.               Hallucination ? "Swee'pea" : "Popeye");
  940.         lesshungry(600);
  941.         gainstr(tin.tin, 0);
  942.     }
  943.     tin.tin->dknown = tin.tin->known = TRUE;
  944. use_me:
  945.     if (carried(tin.tin)) useup(tin.tin);
  946.     else useupf(tin.tin);
  947.     tin.tin = (struct obj *) 0;
  948.     return(0);
  949. }
  950.  
  951. static void
  952. start_tin(otmp)        /* called when starting to open a tin */
  953.     register struct obj *otmp;
  954. {
  955.     register int tmp;
  956.  
  957. #ifdef POLYSELF
  958.     if (metallivorous(uasmon)) {
  959.         You("bite right into the metal tin...");
  960.         tmp = 1;
  961.     } else if (nolimbs(uasmon)) {
  962.         You("cannot handle the tin properly to open it.");
  963.         return;
  964.     } else
  965. #endif
  966.     if (otmp->blessed) {
  967.         pline("The tin opens like magic!");
  968.         tmp = 1;
  969.     } else if(uwep) {
  970.         switch(uwep->otyp) {
  971.         case TIN_OPENER:
  972.             tmp = 1;
  973.             break;
  974.         case DAGGER:
  975.         case ELVEN_DAGGER:
  976.         case ORCISH_DAGGER:
  977.         case ATHAME:
  978.         case CRYSKNIFE:
  979.             tmp = 3;
  980.             break;
  981.         case PICK_AXE:
  982.         case AXE:
  983.             tmp = 6;
  984.             break;
  985.         default:
  986.             goto no_opener;
  987.         }
  988.         pline("Using your %s you try to open the tin.",
  989.             aobjnam(uwep, NULL));
  990.     } else {
  991. no_opener:
  992.         pline("It is not so easy to open this tin.");
  993.         if(Glib) {
  994.             pline("The tin slips from your %s.",
  995.                   makeplural(body_part(FINGER)));
  996.             if(otmp->quan > 1L) {
  997.                 register struct obj *obj;
  998.                 obj = splitobj(otmp, 1L);
  999.                 if(otmp == uwep) setuwep(obj);
  1000.             }
  1001.             if (carried(otmp)) dropx(otmp);
  1002.             else stackobj(otmp);
  1003.             return;
  1004.         }
  1005.         tmp = rn1(1 + 500/((int)(ACURR(A_DEX) + ACURRSTR)), 10);
  1006.     }
  1007.     tin.reqtime = tmp;
  1008.     tin.usedtime = 0;
  1009.     tin.tin = otmp;
  1010.     set_occupation(opentin, "opening the tin", 0);
  1011.     return;
  1012. }
  1013.  
  1014. int
  1015. Hear_again()        /* called when waking up after fainting */
  1016. {
  1017.     flags.soundok = 1;
  1018.     return 0;
  1019. }
  1020.  
  1021. static int
  1022. #ifdef POLYSELF
  1023. rottenfood(obj)
  1024. struct obj *obj;
  1025. #else
  1026. rottenfood()
  1027. #endif
  1028. {        /* called on the "first bite" of rotten food */
  1029. #ifdef POLYSELF
  1030.     pline("Blecch!  Rotten %s!", foodword(obj));
  1031. #else
  1032.     pline("Blecch!  Rotten food!");
  1033. #endif
  1034.     if(!rn2(4)) {
  1035.         if (Hallucination) You("feel rather trippy.");
  1036.         else You("feel rather %s.", body_part(LIGHT_HEADED));
  1037.         make_confused(HConfusion + d(2,4),FALSE);
  1038.     } else if(!rn2(4) && !Blind) {
  1039.         pline("Everything suddenly goes dark.");
  1040.         make_blinded((long)d(2,10),FALSE);
  1041.     } else if(!rn2(3)) {
  1042.         const char *what, *where;
  1043.         if (!Blind)
  1044.             what = "goes",  where = "dark";
  1045.         else if (Levitation || Is_airlevel(&u.uz) ||
  1046.              Is_waterlevel(&u.uz))
  1047.             what = "you lose control of",  where = "yourself";
  1048.         else
  1049.             what = "you slap against the",  where = surface(u.ux,u.uy);
  1050.         pline("The world spins and %s %s.", what, where);
  1051.         flags.soundok = 0;
  1052.         nomul(-rnd(10));
  1053.         nomovemsg = "You are conscious again.";
  1054.         afternmv = Hear_again;
  1055.         return(1);
  1056.     }
  1057.     return(0);
  1058. }
  1059.  
  1060. static int
  1061. eatcorpse(otmp)        /* called when a corpse is selected as food */
  1062.     register struct obj *otmp;
  1063. {
  1064.     register const char *cname = mons[otmp->corpsenm].mname;
  1065.     register int tp, rotted = 0;
  1066.  
  1067.     tp = 0;
  1068.  
  1069.     if(otmp->corpsenm != PM_LIZARD) {
  1070. #ifndef LINT    /* problem if more than 320K moves before try to eat */
  1071.         rotted = (monstermoves - otmp->age)/((long)(10 + rn2(20)));
  1072. #endif
  1073.  
  1074.         if(otmp->cursed) rotted += 2;
  1075.         else if (otmp->blessed) rotted -= 2;
  1076.     }
  1077.  
  1078.     if(otmp->corpsenm != PM_ACID_BLOB && (rotted > 5)) {
  1079.         pline("Ulch - that %s was tainted!",
  1080.               mons[otmp->corpsenm].mlet == S_FUNGUS ? "fungoid vegetation" :
  1081.               is_meaty(&mons[otmp->corpsenm]) ? "meat" : "protoplasm");
  1082. #ifdef POLYSELF
  1083.         if (u.usym == S_FUNGUS)
  1084.             pline("It doesn't seem at all sickening, though...");
  1085.         else {
  1086. #endif
  1087.             make_sick((long) rn1(10, 10),FALSE);
  1088.             Sprintf(corpsename, "rotted %s corpse", cname);
  1089.             u.usick_cause = (const char *)corpsename;
  1090.             flags.botl = 1;
  1091. #ifdef POLYSELF
  1092.         }
  1093. #endif
  1094.         if (carried(otmp)) useup(otmp);
  1095.         else useupf(otmp);
  1096.         return(1);
  1097.     } else if(acidic(&mons[otmp->corpsenm])
  1098. #ifdef POLYSELF
  1099.           && !resists_acid(uasmon)
  1100. #endif
  1101.          ) {
  1102.         tp++;
  1103.         You("have a very bad case of stomach acid.");
  1104.         losehp(rnd(15), "acidic corpse", KILLED_BY_AN);
  1105.     } else if(poisonous(&mons[otmp->corpsenm]) && rn2(5)) {
  1106.         tp++;
  1107.         pline("Ecch - that must have been poisonous!");
  1108.         if(!Poison_resistance) {
  1109.             losestr(rnd(4));
  1110.             losehp(rnd(15), "poisonous corpse", KILLED_BY_AN);
  1111.         } else    You("seem unaffected by the poison.");
  1112.     /* now any corpse left too long will make you mildly ill */
  1113.     } else if(((rotted > 5) || ((rotted > 3) && rn2(5)))
  1114. #ifdef POLYSELF
  1115.         && u.usym != S_FUNGUS
  1116. #endif
  1117.                             ){
  1118.         tp++;
  1119.         You("feel%s sick.", (Sick) ? " very" : "");
  1120.         losehp(rnd(8), "cadaver", KILLED_BY_AN);
  1121.     }
  1122.     if(!tp && otmp->corpsenm != PM_LIZARD && (otmp->orotten || !rn2(7))) {
  1123. #ifdef POLYSELF
  1124.         if(rottenfood(otmp))
  1125. #else
  1126.         if(rottenfood())
  1127. #endif
  1128.         {
  1129.         otmp->orotten = TRUE;
  1130.         (void)touchfood(otmp);
  1131.         return(1);
  1132.         }
  1133.         otmp->oeaten >>= 2;
  1134.     } else {
  1135. #ifdef POLYSELF
  1136.         pline("This %s corpse %s!", cname,
  1137.         (carnivorous(uasmon) && !herbivorous(uasmon))
  1138.         ? "is delicious" : "tastes terrible");
  1139. #else
  1140.         pline("This %s corpse tastes terrible!", cname);
  1141. #endif
  1142.     }
  1143.  
  1144.     /* delay is weight dependent */
  1145.     victual.reqtime = 3 + (mons[otmp->corpsenm].cwt >> 6);
  1146.     return(0);
  1147. }
  1148.  
  1149. static void
  1150. start_eating(otmp)        /* called as you start to eat */
  1151.     register struct obj *otmp;
  1152. {
  1153. #ifdef DEBUG
  1154.     debugpline("start_eating: %lx (victual = %lx)", otmp, victual.piece);
  1155.     debugpline("reqtime = %d", victual.reqtime);
  1156.     debugpline("(original reqtime = %d)", objects[otmp->otyp].oc_delay);
  1157.     debugpline("nmod = %d", victual.nmod);
  1158.     debugpline("oeaten = %d", otmp->oeaten);
  1159. #endif
  1160.     victual.fullwarn = victual.doreset = FALSE;
  1161.     victual.eating = TRUE;
  1162.  
  1163.     if (otmp->otyp == CORPSE) {
  1164.         cprefx(victual.piece->corpsenm);
  1165.         if (!victual.piece && victual.eating) do_reset_eat();
  1166.         if (victual.eating == FALSE) return; /* died and lifesaved */
  1167.     }
  1168.  
  1169.     if (bite()) return;
  1170.  
  1171.     if(++victual.usedtime >= victual.reqtime) {
  1172.         /* print "finish eating" message if they just resumed -dlc */
  1173.         done_eating(victual.reqtime > 1 ? TRUE : FALSE);
  1174.         return;
  1175.     }
  1176.  
  1177.     Sprintf(msgbuf, "eating %s", the(singular(otmp, xname)));
  1178.     set_occupation(eatfood, msgbuf, 0);
  1179. }
  1180.  
  1181.  
  1182. static void
  1183. fprefx(otmp)        /* called on "first bite" of (non-corpse) food */
  1184.  
  1185.     register struct obj *otmp;
  1186. {
  1187.     switch(otmp->otyp) {
  1188.  
  1189.         case FOOD_RATION:
  1190.         if(u.uhunger <= 200)
  1191.             if (Hallucination) pline("Oh wow, like, superior, man!");
  1192.             else           pline("That food really hit the spot!");
  1193.         else if(u.uhunger <= 700) pline("That satiated your stomach!");
  1194.         break;
  1195.         case TRIPE_RATION:
  1196. #ifdef POLYSELF
  1197.         if (carnivorous(uasmon) && !humanoid(uasmon))
  1198.             pline("That tripe ration was surprisingly good!");
  1199.         else {
  1200. #endif
  1201.             pline("Yak - dog food!");
  1202.             more_experienced(1,0);
  1203.             flags.botl = 1;
  1204. #ifdef POLYSELF
  1205.         }
  1206. #endif
  1207.         if(rn2(2)
  1208. #ifdef POLYSELF
  1209.             && (!carnivorous(uasmon) || humanoid(uasmon))
  1210. #endif
  1211.                         ) {
  1212.             make_vomiting((long)rn1(victual.reqtime, 14), FALSE);
  1213.         }
  1214.         break;
  1215. #ifdef POLYSELF
  1216.         case CLOVE_OF_GARLIC:
  1217.         if (is_undead(uasmon)) {
  1218.             make_vomiting((long)rn1(victual.reqtime, 5), FALSE);
  1219.             break;
  1220.         }
  1221.         /* Fall through otherwise */
  1222. #endif
  1223.         default:
  1224. #ifdef TUTTI_FRUTTI
  1225.         if (otmp->otyp==SLIME_MOLD && !otmp->cursed
  1226.             && otmp->spe == current_fruit)
  1227.             pline("My, that was a %s %s!",
  1228.               Hallucination ? "primo" : "yummy",
  1229.               singular(otmp, xname));
  1230.         else
  1231. #endif
  1232. #ifdef UNIX
  1233.         if (otmp->otyp == APPLE || otmp->otyp == PEAR) {
  1234.             if (!Hallucination) pline("Core dumped.");
  1235.             else {
  1236. /* This is based on an old Usenet joke, a fake a.out manual page */
  1237.             int x = rnd(100);
  1238.             if (x <= 75)
  1239.                 pline("Segmentation fault -- core dumped.");
  1240.             else if (x <= 99)
  1241.                 pline("Bus error -- core dumped.");
  1242.             else pline("Yo' mama -- core dumped.");
  1243.             }
  1244.         } else
  1245. #endif
  1246.             pline("This %s is %s", singular(otmp, xname),
  1247.               otmp->cursed ? (Hallucination ? "grody!" : "terrible!") :
  1248.               otmp->otyp == CRAM_RATION ? "bland." :
  1249.               Hallucination ? "gnarly!" : "delicious!");
  1250.         break;
  1251.     }
  1252. }
  1253.  
  1254. #ifdef POLYSELF
  1255. static void
  1256. eatring(otmp)
  1257. struct obj *otmp;
  1258. {
  1259.     int typ = otmp->otyp;
  1260.     int oldprop;
  1261.  
  1262.     /* Note: rings are not so common that this is unbalancing.  (How */
  1263.     /* often do you even _find_ 3 rings of polymorph in a game? */
  1264.     oldprop = !!(u.uprops[objects[typ].oc_oprop].p_flgs);
  1265.     otmp->known = otmp->dknown = 1; /* by taste */
  1266.     if (!rn2(3)) switch (otmp->otyp) {
  1267.         case RIN_AGGRAVATE_MONSTER:
  1268.         case RIN_WARNING:
  1269.         case RIN_POISON_RESISTANCE:
  1270.         case RIN_FIRE_RESISTANCE:
  1271.         case RIN_COLD_RESISTANCE:
  1272.         case RIN_SHOCK_RESISTANCE:
  1273.         case RIN_TELEPORTATION:
  1274.         case RIN_TELEPORT_CONTROL:
  1275.         case RIN_SEE_INVISIBLE:
  1276.         case RIN_PROTECTION_FROM_SHAPE_CHAN:
  1277.         case RIN_SEARCHING:
  1278.         case RIN_STEALTH:
  1279.         case RIN_INVISIBILITY:
  1280.         case RIN_CONFLICT:
  1281.         case RIN_POLYMORPH:
  1282.         case RIN_POLYMORPH_CONTROL:
  1283.         case RIN_REGENERATION: /* Probably stupid. */
  1284.         case RIN_HUNGER: /* Stupid. */
  1285.         case RIN_LEVITATION: /* Stupid. */
  1286.         if (!(u.uprops[objects[typ].oc_oprop].p_flgs & FROMOUTSIDE))
  1287.             pline("Magic spreads through your body as you digest the ring.");
  1288.         u.uprops[objects[typ].oc_oprop].p_flgs |= FROMOUTSIDE;
  1289.         if (typ == RIN_SEE_INVISIBLE) {
  1290.             set_mimic_blocking();
  1291.             see_monsters();
  1292.             if (Invis && !oldprop
  1293. #ifdef POLYSELF
  1294.                 && !perceives(uasmon)
  1295. #endif
  1296.                             && !Blind) {
  1297.             newsym(u.ux,u.uy);
  1298.             pline("Suddenly you can see yourself.");
  1299.             makeknown(typ);
  1300.             }
  1301.         } else if (typ == RIN_INVISIBILITY) {
  1302.             if (!oldprop && !See_invisible && !Blind) {
  1303.             newsym(u.ux,u.uy);
  1304.             Your("body takes on a %s transparency...",
  1305.                 Hallucination ? "normal" : "strange");
  1306.             makeknown(typ);
  1307.             }
  1308.         } else if (typ == RIN_PROTECTION_FROM_SHAPE_CHAN)
  1309.             rescham();
  1310.         else if (typ == RIN_LEVITATION) {
  1311.             if (!Levitation) {
  1312.             float_up();
  1313.             makeknown(typ);
  1314.             }
  1315.         }
  1316.         break;
  1317.         case RIN_ADORNMENT:
  1318.         if (adjattrib(A_CHA, otmp->spe, -1))
  1319.             makeknown(typ);
  1320.         break;
  1321.         case RIN_GAIN_STRENGTH:
  1322.         case RIN_INCREASE_DAMAGE: /* Any better ideas? */
  1323.         if (adjattrib(A_STR, otmp->spe, -1))
  1324.             makeknown(typ);
  1325.         break;
  1326.         case RIN_PROTECTION:
  1327.         Protection |= FROMOUTSIDE;
  1328.         u.ublessed += otmp->spe;
  1329.         flags.botl = 1;
  1330.         break;
  1331.     }
  1332. }
  1333.  
  1334. static void
  1335. eatspecial() /* called after eating non-food */
  1336. {
  1337.     register struct obj *otmp = victual.piece;
  1338.  
  1339.     lesshungry(victual.nmod);
  1340.     victual.piece = (struct obj *)0;
  1341.     victual.eating = 0;
  1342.     if (otmp->oclass == GOLD_CLASS) {
  1343.         dealloc_obj(otmp);
  1344.         return;
  1345.     }
  1346.     if (otmp->oclass == POTION_CLASS) {
  1347.         otmp->quan++; /* dopotion() does a useup() */
  1348.         (void)dopotion(otmp);
  1349.     }
  1350.     if (otmp->oclass == RING_CLASS)
  1351.         eatring(otmp);
  1352.     if (otmp == uball) unpunish();
  1353.     if (otmp == uchain) unpunish(); /* but no useup() */
  1354.     else if (carried(otmp)) useup(otmp);
  1355.     else useupf(otmp);
  1356. }
  1357.  
  1358. /* NOTE: the order of these words exactly corresponds to the
  1359.    order of oc_material values #define'd in objclass.h. */
  1360. static const char *foodwords[] = {
  1361.     "meal", "liquid", "wax", "food", "meat",
  1362.     "paper", "cloth", "leather", "wood", "bone", "scale",
  1363.     "metal", "metal", "metal", "silver", "gold", "platinum", "mithril",
  1364.     "plastic", "glass", "rich food", "stone"
  1365. };
  1366.  
  1367. static const char *
  1368. foodword(otmp)
  1369. register struct obj *otmp;
  1370. {
  1371.     if (otmp->oclass == FOOD_CLASS) return "food";
  1372.     if (otmp->oclass == GEM_CLASS &&
  1373.         objects[otmp->otyp].oc_material == GLASS &&
  1374.         otmp->dknown)
  1375.         makeknown(otmp->otyp);
  1376.     return foodwords[objects[otmp->otyp].oc_material];
  1377. }
  1378. #endif
  1379.  
  1380. static void
  1381. fpostfx(otmp)        /* called after consuming (non-corpse) food */
  1382.  
  1383.     register struct obj *otmp;
  1384. {
  1385.     switch(otmp->otyp) {
  1386. #ifdef POLYSELF
  1387.         case SPRIG_OF_WOLFSBANE:
  1388.         if (u.ulycn != -1) {
  1389.             u.ulycn = -1;
  1390.             You("feel purified.");
  1391.             if(uasmon == &mons[u.ulycn] && !Polymorph_control)
  1392.             rehumanize();
  1393.         }
  1394.         break;
  1395. #endif
  1396.         case CARROT:
  1397.         make_blinded(0L,TRUE);
  1398.         break;
  1399.         case FORTUNE_COOKIE:
  1400.         outrumor(bcsign(otmp), TRUE);
  1401.         break;
  1402.         case LUMP_OF_ROYAL_JELLY:
  1403.         /* This stuff seems to be VERY healthy! */
  1404.         gainstr(otmp, 1);
  1405.         u.uhp += (otmp->cursed) ? -rnd(20) : rnd(20);
  1406.         if(u.uhp > u.uhpmax) {
  1407.             if(!rn2(17)) u.uhpmax++;
  1408.             u.uhp = u.uhpmax;
  1409.         } else if(u.uhp <= 0) {
  1410.             killer_format = KILLED_BY_AN;
  1411.             killer = "rotten lump of royal jelly";
  1412.             done(POISONING);
  1413.         }
  1414.         if(!otmp->cursed) heal_legs();
  1415.         break;
  1416.         case EGG:
  1417.         if(otmp->corpsenm == PM_COCKATRICE) {
  1418. #ifdef POLYSELF
  1419.             if(!resists_ston(uasmon))
  1420.             if(!poly_when_stoned(uasmon) ||
  1421.                !polymon(PM_STONE_GOLEM))
  1422.             {
  1423. #endif
  1424.             if (!Stoned) Stoned = 5;
  1425.             killer_format = KILLED_BY_AN;
  1426.             killer = "cockatrice egg";
  1427. #ifdef POLYSELF
  1428.             }
  1429. #endif
  1430.         }
  1431.         break;
  1432.     }
  1433.     return;
  1434. }
  1435.  
  1436. int
  1437. doeat()        /* generic "eat" command funtion (see cmd.c) */
  1438. {
  1439.     register struct obj *otmp;
  1440.     int basenutrit;            /* nutrition of full item */
  1441.  
  1442.     if (Strangled) {
  1443.         pline("If you can't breathe air, how can you consume solids?");
  1444.         return 0;
  1445.     }
  1446.     if (!(otmp = floorfood("eat", 0))) return 0;
  1447.     if (check_capacity(NULL)) return 0;
  1448. #ifdef POLYSELF
  1449.     /* We have to make non-foods take 1 move to eat, unless we want to
  1450.      * do ridiculous amounts of coding to deal with partly eaten plate
  1451.      * mails, players who polymorph back to human in the middle of their
  1452.      * metallic meal, etc....
  1453.      */
  1454.     if (!is_edible(otmp)) {
  1455.         You("cannot eat that!");
  1456.         return 0;
  1457.     }
  1458.     if (otmp->oclass != FOOD_CLASS) {
  1459.         victual.reqtime = 1;
  1460.         victual.piece = otmp;
  1461.         /* Don't split it, we don't need to if it's 1 move */
  1462.         victual.usedtime = 0;
  1463.         victual.canchoke = (u.uhs == SATIATED);
  1464.         /* Note: gold weighs 1 pt. for each 1000 pieces (see */
  1465.         /* pickup.c) so gold and non-gold is consistent. */
  1466.         if (otmp->oclass == GOLD_CLASS)
  1467.         basenutrit = ((otmp->quan > 200000L) ? 2000
  1468.             : (int)(otmp->quan/100L));
  1469.         else if(otmp->oclass == BALL_CLASS || otmp->oclass == CHAIN_CLASS)
  1470.         basenutrit = weight(otmp);
  1471.         /* oc_nutrition is usually weight anyway */
  1472.         else basenutrit = objects[otmp->otyp].oc_nutrition;
  1473.         victual.nmod = basenutrit;
  1474.         victual.eating = TRUE; /* needed for lesshungry() */
  1475.  
  1476.         if (otmp->cursed)
  1477.         (void) rottenfood(otmp);
  1478.  
  1479.         if (otmp->oclass == WEAPON_CLASS && otmp->opoisoned) {
  1480.         pline("Ecch - that must have been poisonous!");
  1481.         if(!Poison_resistance) {
  1482.             losestr(rnd(4));
  1483.             losehp(rnd(15), xname(otmp), KILLED_BY_AN);
  1484.         } else
  1485.             You("seem unaffected by the poison.");
  1486.         } else if (!otmp->cursed)
  1487.         pline("This %s is delicious!",
  1488.               otmp->oclass == GOLD_CLASS ? foodword(otmp) :
  1489.               singular(otmp, xname));
  1490.         eatspecial();
  1491.         return 1;
  1492.     }
  1493. #endif
  1494.  
  1495.     if(otmp == victual.piece) {
  1496.     /* If they weren't able to choke, they don't suddenly become able to
  1497.      * choke just because they were interrupted.  On the other hand, if
  1498.      * they were able to choke before, if they lost food it's possible
  1499.      * they shouldn't be able to choke now.
  1500.      */
  1501.         if (u.uhs != SATIATED) victual.canchoke = FALSE;
  1502.         if(!carried(victual.piece)) {
  1503.         if(victual.piece->quan > 1L)
  1504.             (void) splitobj(victual.piece, 1L);
  1505.         }
  1506.         You("resume your meal.");
  1507.         start_eating(victual.piece);
  1508.         return(1);
  1509.     }
  1510.  
  1511.     /* nothing in progress - so try to find something. */
  1512.     /* tins are a special case */
  1513.     if(otmp->otyp == TIN) {
  1514.         start_tin(otmp);
  1515.         return(1);
  1516.     }
  1517.  
  1518.     victual.piece = otmp = touchfood(otmp);
  1519.     victual.usedtime = 0;
  1520.  
  1521.     /* Now we need to calculate delay and nutritional info.
  1522.      * The base nutrition calculated here and in eatcorpse() accounts
  1523.      * for normal vs. rotten food.  The reqtime and nutrit values are
  1524.      * then adjusted in accordance with the amount of food left.
  1525.      */
  1526.     if(otmp->otyp == CORPSE) {
  1527.         if(eatcorpse(otmp)) return(1);
  1528.         /* else eatcorpse sets up reqtime and oeaten */
  1529.     } else {
  1530.         victual.reqtime = objects[otmp->otyp].oc_delay;
  1531.         if (otmp->otyp != FORTUNE_COOKIE &&
  1532.         (otmp->cursed ||
  1533.          (((monstermoves - otmp->age) > (int) otmp->blessed ? 50:30) &&
  1534.         (otmp->orotten || !rn2(7))))) {
  1535.  
  1536. #ifdef POLYSELF
  1537.         if(rottenfood(otmp))
  1538. #else
  1539.         if(rottenfood())
  1540. #endif
  1541.         {
  1542.             otmp->orotten = TRUE;
  1543.             return(1);
  1544.         }
  1545.         otmp->oeaten >>= 1;
  1546.         } else fprefx(otmp);
  1547.     }
  1548.  
  1549.     /* re-calc the nutrition */
  1550.     if (otmp->otyp == CORPSE) basenutrit = mons[otmp->corpsenm].cnutrit;
  1551.     else basenutrit = objects[otmp->otyp].oc_nutrition;
  1552.  
  1553. #ifdef DEBUG
  1554.     debugpline("before rounddiv: victual.reqtime == %d", victual.reqtime);
  1555.     debugpline("oeaten == %d, basenutrit == %d", otmp->oeaten, basenutrit);
  1556. #endif
  1557.     victual.reqtime = (basenutrit == 0 ? 0 :
  1558.         rounddiv(victual.reqtime * (long)otmp->oeaten, basenutrit));
  1559. #ifdef DEBUG
  1560.     debugpline("after rounddiv: victual.reqtime == %d", victual.reqtime);
  1561. #endif
  1562.     /* calculate the modulo value (nutrit. units per round eating)
  1563.      * note: this isn't exact - you actually lose a little nutrition
  1564.      *     due to this method.
  1565.      * TODO: add in a "remainder" value to be given at the end of the
  1566.      *     meal.
  1567.      */
  1568.     if(victual.reqtime == 0)
  1569.         /* possible if most has been eaten before */
  1570.         victual.nmod = 0;
  1571.     else if (otmp->oeaten > victual.reqtime)
  1572.         victual.nmod = -(otmp->oeaten / victual.reqtime);
  1573.     else
  1574.         victual.nmod = victual.reqtime % otmp->oeaten;
  1575.     victual.canchoke = (u.uhs == SATIATED);
  1576.  
  1577.     start_eating(otmp);
  1578.     return(1);
  1579. }
  1580.  
  1581. /* Take a single bite from a piece of food, checking for choking and
  1582.  * modifying usedtime.  Returns 1 if they choked and survived, 0 otherwise.
  1583.  */
  1584. static int
  1585. bite()
  1586. {
  1587.     if(victual.canchoke && u.uhunger >= 2000) {
  1588.         choke(victual.piece);
  1589.         return 1;
  1590.     }
  1591.     if (victual.doreset) {
  1592.         do_reset_eat();
  1593.         return 0;
  1594.     }
  1595.     if(victual.nmod < 0) {
  1596.         lesshungry(-victual.nmod);
  1597.         victual.piece->oeaten -= -victual.nmod;
  1598.     } else if(victual.nmod > 0 && (victual.usedtime % victual.nmod)) {
  1599.         lesshungry(1);
  1600.         victual.piece->oeaten--;
  1601.     }
  1602.     recalc_wt();
  1603.     return 0;
  1604. }
  1605.  
  1606. #endif /* OVLB */
  1607. #ifdef OVL0
  1608.  
  1609. void
  1610. gethungry()    /* as time goes by - called by moveloop() and domove() */
  1611. {
  1612.     if (u.uinvulnerable) return;    /* you don't feel hungrier */
  1613.  
  1614.     if ((!u.usleep || !rn2(10))    /* slow metabolic rate while asleep */
  1615.         && (carnivorous(uasmon) || herbivorous(uasmon)))
  1616.         u.uhunger--;        /* ordinary food consumption */
  1617.  
  1618.     if (moves % 2) {    /* odd turns */
  1619.         /* Regeneration uses up food, unless due to an artifact */
  1620.         if ((HRegeneration & (~W_ART)) &&
  1621.         (HRegeneration != W_WEP || !uwep->oartifact)) u.uhunger--;
  1622.         if (near_capacity() > SLT_ENCUMBER) u.uhunger--;
  1623.     } else {        /* even turns */
  1624.         if (Hunger) u.uhunger--;
  1625.         /* Conflict uses up food too */
  1626.         if ((Conflict & (~W_ARTI))) u.uhunger--;
  1627.         /* +0 charged rings don't do anything, so don't affect hunger */
  1628.         switch ((int)(moves % 20)) {    /* note: use even cases only */
  1629.          case  4: if (uleft &&
  1630.               (uleft->spe || !objects[uleft->otyp].oc_charged))
  1631.                 u.uhunger--;
  1632.             break;
  1633.          case  8: if (uamul) u.uhunger--;
  1634.             break;
  1635.          case 12: if (uright &&
  1636.               (uright->spe || !objects[uright->otyp].oc_charged))
  1637.                 u.uhunger--;
  1638.             break;
  1639.          case 16: if (u.uhave.amulet) u.uhunger--;
  1640.             break;
  1641.          default: break;
  1642.         }
  1643.     }
  1644.     newuhs(TRUE);
  1645. }
  1646.  
  1647. #endif /* OVL0 */
  1648. #ifdef OVLB
  1649.  
  1650. void
  1651. morehungry(num)    /* called after vomiting and after performing feats of magic */
  1652. register int num;
  1653. {
  1654.     u.uhunger -= num;
  1655.     newuhs(TRUE);
  1656. }
  1657.  
  1658.  
  1659. void
  1660. lesshungry(num)    /* called after eating (and after drinking fruit juice) */
  1661. register int num;
  1662. {
  1663. #ifdef DEBUG
  1664.     debugpline("lesshungry(%d)", num);
  1665. #endif
  1666.     u.uhunger += num;
  1667.     if(u.uhunger >= 2000) {
  1668.         if (!victual.eating || victual.canchoke)
  1669.         if (victual.eating) {
  1670.             choke(victual.piece);
  1671.             reset_eat();
  1672.         } else
  1673.         if (tin.tin)
  1674.             choke(tin.tin);
  1675.         else
  1676.             choke((struct obj *) 0);
  1677.         /* no reset_eat(); it was a non-food such as juice */
  1678.     } else {
  1679.         /* Have lesshungry() report when you're nearly full so all eating
  1680.          * warns when you're about to choke.
  1681.          */
  1682.         if (u.uhunger >= 1500) {
  1683.           if(!victual.eating || (victual.eating && !victual.fullwarn)) {
  1684.         pline("You're having a hard time getting all of it down.");
  1685.         nomovemsg = "You're finally finished.";
  1686.         if(!victual.eating)
  1687.             multi = -2;
  1688.         else {
  1689.             victual.fullwarn = TRUE;
  1690.             if (victual.canchoke &&
  1691.             /* a one-gulp food will not survive a stop */
  1692.                 victual.reqtime > 1) {
  1693.             if(yn("Stop eating?") == 'y')
  1694.             {
  1695.                 reset_eat();
  1696.                 nomovemsg = NULL;
  1697.             }
  1698.             }
  1699.         }
  1700.           }
  1701.         }
  1702.     }
  1703.     newuhs(FALSE);
  1704. }
  1705.  
  1706. STATIC_PTR
  1707. int
  1708. unfaint()
  1709. {
  1710.     (void) Hear_again();
  1711.     if(u.uhs > FAINTING)
  1712.         u.uhs = FAINTING;
  1713.     stop_occupation();
  1714.     flags.botl = 1;
  1715.     return 0;
  1716. }
  1717.  
  1718. #endif /* OVLB */
  1719. #ifdef OVL0
  1720.  
  1721. boolean
  1722. is_fainted()
  1723. {
  1724.     return((boolean)(u.uhs == FAINTED));
  1725. }
  1726.  
  1727. void
  1728. reset_faint()    /* call when a faint must be prematurely terminated */
  1729. {
  1730.     if(is_fainted()) nomul(0);
  1731. }
  1732.  
  1733. #if 0
  1734. void
  1735. sync_hunger()
  1736. {
  1737.  
  1738.     if(is_fainted()) {
  1739.  
  1740.         flags.soundok = 0;
  1741.         nomul(-10+(u.uhunger/10));
  1742.         nomovemsg = "You regain consciousness.";
  1743.         afternmv = unfaint;
  1744.     }
  1745. }
  1746. #endif
  1747.  
  1748. void
  1749. newuhs(incr)        /* compute and comment on your (new?) hunger status */
  1750.     boolean incr;
  1751. {
  1752.     register int newhs, h = u.uhunger;
  1753.  
  1754.     newhs = (h > 1000) ? SATIATED :
  1755.         (h > 150) ? NOT_HUNGRY :
  1756.         (h > 50) ? HUNGRY :
  1757.         (h > 0) ? WEAK : FAINTING;
  1758.  
  1759.     if(newhs == FAINTING) {
  1760.         if(is_fainted()) newhs = FAINTED;
  1761.         if(u.uhs <= WEAK || rn2(20-u.uhunger/10) >= 19) {
  1762.             if(!is_fainted() && multi >= 0 /* %% */) {
  1763.                 /* stop what you're doing, then faint */
  1764.                 stop_occupation();
  1765.                 You("faint from lack of food.");
  1766.                 flags.soundok = 0;
  1767.                 nomul(-10+(u.uhunger/10));
  1768.                 nomovemsg = "You regain consciousness.";
  1769.                 afternmv = unfaint;
  1770.                 newhs = FAINTED;
  1771.             }
  1772.         } else
  1773.         if(u.uhunger < -(int)(200 + 20*ACURR(A_CON))) {
  1774.             u.uhs = STARVED;
  1775.             flags.botl = 1;
  1776.             bot();
  1777.             You("die from starvation.");
  1778.             killer_format = KILLED_BY;
  1779.             killer = "starvation";
  1780.             done(STARVING);
  1781.             /* if we return, we lifesaved, and that calls newuhs */
  1782.             return;
  1783.         }
  1784.     }
  1785.  
  1786.     if(newhs != u.uhs) {
  1787.         if(newhs >= WEAK && u.uhs < WEAK)
  1788.             losestr(1);    /* this may kill you -- see below */
  1789.         else if(newhs < WEAK && u.uhs >= WEAK)
  1790.             losestr(-1);
  1791.         switch(newhs){
  1792.         case HUNGRY:
  1793.             if (Hallucination) {
  1794.                 pline((!incr) ?
  1795.                 "You now have a lesser case of the munchies." :
  1796.                 "You are getting the munchies.");
  1797.             } else
  1798.                 You((!incr) ? "only feel hungry now." :
  1799.                   (u.uhunger < 145) ? "feel hungry." :
  1800.                    "are beginning to feel hungry.");
  1801.             if (incr && occupation &&
  1802.                 (occupation != eatfood && occupation != opentin))
  1803.                 stop_occupation();
  1804.             break;
  1805.         case WEAK:
  1806.             if (Hallucination)
  1807.                 pline((!incr) ?
  1808.                   "You still have the munchies." :
  1809.       "The munchies are interfering with your motor capabilities.");
  1810.             else
  1811.                 You((!incr) ? "feel weak now." :
  1812.                   (u.uhunger < 45) ? "feel weak." :
  1813.                    "are beginning to feel weak.");
  1814.             if (incr && occupation &&
  1815.                 (occupation != eatfood && occupation != opentin))
  1816.                 stop_occupation();
  1817.             break;
  1818.         }
  1819.         u.uhs = newhs;
  1820.         flags.botl = 1;
  1821.         if(u.uhp < 1) {
  1822.             You("die from hunger and exhaustion.");
  1823.             killer_format = KILLED_BY;
  1824.             killer = "exhaustion";
  1825.             done(STARVING);
  1826.             return;
  1827.         }
  1828.     }
  1829. }
  1830.  
  1831. #endif /* OVL0 */
  1832. #ifdef OVLB
  1833.  
  1834. /* Returns an object representing food.  Object may be either on floor or
  1835.  * in inventory.
  1836.  */
  1837. struct obj *
  1838. floorfood(verb,corpsecheck)    /* get food from floor or pack */
  1839.     const char *verb;
  1840.     int corpsecheck; /* 0, no check, 1, corpses, 2, tinnable corpses */
  1841. {
  1842.     register struct obj *otmp;
  1843.     char qbuf[QBUFSZ];
  1844.     char c;
  1845. #ifdef POLYSELF
  1846.     struct obj *gold = g_at(u.ux, u.uy);
  1847.     boolean feeding = (!strcmp(verb, "eat"));
  1848.  
  1849.     if (feeding && gold && metallivorous(uasmon)) {
  1850.         if (gold->quan == 1L)
  1851.         Sprintf(qbuf, "There is 1 gold piece here; eat it?");
  1852.         else Sprintf(qbuf, "There are %ld gold pieces here; eat them?",
  1853.                                 gold->quan);
  1854.         if (yn(qbuf) == 'y') {
  1855.         /* tricky, because gold isn't a real object -dlc */
  1856.         freeobj(gold);
  1857.         return gold;
  1858.         }
  1859.     }
  1860. #endif
  1861.     /* Is there some food (probably a heavy corpse) here on the ground? */
  1862.     if (!(Levitation && !Is_airlevel(&u.uz)  && !Is_waterlevel(&u.uz))
  1863.         && !u.uswallow) {
  1864.         for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) {
  1865.         if(corpsecheck ?
  1866.         (otmp->otyp==CORPSE && (corpsecheck == 1 || tinnable(otmp))) :
  1867. #ifdef POLYSELF
  1868.             feeding ? (otmp->oclass != GOLD_CLASS && is_edible(otmp)) :
  1869. #endif
  1870.                         otmp->oclass==FOOD_CLASS) {
  1871.             Sprintf(qbuf, "There %s %s here; %s %s?",
  1872.                 (otmp->quan == 1L) ? "is" : "are",
  1873.                 doname(otmp), verb,
  1874.                 (otmp->quan == 1L) ? "it" : "one");
  1875.             if((c = yn_function(qbuf,ynqchars,'n')) == 'y')
  1876.                 return(otmp);
  1877.             else if(c == 'q')
  1878.                 return((struct obj *) 0);
  1879.         }
  1880.         }
  1881.     }
  1882. #ifdef POLYSELF
  1883.     /* We cannot use ALL_CLASSES since that causes getobj() to skip its
  1884.      * "ugly checks" and we need to check for inedible items.
  1885.      */
  1886.     return getobj(feeding ? (const char *)allobj :
  1887.                 (const char *)comestibles, verb);
  1888. #else
  1889.     return getobj(comestibles, verb);
  1890. #endif
  1891. }
  1892.  
  1893. /* Side effects of vomiting */
  1894. /* added nomul (MRS) - it makes sense, you're too busy being sick! */
  1895. /* TO DO: regurgitate swallowed monsters when poly'd */
  1896. void
  1897. vomit()        /* A good idea from David Neves */
  1898. {
  1899.     make_sick(0L,TRUE);
  1900.     nomul(-2);
  1901. }
  1902.  
  1903. int
  1904. eaten_stat(base, obj)
  1905. register int base;
  1906. register struct obj *obj;
  1907. {
  1908.     long uneaten_amt, full_amount;
  1909.  
  1910.     uneaten_amt = (long)obj->oeaten;
  1911.     full_amount = (obj->otyp == CORPSE) ? (long)mons[obj->corpsenm].cnutrit
  1912.                     : (long)objects[obj->otyp].oc_nutrition;
  1913.  
  1914.     base = (int)(full_amount ? (long)base * uneaten_amt / full_amount : 0L);
  1915.     return (base < 1) ? 1 : base;
  1916. }
  1917.  
  1918. #endif /* OVLB */
  1919.  
  1920. /*eat.c*/
  1921.