OSDN Git Service

087ea594c12aebddb6e5346f82a100f050bf7fcb
[jnethack/source.git] / src / eat.c
1 /* NetHack 3.6  eat.c   $NHDT-Date: 1502754159 2017/08/14 23:42:39 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.179 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2012. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2018            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 STATIC_PTR int NDECL(eatmdone);
14 STATIC_PTR int NDECL(eatfood);
15 STATIC_PTR struct obj *FDECL(costly_tin, (int));
16 STATIC_PTR int NDECL(opentin);
17 STATIC_PTR int NDECL(unfaint);
18
19 STATIC_DCL const char *FDECL(food_xname, (struct obj *, BOOLEAN_P));
20 STATIC_DCL void FDECL(choke, (struct obj *));
21 STATIC_DCL void NDECL(recalc_wt);
22 STATIC_DCL unsigned FDECL(obj_nutrition, (struct obj *));
23 STATIC_DCL struct obj *FDECL(touchfood, (struct obj *));
24 STATIC_DCL void NDECL(do_reset_eat);
25 STATIC_DCL void FDECL(done_eating, (BOOLEAN_P));
26 STATIC_DCL void FDECL(cprefx, (int));
27 STATIC_DCL int FDECL(intrinsic_possible, (int, struct permonst *));
28 STATIC_DCL void FDECL(givit, (int, struct permonst *));
29 STATIC_DCL void FDECL(cpostfx, (int));
30 STATIC_DCL void FDECL(consume_tin, (const char *));
31 STATIC_DCL void FDECL(start_tin, (struct obj *));
32 STATIC_DCL int FDECL(eatcorpse, (struct obj *));
33 STATIC_DCL void FDECL(start_eating, (struct obj *));
34 STATIC_DCL void FDECL(fprefx, (struct obj *));
35 STATIC_DCL void FDECL(fpostfx, (struct obj *));
36 STATIC_DCL int NDECL(bite);
37 STATIC_DCL int FDECL(edibility_prompts, (struct obj *));
38 STATIC_DCL int FDECL(rottenfood, (struct obj *));
39 STATIC_DCL void NDECL(eatspecial);
40 STATIC_DCL int FDECL(bounded_increase, (int, int, int));
41 STATIC_DCL void FDECL(accessory_has_effect, (struct obj *));
42 STATIC_DCL void FDECL(eataccessory, (struct obj *));
43 STATIC_DCL const char *FDECL(foodword, (struct obj *));
44 STATIC_DCL int FDECL(tin_variety, (struct obj *, BOOLEAN_P));
45 STATIC_DCL boolean FDECL(maybe_cannibal, (int, BOOLEAN_P));
46
47 char msgbuf[BUFSZ];
48
49 /* also used to see if you're allowed to eat cats and dogs */
50 #define CANNIBAL_ALLOWED() (Role_if(PM_CAVEMAN) || Race_if(PM_ORC))
51
52 /* monster types that cause hero to be turned into stone if eaten */
53 #define flesh_petrifies(pm) (touch_petrifies(pm) || (pm) == &mons[PM_MEDUSA])
54
55 /* Rider corpses are treated as non-rotting so that attempting to eat one
56    will be sure to reach the stage of eating where that meal is fatal */
57 #define nonrotting_corpse(mnum) \
58     ((mnum) == PM_LIZARD || (mnum) == PM_LICHEN || is_rider(&mons[mnum]))
59
60 /* non-rotting non-corpses; unlike lizard corpses, these items will behave
61    as if rotten if they are cursed (fortune cookies handled elsewhere) */
62 #define nonrotting_food(otyp) \
63     ((otyp) == LEMBAS_WAFER || (otyp) == CRAM_RATION)
64
65 STATIC_OVL NEARDATA const char comestibles[] = { FOOD_CLASS, 0 };
66 STATIC_OVL NEARDATA const char offerfodder[] = { FOOD_CLASS, AMULET_CLASS,
67                                                  0 };
68
69 /* Gold must come first for getobj(). */
70 STATIC_OVL NEARDATA const char allobj[] = {
71     COIN_CLASS,   WEAPON_CLASS, ARMOR_CLASS,  POTION_CLASS,
72     SCROLL_CLASS, WAND_CLASS,   RING_CLASS,   AMULET_CLASS,
73     FOOD_CLASS,   TOOL_CLASS,   GEM_CLASS,    ROCK_CLASS,
74     BALL_CLASS,   CHAIN_CLASS,  SPBOOK_CLASS, 0
75 };
76
77 STATIC_OVL boolean force_save_hs = FALSE;
78
79 /* see hunger states in hack.h - texts used on bottom line */
80 #if 0 /*JP*/
81 const char *hu_stat[] = { "Satiated", "        ", "Hungry  ", "Weak    ",
82                           "Fainting", "Fainted ", "Starved " };
83 #else
84 const char *hu_stat[] = { "\96\9e\95     ", "        ", "\82Ø\82±\82Ø\82±", "\90\8a\8eã    ",
85                           "\82Ó\82ç\82Ó\82ç", "\91²\93|    ", "\89ì\8e\80    " };
86 #endif
87
88 /*
89  * Decide whether a particular object can be eaten by the possibly
90  * polymorphed character.  Not used for monster checks.
91  */
92 boolean
93 is_edible(obj)
94 register struct obj *obj;
95 {
96     /* protect invocation tools but not Rider corpses (handled elsewhere)*/
97     /* if (obj->oclass != FOOD_CLASS && obj_resists(obj, 0, 0)) */
98     if (objects[obj->otyp].oc_unique)
99         return FALSE;
100     /* above also prevents the Amulet from being eaten, so we must never
101        allow fake amulets to be eaten either [which is already the case] */
102
103     if (metallivorous(youmonst.data) && is_metallic(obj)
104         && (youmonst.data != &mons[PM_RUST_MONSTER] || is_rustprone(obj)))
105         return TRUE;
106
107     /* Ghouls only eat non-veggy corpses or eggs (see dogfood()) */
108     if (u.umonnum == PM_GHOUL)
109         return (boolean)((obj->otyp == CORPSE
110                           && !vegan(&mons[obj->corpsenm]))
111                          || (obj->otyp == EGG));
112
113     if (u.umonnum == PM_GELATINOUS_CUBE && is_organic(obj)
114         /* [g.cubes can eat containers and retain all contents
115             as engulfed items, but poly'd player can't do that] */
116         && !Has_contents(obj))
117         return TRUE;
118
119     /* return (boolean) !!index(comestibles, obj->oclass); */
120     return (boolean) (obj->oclass == FOOD_CLASS);
121 }
122
123 void
124 init_uhunger()
125 {
126     context.botl = (u.uhs != NOT_HUNGRY || ATEMP(A_STR) < 0);
127     u.uhunger = 900;
128     u.uhs = NOT_HUNGRY;
129     if (ATEMP(A_STR) < 0)
130         ATEMP(A_STR) = 0;
131 }
132
133 /* tin types [SPINACH_TIN = -1, overrides corpsenm, nut==600] */
134 static const struct {
135     const char *txt;                      /* description */
136     int nut;                              /* nutrition */
137     Bitfield(fodder, 1);                  /* stocked by health food shops */
138     Bitfield(greasy, 1);                  /* causes slippery fingers */
139 #if 0 /*JP*/
140 } tintxts[] = { { "rotten", -50, 0, 0 },  /* ROTTEN_TIN = 0 */
141                 { "homemade", 50, 1, 0 }, /* HOMEMADE_TIN = 1 */
142                 { "soup made from", 20, 1, 0 },
143                 { "french fried", 40, 0, 1 },
144                 { "pickled", 40, 1, 0 },
145                 { "boiled", 50, 1, 0 },
146                 { "smoked", 50, 1, 0 },
147                 { "dried", 55, 1, 0 },
148                 { "deep fried", 60, 0, 1 },
149                 { "szechuan", 70, 1, 0 },
150                 { "broiled", 80, 0, 0 },
151                 { "stir fried", 80, 0, 1 },
152                 { "sauteed", 95, 0, 0 },
153                 { "candied", 100, 1, 0 },
154                 { "pureed", 500, 1, 0 },
155                 { "", 0, 0, 0 } };
156 #else
157 } tintxts[] = { { "\95\85\82Á\82½", -50, 0, 0 },  /* ROTTEN_TIN = 0 */
158                 { "\8e©\89Æ\90»\82Ì", 50, 1, 0 }, /* HOMEMADE_TIN = 1 */
159                 { "\82Ì\83X\81[\83v", 20, 1, 0 },
160                 { "\82Ì\83t\83\89\83C", 40, 0, 1 },
161                 { "\82Ì\92Ð\95¨", 40, 1, 0 },
162                 { "\82ä\82Å", 50, 1, 0 },
163                 { "\82Ìà\8e\90»", 50, 1, 0 },
164                 { "\8a£\91\87", 55, 1, 0 },
165                 { "\82Ì\97g\82°\95¨", 60, 0, 1 },
166                 { "\8el\90ì\95\97", 70, 1, 0 },
167                 { "\82Ì\96Ô\8fÄ\82«", 80, 0, 0 },
168                 { "àu\82ß", 80, 0, 1 },
169                 { "\82Ì\83\\83e\81[", 95, 0, 0 },
170                 { "\82Ì\8d»\93\9c\92Ð\82¯", 100, 1, 0 },
171                 { "\82Ì\83s\83\85\81[\83\8c", 500, 1, 0 },
172                 { "", 0, 0, 0 } };
173 #endif
174 #define TTSZ SIZE(tintxts)
175
176 static char *eatmbuf = 0; /* set by cpostfx() */
177
178 /* called after mimicing is over */
179 STATIC_PTR int
180 eatmdone(VOID_ARGS)
181 {
182     /* release `eatmbuf' */
183     if (eatmbuf) {
184         if (nomovemsg == eatmbuf)
185             nomovemsg = 0;
186         free((genericptr_t) eatmbuf), eatmbuf = 0;
187     }
188     /* update display */
189     if (youmonst.m_ap_type) {
190         youmonst.m_ap_type = M_AP_NOTHING;
191         newsym(u.ux, u.uy);
192     }
193     return 0;
194 }
195
196 /* called when hallucination is toggled */
197 void
198 eatmupdate()
199 {
200     const char *altmsg = 0;
201     int altapp = 0; /* lint suppression */
202
203     if (!eatmbuf || nomovemsg != eatmbuf)
204         return;
205
206     if (is_obj_mappear(&youmonst,ORANGE) && !Hallucination) {
207         /* revert from hallucinatory to "normal" mimicking */
208 /*JP
209         altmsg = "You now prefer mimicking yourself.";
210 */
211         altmsg = "\82 \82È\82½\82Í\8e©\95ª\8e©\90g\82Ì\82Ü\82Ë\82ð\82·\82é\82±\82Æ\82ð\91I\82ñ\82¾\81D";
212         altapp = GOLD_PIECE;
213     } else if (is_obj_mappear(&youmonst,GOLD_PIECE) && Hallucination) {
214         /* won't happen; anything which might make immobilized
215            hero begin hallucinating (black light attack, theft
216            of Grayswandir) will terminate the mimicry first */
217 /*JP
218         altmsg = "Your rind escaped intact.";
219 */
220         altmsg = "\82 \82È\82½\82Ì\94ç\82ª\82»\82Ì\82Ü\82Ü\82Ì\8c`\82Å\93¦\82°\82Ä\82¢\82Á\82½\81D";
221         altapp = ORANGE;
222     }
223
224     if (altmsg) {
225         /* replace end-of-mimicking message */
226         if (strlen(altmsg) > strlen(eatmbuf)) {
227             free((genericptr_t) eatmbuf);
228             eatmbuf = (char *) alloc(strlen(altmsg) + 1);
229         }
230         nomovemsg = strcpy(eatmbuf, altmsg);
231         /* update current image */
232         youmonst.mappearance = altapp;
233         newsym(u.ux, u.uy);
234     }
235 }
236
237 /* ``[the(] singular(food, xname) [)]'' */
238 STATIC_OVL const char *
239 food_xname(food, the_pfx)
240 struct obj *food;
241 boolean the_pfx;
242 {
243     const char *result;
244
245     if (food->otyp == CORPSE) {
246         result = corpse_xname(food, (const char *) 0,
247                               CXN_SINGULAR | (the_pfx ? CXN_PFX_THE : 0));
248         /* not strictly needed since pname values are capitalized
249            and the() is a no-op for them */
250         if (type_is_pname(&mons[food->corpsenm]))
251             the_pfx = FALSE;
252     } else {
253         /* the ordinary case */
254         result = singular(food, xname);
255     }
256     if (the_pfx)
257         result = the(result);
258     return result;
259 }
260
261 /* Created by GAN 01/28/87
262  * Amended by AKP 09/22/87: if not hard, don't choke, just vomit.
263  * Amended by 3.  06/12/89: if not hard, sometimes choke anyway, to keep risk.
264  *                11/10/89: if hard, rarely vomit anyway, for slim chance.
265  *
266  * To a full belly all food is bad. (It.)
267  */
268 STATIC_OVL void
269 choke(food)
270 struct obj *food;
271 {
272     /* only happens if you were satiated */
273     if (u.uhs != SATIATED) {
274         if (!food || food->otyp != AMULET_OF_STRANGULATION)
275             return;
276     } else if (Role_if(PM_KNIGHT) && u.ualign.type == A_LAWFUL) {
277         adjalign(-1); /* gluttony is unchivalrous */
278 /*JP
279         You_feel("like a glutton!");
280 */
281         You("\91å\90H\8a¿\82Ì\82æ\82¤\82È\8bC\82ª\82µ\82½\81I");
282     }
283
284     exercise(A_CON, FALSE);
285
286     if (Breathless || (!Strangled && !rn2(20))) {
287         /* choking by eating AoS doesn't involve stuffing yourself */
288         if (food && food->otyp == AMULET_OF_STRANGULATION) {
289 /*JP
290             You("choke, but recover your composure.");
291 */
292             You("\8eñ\82ð\8di\82ß\82ç\82ê\82½\81D\82µ\82©\82µ\82È\82ñ\82Æ\82à\82È\82©\82Á\82½\81D");
293             return;
294         }
295 /*JP
296         You("stuff yourself and then vomit voluminously.");
297 */
298         pline("\82ª\82Â\82ª\82Â\82Æ\8cû\82É\8bl\82ß\8d\9e\82ñ\82¾\82ª\81C\83h\83o\82Á\82Æ\93f\82«\8fo\82µ\82Ä\82µ\82Ü\82Á\82½\81D");
299         morehungry(1000); /* you just got *very* sick! */
300         vomit();
301     } else {
302         killer.format = KILLED_BY_AN;
303         /*
304          * Note all "killer"s below read "Choked on %s" on the
305          * high score list & tombstone.  So plan accordingly.
306          */
307         if (food) {
308 /*JP
309             You("choke over your %s.", foodword(food));
310 */
311             You("%s\82ð\8dA\82É\8bl\82Ü\82ç\82¹\82Ä\82µ\82Ü\82Á\82½\81D", foodword(food));
312             if (food->oclass == COIN_CLASS) {
313 /*JP
314                 Strcpy(killer.name, "very rich meal");
315 */
316                 Strcpy(killer.name, "\82Æ\82Ä\82à\8d\82\89¿\82È\97¿\97\9d");
317             } else {
318                 killer.format = KILLED_BY;
319                 Strcpy(killer.name, killer_xname(food));
320             }
321         } else {
322 /*JP
323             You("choke over it.");
324 */
325             pline("\8dA\82É\8bl\82Ü\82ç\82¹\82Ä\82µ\82Ü\82Á\82½\81D");
326 /*JP
327             Strcpy(killer.name, "quick snack");
328 */
329             Strcpy(killer.name, "\91\81\90H\82¢");
330         }
331 /*JP
332         You("die...");
333 */
334         pline("\82 \82È\82½\82Í\8e\80\82É\82Ü\82µ\82½\81D\81D\81D");
335         done(CHOKING);
336     }
337 }
338
339 /* modify object wt. depending on time spent consuming it */
340 STATIC_OVL void
341 recalc_wt()
342 {
343     struct obj *piece = context.victual.piece;
344     if (!piece) {
345         impossible("recalc_wt without piece");
346         return;
347     }
348     debugpline1("Old weight = %d", piece->owt);
349     debugpline2("Used time = %d, Req'd time = %d", context.victual.usedtime,
350                 context.victual.reqtime);
351     piece->owt = weight(piece);
352     debugpline1("New weight = %d", piece->owt);
353 }
354
355 /* called when eating interrupted by an event */
356 void
357 reset_eat()
358 {
359     /* we only set a flag here - the actual reset process is done after
360      * the round is spent eating.
361      */
362     if (context.victual.eating && !context.victual.doreset) {
363         debugpline0("reset_eat...");
364         context.victual.doreset = TRUE;
365     }
366     return;
367 }
368
369 /* base nutrition of a food-class object */
370 STATIC_OVL unsigned
371 obj_nutrition(otmp)
372 struct obj *otmp;
373 {
374     unsigned nut = (otmp->otyp == CORPSE) ? mons[otmp->corpsenm].cnutrit
375                       : otmp->globby ? otmp->owt
376                          : (unsigned) objects[otmp->otyp].oc_nutrition;
377
378     if (otmp->otyp == LEMBAS_WAFER) {
379         if (maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF)))
380             nut += nut / 4; /* 800 -> 1000 */
381         else if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC)))
382             nut -= nut / 4; /* 800 -> 600 */
383         /* prevent polymorph making a partly eaten wafer
384            become more nutritious than an untouched one */
385         if (otmp->oeaten >= nut)
386             otmp->oeaten = (otmp->oeaten < objects[LEMBAS_WAFER].oc_nutrition)
387                               ? (nut - 1) : nut;
388     } else if (otmp->otyp == CRAM_RATION) {
389         if (maybe_polyd(is_dwarf(youmonst.data), Race_if(PM_DWARF)))
390             nut += nut / 6; /* 600 -> 700 */
391     }
392     return nut;
393 }
394
395 STATIC_OVL struct obj *
396 touchfood(otmp)
397 struct obj *otmp;
398 {
399     if (otmp->quan > 1L) {
400         if (!carried(otmp))
401             (void) splitobj(otmp, otmp->quan - 1L);
402         else
403             otmp = splitobj(otmp, 1L);
404         debugpline0("split object,");
405     }
406
407     if (!otmp->oeaten) {
408         costly_alteration(otmp, COST_BITE);
409         otmp->oeaten = obj_nutrition(otmp);
410     }
411
412     if (carried(otmp)) {
413         freeinv(otmp);
414         if (inv_cnt(FALSE) >= 52) {
415             sellobj_state(SELL_DONTSELL);
416             dropy(otmp);
417             sellobj_state(SELL_NORMAL);
418         } else {
419             otmp->nomerge = 1; /* used to prevent merge */
420             otmp = addinv(otmp);
421             otmp->nomerge = 0;
422         }
423     }
424     return otmp;
425 }
426
427 /* When food decays, in the middle of your meal, we don't want to dereference
428  * any dangling pointers, so set it to null (which should still trigger
429  * do_reset_eat() at the beginning of eatfood()) and check for null pointers
430  * in do_reset_eat().
431  */
432 void
433 food_disappears(obj)
434 struct obj *obj;
435 {
436     if (obj == context.victual.piece) {
437         context.victual.piece = (struct obj *) 0;
438         context.victual.o_id = 0;
439     }
440     if (obj->timed)
441         obj_stop_timers(obj);
442 }
443
444 /* renaming an object used to result in it having a different address,
445    so the sequence start eating/opening, get interrupted, name the food,
446    resume eating/opening would restart from scratch */
447 void
448 food_substitution(old_obj, new_obj)
449 struct obj *old_obj, *new_obj;
450 {
451     if (old_obj == context.victual.piece) {
452         context.victual.piece = new_obj;
453         context.victual.o_id = new_obj->o_id;
454     }
455     if (old_obj == context.tin.tin) {
456         context.tin.tin = new_obj;
457         context.tin.o_id = new_obj->o_id;
458     }
459 }
460
461 STATIC_OVL void
462 do_reset_eat()
463 {
464     debugpline0("do_reset_eat...");
465     if (context.victual.piece) {
466         context.victual.o_id = 0;
467         context.victual.piece = touchfood(context.victual.piece);
468         if (context.victual.piece)
469             context.victual.o_id = context.victual.piece->o_id;
470         recalc_wt();
471     }
472     context.victual.fullwarn = context.victual.eating =
473         context.victual.doreset = FALSE;
474     /* Do not set canchoke to FALSE; if we continue eating the same object
475      * we need to know if canchoke was set when they started eating it the
476      * previous time.  And if we don't continue eating the same object
477      * canchoke always gets recalculated anyway.
478      */
479     stop_occupation();
480     newuhs(FALSE);
481 }
482
483 /* called each move during eating process */
484 STATIC_PTR int
485 eatfood(VOID_ARGS)
486 {
487     if (!context.victual.piece
488         || (!carried(context.victual.piece)
489             && !obj_here(context.victual.piece, u.ux, u.uy))) {
490         /* maybe it was stolen? */
491         do_reset_eat();
492         return 0;
493     }
494     if (!context.victual.eating)
495         return 0;
496
497     if (++context.victual.usedtime <= context.victual.reqtime) {
498         if (bite())
499             return 0;
500         return 1; /* still busy */
501     } else {        /* done */
502         done_eating(TRUE);
503         return 0;
504     }
505 }
506
507 STATIC_OVL void
508 done_eating(message)
509 boolean message;
510 {
511     struct obj *piece = context.victual.piece;
512
513     piece->in_use = TRUE;
514     occupation = 0; /* do this early, so newuhs() knows we're done */
515     newuhs(FALSE);
516     if (nomovemsg) {
517         if (message)
518             pline1(nomovemsg);
519         nomovemsg = 0;
520     } else if (message)
521 /*JP
522         You("finish eating %s.", food_xname(piece, TRUE));
523 */
524         You("%s\82ð\90H\82×\8fI\82¦\82½\81D",  food_xname(piece, TRUE));
525
526     if (piece->otyp == CORPSE || piece->globby)
527         cpostfx(piece->corpsenm);
528     else
529         fpostfx(piece);
530
531     if (carried(piece))
532         useup(piece);
533     else
534         useupf(piece, 1L);
535     context.victual.piece = (struct obj *) 0;
536     context.victual.o_id = 0;
537     context.victual.fullwarn = context.victual.eating =
538         context.victual.doreset = FALSE;
539 }
540
541 void
542 eating_conducts(pd)
543 struct permonst *pd;
544 {
545     u.uconduct.food++;
546     if (!vegan(pd))
547         u.uconduct.unvegan++;
548     if (!vegetarian(pd))
549         violated_vegetarian();
550 }
551
552 /* handle side-effects of mind flayer's tentacle attack */
553 int
554 eat_brains(magr, mdef, visflag, dmg_p)
555 struct monst *magr, *mdef;
556 boolean visflag;
557 int *dmg_p; /* for dishing out extra damage in lieu of Int loss */
558 {
559     struct permonst *pd = mdef->data;
560     boolean give_nutrit = FALSE;
561     int result = MM_HIT, xtra_dmg = rnd(10);
562
563     if (noncorporeal(pd)) {
564         if (visflag)
565 #if 0 /*JP*/
566             pline("%s brain is unharmed.",
567                   (mdef == &youmonst) ? "Your" : s_suffix(Monnam(mdef)));
568 #else
569             pline("%s\82Ì\94]\82Í\96³\8e\96\82¾\82Á\82½\81D",
570                   (mdef == &youmonst) ? "\82 \82È\82½" : Monnam(mdef));
571 #endif
572         return MM_MISS; /* side-effects can't occur */
573     } else if (magr == &youmonst) {
574 /*JP
575         You("eat %s brain!", s_suffix(mon_nam(mdef)));
576 */
577         You("%s\82Ì\94]\82ð\90H\82×\82½\81I", mon_nam(mdef));
578     } else if (mdef == &youmonst) {
579 /*JP
580         Your("brain is eaten!");
581 */
582         Your("\94]\82Í\90H\82×\82ç\82ê\82½\81I");
583     } else { /* monster against monster */
584         if (visflag && canspotmon(mdef))
585 /*JP
586             pline("%s brain is eaten!", s_suffix(Monnam(mdef)));
587 */
588             pline("%s\82Ì\94]\82Í\90H\82×\82ç\82ê\82½\81I", Monnam(mdef));
589     }
590
591     if (flesh_petrifies(pd)) {
592         /* mind flayer has attempted to eat the brains of a petrification
593            inducing critter (most likely Medusa; attacking a cockatrice via
594            tentacle-touch should have been caught before reaching this far) */
595         if (magr == &youmonst) {
596             if (!Stone_resistance && !Stoned)
597                 make_stoned(5L, (char *) 0, KILLED_BY_AN, pd->mname);
598         } else {
599             /* no need to check for poly_when_stoned or Stone_resistance;
600                mind flayers don't have those capabilities */
601             if (visflag && canseemon(magr))
602 /*JP
603                 pline("%s turns to stone!", Monnam(magr));
604 */
605                 pline("%s\82Í\90Î\82É\82È\82Á\82½\81I", Monnam(magr));
606             monstone(magr);
607             if (magr->mhp > 0) {
608                 /* life-saved; don't continue eating the brains */
609                 return MM_MISS;
610             } else {
611                 if (magr->mtame && !visflag)
612                     /* parallels mhitm.c's brief_feeling */
613 /*JP
614                     You("have a sad thought for a moment, then it passes.");
615 */
616                     You("\94ß\82µ\82¢\8dl\82¦\82É\82¨\82»\82í\82ê\82½\82ª\81A\82·\82®\82É\89ß\82¬\82³\82Á\82½\81D");
617                 return MM_AGR_DIED;
618             }
619         }
620     }
621
622     if (magr == &youmonst) {
623         /*
624          * player mind flayer is eating something's brain
625          */
626         eating_conducts(pd);
627         if (mindless(pd)) { /* (cannibalism not possible here) */
628 /*JP
629             pline("%s doesn't notice.", Monnam(mdef));
630 */
631             pline("%s\82Í\8bC\82Ã\82¢\82Ä\82¢\82È\82¢\81D", Monnam(mdef));
632             /* all done; no extra harm inflicted upon target */
633             return MM_MISS;
634         } else if (is_rider(pd)) {
635 /*JP
636             pline("Ingesting that is fatal.");
637 */
638             pline("\8eæ\82è\8d\9e\82ñ\82¾\82ç\82·\82®\82É\8e\80\82ñ\82Å\82µ\82Ü\82Á\82½\81D");
639 #if 0 /*JP*/
640             Sprintf(killer.name, "unwisely ate the brain of %s", pd->mname);
641             killer.format = NO_KILLER_PREFIX;
642 #else
643             Sprintf(killer.name, "\8bð\82©\82É\82à%s\82Ì\91Ì\82ð\90H\82×\82Ä", pd->mname);
644             killer.format = KILLED_BY;
645 #endif
646             done(DIED);
647             /* life-saving needed to reach here */
648             exercise(A_WIS, FALSE);
649             *dmg_p += xtra_dmg; /* Rider takes extra damage */
650         } else {
651             morehungry(-rnd(30)); /* cannot choke */
652             if (ABASE(A_INT) < AMAX(A_INT)) {
653                 /* recover lost Int; won't increase current max */
654                 ABASE(A_INT) += rnd(4);
655                 if (ABASE(A_INT) > AMAX(A_INT))
656                     ABASE(A_INT) = AMAX(A_INT);
657                 context.botl = 1;
658             }
659             exercise(A_WIS, TRUE);
660             *dmg_p += xtra_dmg;
661         }
662         /* targetting another mind flayer or your own underlying species
663            is cannibalism */
664         (void) maybe_cannibal(monsndx(pd), TRUE);
665
666     } else if (mdef == &youmonst) {
667         /*
668          * monster mind flayer is eating hero's brain
669          */
670         /* no such thing as mindless players */
671         if (ABASE(A_INT) <= ATTRMIN(A_INT)) {
672 /*JP
673             static NEARDATA const char brainlessness[] = "brainlessness";
674 */
675             static NEARDATA const char brainlessness[] = "\94]\82ð\8e¸\82Á\82Ä";
676
677             if (Lifesaved) {
678                 Strcpy(killer.name, brainlessness);
679                 killer.format = KILLED_BY;
680                 done(DIED);
681                 /* amulet of life saving has now been used up */
682 /*JP
683                 pline("Unfortunately your brain is still gone.");
684 */
685                 pline("\8ec\94O\82È\82ª\82ç\82 \82È\82½\82É\82Í\94]\82ª\82È\82¢\81D");
686                 /* sanity check against adding other forms of life-saving */
687                 u.uprops[LIFESAVED].extrinsic =
688                     u.uprops[LIFESAVED].intrinsic = 0L;
689             } else {
690 /*JP
691                 Your("last thought fades away.");
692 */
693                 Your("\8dÅ\8cã\82Ì\8ev\82¢\82ª\91\96\94n\93\95\82Ì\82æ\82¤\82É\89¡\82¬\82Á\82½\81D");
694             }
695             Strcpy(killer.name, brainlessness);
696             killer.format = KILLED_BY;
697             done(DIED);
698             /* can only get here when in wizard or explore mode and user has
699                explicitly chosen not to die; arbitrarily boost intelligence */
700             ABASE(A_INT) = ATTRMIN(A_INT) + 2;
701 /*JP
702             You_feel("like a scarecrow.");
703 */
704             You("\82©\82©\82µ\82Ì\82æ\82¤\82È\8bC\8e\9d\82ª\82µ\82½\81D");
705         }
706         give_nutrit = TRUE; /* in case a conflicted pet is doing this */
707         exercise(A_WIS, FALSE);
708         /* caller handles Int and memory loss */
709
710     } else { /* mhitm */
711         /*
712          * monster mind flayer is eating another monster's brain
713          */
714         if (mindless(pd)) {
715             if (visflag && canspotmon(mdef))
716 /*JP
717                 pline("%s doesn't notice.", Monnam(mdef));
718 */
719                 pline("%s\82Í\8bC\82Ã\82¢\82Ä\82¢\82È\82¢\81D", Monnam(mdef));
720             return MM_MISS;
721         } else if (is_rider(pd)) {
722             mondied(magr);
723             if (magr->mhp <= 0)
724                 result = MM_AGR_DIED;
725             /* Rider takes extra damage regardless of whether attacker dies */
726             *dmg_p += xtra_dmg;
727         } else {
728             *dmg_p += xtra_dmg;
729             give_nutrit = TRUE;
730             if (*dmg_p >= mdef->mhp && visflag && canspotmon(mdef))
731 #if 0 /*JP*/
732                 pline("%s last thought fades away...",
733                       s_suffix(Monnam(mdef)));
734 #else
735                 pline("%s\82Ì\8dÅ\8cã\82Ì\8ev\82¢\82ª\82æ\82¬\82é\81D\81D\81D",
736                       Monnam(mdef));
737 #endif
738         }
739     }
740
741     if (give_nutrit && magr->mtame && !magr->isminion) {
742         EDOG(magr)->hungrytime += rnd(60);
743         magr->mconf = 0;
744     }
745
746     return result;
747 }
748
749 /* eating a corpse or egg of one's own species is usually naughty */
750 STATIC_OVL boolean
751 maybe_cannibal(pm, allowmsg)
752 int pm;
753 boolean allowmsg;
754 {
755     static NEARDATA long ate_brains = 0L;
756     struct permonst *fptr = &mons[pm]; /* food type */
757
758     /* when poly'd into a mind flayer, multiple tentacle hits in one
759        turn cause multiple digestion checks to occur; avoid giving
760        multiple luck penalties for the same attack */
761     if (moves == ate_brains)
762         return FALSE;
763     ate_brains = moves; /* ate_anything, not just brains... */
764
765     if (!CANNIBAL_ALLOWED()
766         /* non-cannibalistic heroes shouldn't eat own species ever
767            and also shouldn't eat current species when polymorphed
768            (even if having the form of something which doesn't care
769            about cannibalism--hero's innate traits aren't altered) */
770         && (your_race(fptr)
771             || (Upolyd && same_race(youmonst.data, fptr))
772             || (u.ulycn >= LOW_PM && were_beastie(pm) == u.ulycn))) {
773         if (allowmsg) {
774             if (Upolyd && your_race(fptr))
775 /*JP
776                 You("have a bad feeling deep inside.");
777 */
778                 You("\8c\99\88«\8a´\82É\82¨\82»\82í\82ê\82½\81D");
779 /*JP
780             You("cannibal!  You will regret this!");
781 */
782             pline("\8b¤\8bò\82¢\82¾\81I\8cã\89÷\82·\82é\82¼\81I");
783         }
784         HAggravate_monster |= FROMOUTSIDE;
785         change_luck(-rn1(4, 2)); /* -5..-2 */
786         return TRUE;
787     }
788     return FALSE;
789 }
790
791 STATIC_OVL void
792 cprefx(pm)
793 register int pm;
794 {
795     (void) maybe_cannibal(pm, TRUE);
796     if (flesh_petrifies(&mons[pm])) {
797         if (!Stone_resistance
798             && !(poly_when_stoned(youmonst.data)
799                  && polymon(PM_STONE_GOLEM))) {
800 /*JP
801             Sprintf(killer.name, "tasting %s meat", mons[pm].mname);
802 */
803             Sprintf(killer.name, "%s\82Ì\93÷\82ð\90H\82×", mons[pm].mname);
804             killer.format = KILLED_BY;
805 /*JP
806             You("turn to stone.");
807 */
808             You("\90Î\82É\82È\82Á\82½\81D");
809             done(STONING);
810             if (context.victual.piece)
811                 context.victual.eating = FALSE;
812             return; /* lifesaved */
813         }
814     }
815
816     switch (pm) {
817     case PM_LITTLE_DOG:
818     case PM_DOG:
819     case PM_LARGE_DOG:
820     case PM_KITTEN:
821     case PM_HOUSECAT:
822     case PM_LARGE_CAT:
823         /* cannibals are allowed to eat domestic animals without penalty */
824         if (!CANNIBAL_ALLOWED()) {
825 /*JP
826             You_feel("that eating the %s was a bad idea.", mons[pm].mname);
827 */
828             pline("%s\82ð\90H\82×\82é\82Ì\82Í\82æ\82­\82È\82¢\8bC\82ª\82µ\82½\81D", mons[pm].mname);
829             HAggravate_monster |= FROMOUTSIDE;
830         }
831         break;
832     case PM_LIZARD:
833         if (Stoned)
834             fix_petrification();
835         break;
836     case PM_DEATH:
837     case PM_PESTILENCE:
838     case PM_FAMINE: {
839 /*JP
840         pline("Eating that is instantly fatal.");
841 */
842         pline("\90H\82×\82½\82ç\82·\82®\82É\8e\80\82ñ\82Å\82µ\82Ü\82Á\82½\81D");
843 #if 0 /*JP*/
844         Sprintf(killer.name, "unwisely ate the body of %s", mons[pm].mname);
845         killer.format = NO_KILLER_PREFIX;
846 #else
847         Sprintf(killer.name, "\8bð\82©\82É\82à%s\82Ì\91Ì\82ð\90H\82×\82Ä", mons[pm].mname);
848         killer.format = KILLED_BY;
849 #endif
850         done(DIED);
851         /* life-saving needed to reach here */
852         exercise(A_WIS, FALSE);
853         /* It so happens that since we know these monsters */
854         /* cannot appear in tins, context.victual.piece will always */
855         /* be what we want, which is not generally true. */
856         if (revive_corpse(context.victual.piece)) {
857             context.victual.piece = (struct obj *) 0;
858             context.victual.o_id = 0;
859         }
860         return;
861     }
862     case PM_GREEN_SLIME:
863         if (!Slimed && !Unchanging && !slimeproof(youmonst.data)) {
864 /*JP
865             You("don't feel very well.");
866 */
867             You("\82·\82²\82­\8bC\95ª\82ª\88«\82¢\81D");
868             make_slimed(10L, (char *) 0);
869             delayed_killer(SLIMED, KILLED_BY_AN, "");
870         }
871     /* Fall through */
872     default:
873         if (acidic(&mons[pm]) && Stoned)
874             fix_petrification();
875         break;
876     }
877 }
878
879 void
880 fix_petrification()
881 {
882     char buf[BUFSZ];
883
884     if (Hallucination)
885 #if 0 /*JP*/
886         Sprintf(buf, "What a pity--you just ruined a future piece of %sart!",
887                 ACURR(A_CHA) > 15 ? "fine " : "");
888 #else
889         Sprintf(buf, "\82È\82ñ\82Ä\82±\82Æ\82¾\81I%s\8c|\8fp\8dì\95i\82É\82È\82ê\82½\82©\82à\82µ\82ê\82È\82¢\82Ì\82É\81I",
890                 ACURR(A_CHA) > 15 ? "\8bM\8fd\82È" : "");
891 #endif
892     else
893 /*JP
894         Strcpy(buf, "You feel limber!");
895 */
896         Strcpy(buf, "\91Ì\82ª\93î\82ç\82©\82­\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81I");
897     make_stoned(0L, buf, 0, (char *) 0);
898 }
899
900 /*
901  * If you add an intrinsic that can be gotten by eating a monster, add it
902  * to intrinsic_possible() and givit().  (It must already be in prop.h to
903  * be an intrinsic property.)
904  * It would be very easy to make the intrinsics not try to give you one
905  * that you already had by checking to see if you have it in
906  * intrinsic_possible() instead of givit(), but we're not that nice.
907  */
908
909 /* intrinsic_possible() returns TRUE iff a monster can give an intrinsic. */
910 STATIC_OVL int
911 intrinsic_possible(type, ptr)
912 int type;
913 register struct permonst *ptr;
914 {
915     int res = 0;
916
917 #ifdef DEBUG
918 #define ifdebugresist(Msg)      \
919     do {                        \
920         if (res)                \
921             debugpline0(Msg);   \
922     } while (0)
923 #else
924 #define ifdebugresist(Msg) /*empty*/
925 #endif
926     switch (type) {
927     case FIRE_RES:
928         res = (ptr->mconveys & MR_FIRE) != 0;
929         ifdebugresist("can get fire resistance");
930         break;
931     case SLEEP_RES:
932         res = (ptr->mconveys & MR_SLEEP) != 0;
933         ifdebugresist("can get sleep resistance");
934         break;
935     case COLD_RES:
936         res = (ptr->mconveys & MR_COLD) != 0;
937         ifdebugresist("can get cold resistance");
938         break;
939     case DISINT_RES:
940         res = (ptr->mconveys & MR_DISINT) != 0;
941         ifdebugresist("can get disintegration resistance");
942         break;
943     case SHOCK_RES: /* shock (electricity) resistance */
944         res = (ptr->mconveys & MR_ELEC) != 0;
945         ifdebugresist("can get shock resistance");
946         break;
947     case POISON_RES:
948         res = (ptr->mconveys & MR_POISON) != 0;
949         ifdebugresist("can get poison resistance");
950         break;
951     case TELEPORT:
952         res = can_teleport(ptr);
953         ifdebugresist("can get teleport");
954         break;
955     case TELEPORT_CONTROL:
956         res = control_teleport(ptr);
957         ifdebugresist("can get teleport control");
958         break;
959     case TELEPAT:
960         res = telepathic(ptr);
961         ifdebugresist("can get telepathy");
962         break;
963     default:
964         /* res stays 0 */
965         break;
966     }
967 #undef ifdebugresist
968     return res;
969 }
970
971 /* givit() tries to give you an intrinsic based on the monster's level
972  * and what type of intrinsic it is trying to give you.
973  */
974 STATIC_OVL void
975 givit(type, ptr)
976 int type;
977 register struct permonst *ptr;
978 {
979     register int chance;
980
981     debugpline1("Attempting to give intrinsic %d", type);
982     /* some intrinsics are easier to get than others */
983     switch (type) {
984     case POISON_RES:
985         if ((ptr == &mons[PM_KILLER_BEE] || ptr == &mons[PM_SCORPION])
986             && !rn2(4))
987             chance = 1;
988         else
989             chance = 15;
990         break;
991     case TELEPORT:
992         chance = 10;
993         break;
994     case TELEPORT_CONTROL:
995         chance = 12;
996         break;
997     case TELEPAT:
998         chance = 1;
999         break;
1000     default:
1001         chance = 15;
1002         break;
1003     }
1004
1005     if (ptr->mlevel <= rn2(chance))
1006         return; /* failed die roll */
1007
1008     switch (type) {
1009     case FIRE_RES:
1010         debugpline0("Trying to give fire resistance");
1011         if (!(HFire_resistance & FROMOUTSIDE)) {
1012 /*JP
1013             You(Hallucination ? "be chillin'." : "feel a momentary chill.");
1014 */
1015             You(Hallucination ? "\81u\83N\81[\83\8b\91î\94z\95Ö\81v\82³\82ê\82Ä\82¢\82é\82æ\82¤\82¾\81D" : "\88ê\8fu\8a¦\82¯\82ª\82µ\82½\81D");
1016             HFire_resistance |= FROMOUTSIDE;
1017         }
1018         break;
1019     case SLEEP_RES:
1020         debugpline0("Trying to give sleep resistance");
1021         if (!(HSleep_resistance & FROMOUTSIDE)) {
1022 /*JP
1023             You_feel("wide awake.");
1024 */
1025             You("\82Ï\82Á\82¿\82è\96Ú\82ª\82³\82ß\82½\81D");
1026             HSleep_resistance |= FROMOUTSIDE;
1027         }
1028         break;
1029     case COLD_RES:
1030         debugpline0("Trying to give cold resistance");
1031         if (!(HCold_resistance & FROMOUTSIDE)) {
1032 /*JP
1033             You_feel("full of hot air.");
1034 */
1035             You("\94M\95\97\82ð\91S\90g\82É\8a´\82\82½\81D");
1036             HCold_resistance |= FROMOUTSIDE;
1037         }
1038         break;
1039     case DISINT_RES:
1040         debugpline0("Trying to give disintegration resistance");
1041         if (!(HDisint_resistance & FROMOUTSIDE)) {
1042 /*JP
1043             You_feel(Hallucination ? "totally together, man." : "very firm.");
1044 */
1045             You_feel(Hallucination ? "\90¢\8aE\90l\97Þ\82Æ\8cZ\92í\82É\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D" : "\82Æ\82Ä\82à\8aæ\8fä\82É\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
1046             HDisint_resistance |= FROMOUTSIDE;
1047         }
1048         break;
1049     case SHOCK_RES: /* shock (electricity) resistance */
1050         debugpline0("Trying to give shock resistance");
1051         if (!(HShock_resistance & FROMOUTSIDE)) {
1052             if (Hallucination)
1053 /*JP
1054                 You_feel("grounded in reality.");
1055 */
1056               You("\8eÀ\82Í\83A\81[\83X\82³\82ê\82Ä\82¢\82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
1057             else
1058 /*JP
1059                 Your("health currently feels amplified!");
1060 */
1061               pline("\8c\92\8dN\82ª\91\9d\95\9d\82³\82ê\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81I");
1062             HShock_resistance |= FROMOUTSIDE;
1063         }
1064         break;
1065     case POISON_RES:
1066         debugpline0("Trying to give poison resistance");
1067         if (!(HPoison_resistance & FROMOUTSIDE)) {
1068 /*JP
1069             You_feel(Poison_resistance ? "especially healthy." : "healthy.");
1070 */
1071             You_feel(Poison_resistance ? "\93Á\82É\8c\92\8dN\82É\82È\82Á\82½\8bC\82ª\82µ\82½\81D" : "\8c\92\8dN\82É\82È\82Á\82½\8bC\82ª\82µ\82½\81D");
1072             HPoison_resistance |= FROMOUTSIDE;
1073         }
1074         break;
1075     case TELEPORT:
1076         debugpline0("Trying to give teleport");
1077         if (!(HTeleportation & FROMOUTSIDE)) {
1078 /*JP
1079             You_feel(Hallucination ? "diffuse." : "very jumpy.");
1080 */
1081             pline(Hallucination ? "\91Ì\82ª\94ò\82Ñ\8eU\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D" : "\92µ\96ô\97Í\82ª\8d\82\82Ü\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
1082             HTeleportation |= FROMOUTSIDE;
1083         }
1084         break;
1085     case TELEPORT_CONTROL:
1086         debugpline0("Trying to give teleport control");
1087         if (!(HTeleport_control & FROMOUTSIDE)) {
1088 #if 0 /*JP*/
1089             You_feel(Hallucination ? "centered in your personal space."
1090                                    : "in control of yourself.");
1091 #else
1092             You_feel(Hallucination ? "\8e©\8cÈ\92\86\90S\93I\82É\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D"
1093                                    : "\8e©\95ª\8e©\90g\82ð\90§\8cä\82Å\82«\82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
1094 #endif
1095             HTeleport_control |= FROMOUTSIDE;
1096         }
1097         break;
1098     case TELEPAT:
1099         debugpline0("Trying to give telepathy");
1100         if (!(HTelepat & FROMOUTSIDE)) {
1101 #if 0 /*JP*/
1102             You_feel(Hallucination ? "in touch with the cosmos."
1103                                    : "a strange mental acuity.");
1104 #else
1105             You_feel(Hallucination ? "\89F\92\88\82Ì\90_\94é\82É\90G\82ê\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D"
1106                                    : "\8aï\96­\82È\90¸\90_\93I\89s\82³\82ð\8a´\82\82½\81D");
1107 #endif
1108             HTelepat |= FROMOUTSIDE;
1109             /* If blind, make sure monsters show up. */
1110             if (Blind)
1111                 see_monsters();
1112         }
1113         break;
1114     default:
1115         debugpline0("Tried to give an impossible intrinsic");
1116         break;
1117     }
1118 }
1119
1120 /* called after completely consuming a corpse */
1121 STATIC_OVL void
1122 cpostfx(pm)
1123 register int pm;
1124 {
1125     register int tmp = 0;
1126     int catch_lycanthropy = NON_PM;
1127
1128     /* in case `afternmv' didn't get called for previously mimicking
1129        gold, clean up now to avoid `eatmbuf' memory leak */
1130     if (eatmbuf)
1131         (void) eatmdone();
1132
1133     switch (pm) {
1134     case PM_NEWT:
1135         /* MRKR: "eye of newt" may give small magical energy boost */
1136         if (rn2(3) || 3 * u.uen <= 2 * u.uenmax) {
1137             int old_uen = u.uen;
1138             u.uen += rnd(3);
1139             if (u.uen > u.uenmax) {
1140                 if (!rn2(3))
1141                     u.uenmax++;
1142                 u.uen = u.uenmax;
1143             }
1144             if (old_uen != u.uen) {
1145 /*JP
1146                 You_feel("a mild buzz.");
1147 */
1148                 You("\82·\82±\82µ\82Ó\82ç\82Ó\82ç\82µ\82½\81D");
1149                 context.botl = 1;
1150             }
1151         }
1152         break;
1153     case PM_WRAITH:
1154         pluslvl(FALSE);
1155         break;
1156     case PM_HUMAN_WERERAT:
1157         catch_lycanthropy = PM_WERERAT;
1158         break;
1159     case PM_HUMAN_WEREJACKAL:
1160         catch_lycanthropy = PM_WEREJACKAL;
1161         break;
1162     case PM_HUMAN_WEREWOLF:
1163         catch_lycanthropy = PM_WEREWOLF;
1164         break;
1165     case PM_NURSE:
1166         if (Upolyd)
1167             u.mh = u.mhmax;
1168         else
1169             u.uhp = u.uhpmax;
1170         make_blinded(0L, !u.ucreamed);
1171         context.botl = 1;
1172         break;
1173     case PM_STALKER:
1174         if (!Invis) {
1175             set_itimeout(&HInvis, (long) rn1(100, 50));
1176             if (!Blind && !BInvis)
1177                 self_invis_message();
1178         } else {
1179             if (!(HInvis & INTRINSIC))
1180 /*JP
1181                 You_feel("hidden!");
1182 */
1183                 Your("\8ep\82Í\89B\82³\82ê\82½\81I");
1184             HInvis |= FROMOUTSIDE;
1185             HSee_invisible |= FROMOUTSIDE;
1186         }
1187         newsym(u.ux, u.uy);
1188         /*FALLTHRU*/
1189     case PM_YELLOW_LIGHT:
1190     case PM_GIANT_BAT:
1191         make_stunned((HStun & TIMEOUT) + 30L, FALSE);
1192         /*FALLTHRU*/
1193     case PM_BAT:
1194         make_stunned((HStun & TIMEOUT) + 30L, FALSE);
1195         break;
1196     case PM_GIANT_MIMIC:
1197         tmp += 10;
1198         /*FALLTHRU*/
1199     case PM_LARGE_MIMIC:
1200         tmp += 20;
1201         /*FALLTHRU*/
1202     case PM_SMALL_MIMIC:
1203         tmp += 20;
1204         if (youmonst.data->mlet != S_MIMIC && !Unchanging) {
1205             char buf[BUFSZ];
1206
1207             u.uconduct.polyselfs++; /* you're changing form */
1208 #if 0 /*JP*/
1209             You_cant("resist the temptation to mimic %s.",
1210                      Hallucination ? "an orange" : "a pile of gold");
1211 #else
1212             You("%s\82ð\90^\8e\97\82µ\82½\82¢\97U\98f\82É\82©\82ç\82ê\82½\81D",
1213                      Hallucination ? "\83I\83\8c\83\93\83W" : "\8bà\89Ý\82Ì\8eR");
1214 #endif
1215             /* A pile of gold can't ride. */
1216             if (u.usteed)
1217                 dismount_steed(DISMOUNT_FELL);
1218             nomul(-tmp);
1219 /*JP
1220             multi_reason = "pretending to be a pile of gold";
1221 */
1222             multi_reason = "\8bà\89Ý\82Ì\8eR\82Ì\90^\8e\97\82ð\82µ\82Ä\82¢\82é\8e\9e\82É";
1223             Sprintf(buf,
1224                     Hallucination
1225 /*JP
1226                        ? "You suddenly dread being peeled and mimic %s again!"
1227 */
1228                        ? "\93Ë\91R\8aÛ\97\87\82É\82³\82ê\82é\82Ì\82ª\8b°\82ë\82µ\82­\82È\82Á\82Ä\82Ü\82½%s\82Ì\90^\8e\97\82ð\82µ\82½\81I"
1229 /*JP
1230                        : "You now prefer mimicking %s again.",
1231 */
1232                        : "\82±\82ñ\82Ç\82Í\82Ü\82½%s\82Ì\90^\8e\97\82ª\82µ\82½\82­\82È\82Á\82½\81D",
1233                     an(Upolyd ? youmonst.data->mname : urace.noun));
1234             eatmbuf = dupstr(buf);
1235             nomovemsg = eatmbuf;
1236             afternmv = eatmdone;
1237             /* ??? what if this was set before? */
1238             youmonst.m_ap_type = M_AP_OBJECT;
1239             youmonst.mappearance = Hallucination ? ORANGE : GOLD_PIECE;
1240             newsym(u.ux, u.uy);
1241             curs_on_u();
1242             /* make gold symbol show up now */
1243             display_nhwindow(WIN_MAP, TRUE);
1244         }
1245         break;
1246     case PM_QUANTUM_MECHANIC:
1247 /*JP
1248         Your("velocity suddenly seems very uncertain!");
1249 */
1250         Your("\91¬\93x\82ª\93Ë\91R\81C\95s\8am\92è\82É\82È\82Á\82½\81I");
1251         if (HFast & INTRINSIC) {
1252             HFast &= ~INTRINSIC;
1253 /*JP
1254             You("seem slower.");
1255 */
1256             You("\92x\82­\82È\82Á\82½\82æ\82¤\82¾\81D");
1257         } else {
1258             HFast |= FROMOUTSIDE;
1259 /*JP
1260             You("seem faster.");
1261 */
1262             You("\91¬\82­\82È\82Á\82½\82æ\82¤\82¾\81D");
1263         }
1264         break;
1265     case PM_LIZARD:
1266         if ((HStun & TIMEOUT) > 2)
1267             make_stunned(2L, FALSE);
1268         if ((HConfusion & TIMEOUT) > 2)
1269             make_confused(2L, FALSE);
1270         break;
1271     case PM_CHAMELEON:
1272     case PM_DOPPELGANGER:
1273     case PM_SANDESTIN: /* moot--they don't leave corpses */
1274         if (Unchanging) {
1275 #if 0 /*JP*/
1276             You_feel("momentarily different."); /* same as poly trap */
1277 #else
1278             You_feel("\88ê\8fu\88á\82Á\82½\8a´\82\82ª\82µ\82½\81D"); /* same as poly trap */
1279 #endif
1280         } else {
1281 /*JP
1282             You_feel("a change coming over you.");
1283 */
1284             pline("\95Ï\89»\82ª\96K\82ê\82½\81D");
1285             polyself(0);
1286         }
1287         break;
1288     case PM_DISENCHANTER:
1289         /* picks an intrinsic at random and removes it; there's
1290            no feedback if hero already lacks the chosen ability */
1291         debugpline0("using attrcurse to strip an intrinsic");
1292         attrcurse();
1293         break;
1294     case PM_MIND_FLAYER:
1295     case PM_MASTER_MIND_FLAYER:
1296         if (ABASE(A_INT) < ATTRMAX(A_INT)) {
1297             if (!rn2(2)) {
1298 /*JP
1299                 pline("Yum! That was real brain food!");
1300 */
1301                 pline("\82¤\82Ü\82¢\81I\82±\82ê\82±\82»\96{\93\96\82Ì\81u\93ª\82Ì\97Ç\82­\82È\82é\90H\8e\96\81v\82¾\81I");
1302                 (void) adjattrib(A_INT, 1, FALSE);
1303                 break; /* don't give them telepathy, too */
1304             }
1305         } else {
1306 /*JP
1307             pline("For some reason, that tasted bland.");
1308 */
1309             pline("\82Ç\82¤\82µ\82½\82í\82¯\82©\81C\92W\94\92\82È\96¡\82¾\81D");
1310         }
1311     /*FALLTHRU*/
1312     default: {
1313         struct permonst *ptr = &mons[pm];
1314         boolean conveys_STR = is_giant(ptr);
1315         int i, count;
1316
1317         if (dmgtype(ptr, AD_STUN) || dmgtype(ptr, AD_HALU)
1318             || pm == PM_VIOLET_FUNGUS) {
1319 /*JP
1320             pline("Oh wow!  Great stuff!");
1321 */
1322             pline("\83\8f\81[\83H\81I\82±\82è\82á\82·\82²\82¢\81I");
1323             (void) make_hallucinated((HHallucination & TIMEOUT) + 200L, FALSE,
1324                                      0L);
1325         }
1326
1327         /* Check the monster for all of the intrinsics.  If this
1328          * monster can give more than one, pick one to try to give
1329          * from among all it can give.
1330          *
1331          * Strength from giants is now treated like an intrinsic
1332          * rather than being given unconditionally.
1333          */
1334         count = 0; /* number of possible intrinsics */
1335         tmp = 0;   /* which one we will try to give */
1336         if (conveys_STR) {
1337             count = 1;
1338             tmp = -1; /* use -1 as fake prop index for STR */
1339             debugpline1("\"Intrinsic\" strength, %d", tmp);
1340         }
1341         for (i = 1; i <= LAST_PROP; i++) {
1342             if (!intrinsic_possible(i, ptr))
1343                 continue;
1344             ++count;
1345             /* a 1 in count chance of replacing the old choice
1346                with this one, and a count-1 in count chance
1347                of keeping the old choice (note that 1 in 1 and
1348                0 in 1 are what we want for the first candidate) */
1349             if (!rn2(count)) {
1350                 debugpline2("Intrinsic %d replacing %d", i, tmp);
1351                 tmp = i;
1352             }
1353         }
1354         /* if strength is the only candidate, give it 50% chance */
1355         if (conveys_STR && count == 1 && !rn2(2))
1356             tmp = 0;
1357         /* if something was chosen, give it now (givit() might fail) */
1358         if (tmp == -1)
1359             gainstr((struct obj *) 0, 0, TRUE);
1360         else if (tmp > 0)
1361             givit(tmp, ptr);
1362         break;
1363     } /* default case */
1364     } /* switch */
1365
1366     if (catch_lycanthropy >= LOW_PM) {
1367         set_ulycn(catch_lycanthropy);
1368         retouch_equipment(2);
1369     }
1370     return;
1371 }
1372
1373 void
1374 violated_vegetarian()
1375 {
1376     u.uconduct.unvegetarian++;
1377     if (Role_if(PM_MONK)) {
1378 /*JP
1379         You_feel("guilty.");
1380 */
1381         pline("\8dß\82ð\8a´\82\82½\81D");
1382         adjalign(-1);
1383     }
1384     return;
1385 }
1386
1387 /* common code to check and possibly charge for 1 context.tin.tin,
1388  * will split() context.tin.tin if necessary */
1389 STATIC_PTR struct obj *
1390 costly_tin(alter_type)
1391 int alter_type; /* COST_xxx */
1392 {
1393     struct obj *tin = context.tin.tin;
1394
1395     if (carried(tin) ? tin->unpaid
1396                      : (costly_spot(tin->ox, tin->oy) && !tin->no_charge)) {
1397         if (tin->quan > 1L) {
1398             tin = context.tin.tin = splitobj(tin, 1L);
1399             context.tin.o_id = tin->o_id;
1400         }
1401         costly_alteration(tin, alter_type);
1402     }
1403     return tin;
1404 }
1405
1406 int
1407 tin_variety_txt(s, tinvariety)
1408 char *s;
1409 int *tinvariety;
1410 {
1411     int k, l;
1412
1413     if (s && tinvariety) {
1414         *tinvariety = -1;
1415         for (k = 0; k < TTSZ - 1; ++k) {
1416             l = (int) strlen(tintxts[k].txt);
1417             if (!strncmpi(s, tintxts[k].txt, l) && ((int) strlen(s) > l)
1418                 && s[l] == ' ') {
1419                 *tinvariety = k;
1420                 return (l + 1);
1421             }
1422         }
1423     }
1424     return 0;
1425 }
1426
1427 /*
1428  * This assumes that buf already contains the word "tin",
1429  * as is the case with caller xname().
1430  */
1431 /*JP:\81u\8aÊ\8bl\81v\82Í\8cã\82Å\95t\82¯\82é */
1432 void
1433 tin_details(obj, mnum, buf)
1434 struct obj *obj;
1435 int mnum;
1436 char *buf;
1437 {
1438 #if 0 /*JP*/
1439     char buf2[BUFSZ];
1440 #endif
1441     int r = tin_variety(obj, TRUE);
1442
1443     if (obj && buf) {
1444         if (r == SPINACH_TIN)
1445 /*JP
1446             Strcat(buf, " of spinach");
1447 */
1448             Strcat(buf, "\83z\83E\83\8c\83\93\91\90\82Ì");
1449         else if (mnum == NON_PM)
1450 /*JP
1451             Strcpy(buf, "empty tin");
1452 */
1453             Strcat(buf, "\8bó\82Á\82Û\82Ì");
1454         else {
1455 #if 0 /*JP*//*\93ú\96{\8cê\82Í\8cã\82Å*/
1456             if ((obj->cknown || iflags.override_ID) && obj->spe < 0) {
1457                 if (r == ROTTEN_TIN || r == HOMEMADE_TIN) {
1458                     /* put these before the word tin */
1459                     Sprintf(buf2, "%s %s of ", tintxts[r].txt, buf);
1460                     Strcpy(buf, buf2);
1461                 } else {
1462                     Sprintf(eos(buf), " of %s ", tintxts[r].txt);
1463                 }
1464                 Sprintf(eos(buf), "%s", tintxts[r].txt);
1465             } else {
1466                 Strcpy(eos(buf), " of ");
1467             }
1468 #endif
1469 #if 1 /*JP*//*\81u\82Ì\81v\82Å\8en\82Ü\82é\82È\82ç\8cã\92u\81A\82»\82ê\88È\8aO\82È\82ç\91O\92u*/
1470             if (strstr(tintxts[r].txt, "\82Ì") != tintxts[r].txt) {
1471                 Strcpy(eos(buf), tintxts[r].txt);
1472             }
1473 #endif
1474             if (vegetarian(&mons[mnum]))
1475 /*JP
1476                 Sprintf(eos(buf), "%s", mons[mnum].mname);
1477 */
1478                 Sprintf(eos(buf), "%s", mons[mnum].mname);
1479             else
1480 /*JP
1481                 Sprintf(eos(buf), "%s meat", mons[mnum].mname);
1482 */
1483                 Sprintf(eos(buf), "%s\82Ì\93÷", mons[mnum].mname);
1484 #if 1 /*JP*//*\81u\82Ì\81v\82Å\8en\82Ü\82é\82È\82ç\8cã\92u\81A\82»\82ê\88È\8aO\82È\82ç\91O\92u*/
1485             if (strstr(tintxts[r].txt, "\82Ì") == tintxts[r].txt) {
1486                 Strcpy(eos(buf), tintxts[r].txt);
1487             }
1488             Strcpy(eos(buf), "\82Ì");
1489 #endif
1490         }
1491     }
1492 }
1493
1494 void
1495 set_tin_variety(obj, forcetype)
1496 struct obj *obj;
1497 int forcetype;
1498 {
1499     register int r;
1500
1501     if (forcetype == SPINACH_TIN
1502         || (forcetype == HEALTHY_TIN
1503             && (obj->corpsenm == NON_PM /* empty or already spinach */
1504                 || !vegetarian(&mons[obj->corpsenm])))) { /* replace meat */
1505         obj->corpsenm = NON_PM; /* not based on any monster */
1506         obj->spe = 1;           /* spinach */
1507         return;
1508     } else if (forcetype == HEALTHY_TIN) {
1509         r = tin_variety(obj, FALSE);
1510         if (r < 0 || r >= TTSZ)
1511             r = ROTTEN_TIN; /* shouldn't happen */
1512         while ((r == ROTTEN_TIN && !obj->cursed) || !tintxts[r].fodder)
1513             r = rn2(TTSZ - 1);
1514     } else if (forcetype >= 0 && forcetype < TTSZ - 1) {
1515         r = forcetype;
1516     } else {               /* RANDOM_TIN */
1517         r = rn2(TTSZ - 1); /* take your pick */
1518         if (r == ROTTEN_TIN && nonrotting_corpse(obj->corpsenm))
1519             r = HOMEMADE_TIN; /* lizards don't rot */
1520     }
1521     obj->spe = -(r + 1); /* offset by 1 to allow index 0 */
1522 }
1523
1524 STATIC_OVL int
1525 tin_variety(obj, disp)
1526 struct obj *obj;
1527 boolean disp; /* we're just displaying so leave things alone */
1528 {
1529     register int r;
1530
1531     if (obj->spe == 1) {
1532         r = SPINACH_TIN;
1533     } else if (obj->cursed) {
1534         r = ROTTEN_TIN; /* always rotten if cursed */
1535     } else if (obj->spe < 0) {
1536         r = -(obj->spe);
1537         --r; /* get rid of the offset */
1538     } else
1539         r = rn2(TTSZ - 1);
1540
1541     if (!disp && r == HOMEMADE_TIN && !obj->blessed && !rn2(7))
1542         r = ROTTEN_TIN; /* some homemade tins go bad */
1543
1544     if (r == ROTTEN_TIN && nonrotting_corpse(obj->corpsenm))
1545         r = HOMEMADE_TIN; /* lizards don't rot */
1546     return r;
1547 }
1548
1549 STATIC_OVL void
1550 consume_tin(mesg)
1551 const char *mesg;
1552 {
1553     const char *what;
1554     int which, mnum, r;
1555     struct obj *tin = context.tin.tin;
1556
1557     r = tin_variety(tin, FALSE);
1558     if (tin->otrapped || (tin->cursed && r != HOMEMADE_TIN && !rn2(8))) {
1559 /*JP
1560         b_trapped("tin", 0);
1561 */
1562         b_trapped("\8aÊ", 0);
1563         tin = costly_tin(COST_DSTROY);
1564         goto use_up_tin;
1565     }
1566
1567     pline1(mesg); /* "You succeed in opening the tin." */
1568
1569     if (r != SPINACH_TIN) {
1570         mnum = tin->corpsenm;
1571         if (mnum == NON_PM) {
1572 /*JP
1573             pline("It turns out to be empty.");
1574 */
1575             pline("\8aÊ\82Í\8bó\82Á\82Û\82¾\82Á\82½\81D");
1576             tin->dknown = tin->known = 1;
1577             tin = costly_tin(COST_OPEN);
1578             goto use_up_tin;
1579         }
1580
1581         which = 0; /* 0=>plural, 1=>as-is, 2=>"the" prefix */
1582         if ((mnum == PM_COCKATRICE || mnum == PM_CHICKATRICE)
1583             && (Stone_resistance || Hallucination)) {
1584 /*JP
1585             what = "chicken";
1586 */
1587             what = "\8c{\93÷";
1588             which = 1; /* suppress pluralization */
1589         } else if (Hallucination) {
1590             what = rndmonnam(NULL);
1591         } else {
1592             what = mons[mnum].mname;
1593             if (the_unique_pm(&mons[mnum]))
1594                 which = 2;
1595             else if (type_is_pname(&mons[mnum]))
1596                 which = 1;
1597         }
1598         if (which == 0)
1599             what = makeplural(what);
1600         else if (which == 2)
1601             what = the(what);
1602
1603 /*JP
1604         pline("It smells like %s.", what);
1605 */
1606         pline("%s\82Ì\82æ\82¤\82È\93õ\82¢\82ª\82µ\82½\81D", what);
1607 /*JP
1608         if (yn("Eat it?") == 'n') {
1609 */
1610         if (yn("\90H\82×\82Ü\82·\82©\81H") == 'n') {
1611             if (flags.verbose)
1612 /*JP
1613                 You("discard the open tin.");
1614 */
1615                 You("\8aJ\82¯\82½\8aÊ\82ð\8eÌ\82Ä\82½\81D");
1616             if (!Hallucination)
1617                 tin->dknown = tin->known = 1;
1618             tin = costly_tin(COST_OPEN);
1619             goto use_up_tin;
1620         }
1621
1622         /* in case stop_occupation() was called on previous meal */
1623         context.victual.piece = (struct obj *) 0;
1624         context.victual.o_id = 0;
1625         context.victual.fullwarn = context.victual.eating =
1626             context.victual.doreset = FALSE;
1627
1628 #if 0 /*JP*/
1629         You("consume %s %s.", tintxts[r].txt, mons[mnum].mname);
1630 #else /*JP: \81u\82Ì\81v\82Å\8en\82Ü\82é\82È\82ç\8cã\92u\81A\82»\82ê\88È\8aO\82È\82ç\91O\92u */
1631         if (strstr(tintxts[r].txt, "\82Ì") == tintxts[r].txt) {
1632             You("%s%s\82Ì\8aÊ\8bl\82ð\82½\82¢\82ç\82°\82½\81D", mons[mnum].mname, tintxts[r].txt);
1633         } else {
1634             You("%s%s\82Ì\8aÊ\8bl\82ð\82½\82¢\82ç\82°\82½\81D", tintxts[r].txt, mons[mnum].mname);
1635         }
1636 #endif
1637
1638         eating_conducts(&mons[mnum]);
1639
1640         tin->dknown = tin->known = 1;
1641         cprefx(mnum);
1642         cpostfx(mnum);
1643
1644         /* charge for one at pre-eating cost */
1645         tin = costly_tin(COST_OPEN);
1646
1647         if (tintxts[r].nut < 0) /* rotten */
1648             make_vomiting((long) rn1(15, 10), FALSE);
1649         else
1650             lesshungry(tintxts[r].nut);
1651
1652         if (tintxts[r].greasy) {
1653             /* Assume !Glib, because you can't open tins when Glib. */
1654             incr_itimeout(&Glib, rnd(15));
1655 #if 0 /*JP*/
1656             pline("Eating %s food made your %s very slippery.",
1657                   tintxts[r].txt, makeplural(body_part(FINGER)));
1658 #else
1659             pline("\96û\82Á\82Û\82¢\95¨\82ð\90H\82×\82½\82Ì\82Å\82 \82È\82½\82Ì%s\82Í\8a\8a\82è\82â\82·\82­\82È\82Á\82½\81D",
1660                   body_part(FINGER));
1661 #endif
1662         }
1663
1664     } else { /* spinach... */
1665         if (tin->cursed) {
1666 #if 0 /*JP*/
1667             pline("It contains some decaying%s%s substance.",
1668                   Blind ? "" : " ", Blind ? "" : hcolor(NH_GREEN));
1669 #else
1670             pline("%s\95\85\82Á\82½\95¨\91Ì\82ª\93ü\82Á\82Ä\82¢\82é\81D",
1671                   Blind ? "" : hcolor(NH_GREEN));
1672 #endif
1673         } else {
1674 /*JP
1675             pline("It contains spinach.");
1676 */
1677             pline("\83z\83E\83\8c\83\93\91\90\82ª\93ü\82Á\82Ä\82¢\82é\81D");
1678             tin->dknown = tin->known = 1;
1679         }
1680
1681 /*JP
1682         if (yn("Eat it?") == 'n') {
1683 */
1684         if (yn("\90H\82×\82Ü\82·\82©\81H") == 'n') {
1685             if (flags.verbose)
1686 /*JP
1687                 You("discard the open tin.");
1688 */
1689                 You("\8aJ\82¯\82½\8aÊ\82ð\8eÌ\82Ä\82½\81D");
1690             tin = costly_tin(COST_OPEN);
1691             goto use_up_tin;
1692         }
1693
1694         /*
1695          * Same order as with non-spinach above:
1696          * conduct update, side-effects, shop handling, and nutrition.
1697          */
1698         u.uconduct.food++; /* don't need vegetarian checks for spinach */
1699         if (!tin->cursed)
1700 #if 0 /*JP:T*/
1701             pline("This makes you feel like %s!",
1702                   Hallucination ? "Swee'pea" : "Popeye");
1703 #else
1704             pline("%s\82Ì\82æ\82¤\82È\8bC\95ª\82É\82È\82Á\82½\81I",
1705                   Hallucination ? "\83X\83C\81[\83s\81[" : "\83|\83p\83C");
1706 #endif
1707         gainstr(tin, 0, FALSE);
1708
1709         tin = costly_tin(COST_OPEN);
1710
1711         lesshungry(tin->blessed
1712                       ? 600                   /* blessed */
1713                       : !tin->cursed
1714                          ? (400 + rnd(200))   /* uncursed */
1715                          : (200 + rnd(400))); /* cursed */
1716     }
1717
1718 use_up_tin:
1719     if (carried(tin))
1720         useup(tin);
1721     else
1722         useupf(tin, 1L);
1723     context.tin.tin = (struct obj *) 0;
1724     context.tin.o_id = 0;
1725 }
1726
1727 /* called during each move whilst opening a tin */
1728 STATIC_PTR int
1729 opentin(VOID_ARGS)
1730 {
1731     /* perhaps it was stolen (although that should cause interruption) */
1732     if (!carried(context.tin.tin)
1733         && (!obj_here(context.tin.tin, u.ux, u.uy) || !can_reach_floor(TRUE)))
1734         return 0; /* %% probably we should use tinoid */
1735     if (context.tin.usedtime++ >= 50) {
1736 /*JP
1737         You("give up your attempt to open the tin.");
1738 */
1739         You("\8aÊ\82ð\8aJ\82¯\82é\82Ì\82ð\82 \82«\82ç\82ß\82½\81D");
1740         return 0;
1741     }
1742     if (context.tin.usedtime < context.tin.reqtime)
1743         return 1; /* still busy */
1744
1745 /*JP
1746     consume_tin("You succeed in opening the tin.");
1747 */
1748     consume_tin("\8aÊ\82ð\8aJ\82¯\82é\82Ì\82É\90¬\8c÷\82µ\82½\81D");
1749     return 0;
1750 }
1751
1752 /* called when starting to open a tin */
1753 STATIC_OVL void
1754 start_tin(otmp)
1755 struct obj *otmp;
1756 {
1757     const char *mesg = 0;
1758     register int tmp;
1759
1760     if (metallivorous(youmonst.data)) {
1761 /*JP
1762         mesg = "You bite right into the metal tin...";
1763 */
1764         mesg = "\8bà\91®\82Ì\8aÊ\82ð\8a\9a\82Ý\82Í\82\82ß\82½\81D\81D\81D";
1765         tmp = 0;
1766     } else if (cantwield(youmonst.data)) { /* nohands || verysmall */
1767 /*JP
1768         You("cannot handle the tin properly to open it.");
1769 */
1770         You("\8aÊ\82ð\82¤\82Ü\82­\8aJ\82¯\82ç\82ê\82È\82¢\81D");
1771         return;
1772     } else if (otmp->blessed) {
1773         /* 50/50 chance for immediate access vs 1 turn delay (unless
1774            wielding blessed tin opener which always yields immediate
1775            access); 1 turn delay case is non-deterministic:  getting
1776            interrupted and retrying might yield another 1 turn delay
1777            or might open immediately on 2nd (or 3rd, 4th, ...) try */
1778         tmp = (uwep && uwep->blessed && uwep->otyp == TIN_OPENER) ? 0 : rn2(2);
1779         if (!tmp)
1780 /*JP
1781             mesg = "The tin opens like magic!";
1782 */
1783             mesg = "\8aÊ\82Í\96\82\96@\82Ì\82æ\82¤\82É\8aJ\82¢\82½\81I";
1784         else
1785 /*JP
1786             pline_The("tin seems easy to open.");
1787 */
1788             pline_The("\8aÊ\82Í\8aÈ\92P\82É\8aJ\82¯\82ç\82ê\82»\82¤\82¾\81D");
1789     } else if (uwep) {
1790         switch (uwep->otyp) {
1791         case TIN_OPENER:
1792 #if 0 /*JP*/
1793             mesg = "You easily open the tin."; /* iff tmp==0 */
1794 #else
1795             mesg = "\82 \82È\82½\82Í\8aÈ\92P\82É\8aÊ\82ð\8aJ\82¯\82½\81D"; /* iff tmp==0 */
1796 #endif
1797             tmp = rn2(uwep->cursed ? 3 : !uwep->blessed ? 2 : 1);
1798             break;
1799         case DAGGER:
1800         case SILVER_DAGGER:
1801         case ELVEN_DAGGER:
1802         case ORCISH_DAGGER:
1803         case ATHAME:
1804         case KNIFE:
1805         case STILETTO:
1806         case CRYSKNIFE:
1807             tmp = 3;
1808             break;
1809         case PICK_AXE:
1810         case AXE:
1811             tmp = 6;
1812             break;
1813         default:
1814             goto no_opener;
1815         }
1816 /*JP
1817         pline("Using %s you try to open the tin.", yobjnam(uwep, (char *) 0));
1818 */
1819         You("%s\82ð\8eg\82Á\82Ä\8aÊ\82ð\8aJ\82¯\82æ\82¤\82Æ\82µ\82½\81D", xname(uwep));
1820     } else {
1821     no_opener:
1822 /*JP
1823         pline("It is not so easy to open this tin.");
1824 */
1825         pline("\82±\82Ì\8aÊ\82ð\8aJ\82¯\82é\82Ì\82Í\97e\88Õ\82È\82±\82Æ\82Å\82Í\82È\82¢\81D");
1826         if (Glib) {
1827 /*JP
1828             pline_The("tin slips from your %s.",
1829 */
1830             pline("\8aÊ\82Í\82 \82È\82½\82Ì%s\82©\82ç\8a\8a\82è\97\8e\82¿\82½\81D",
1831                       makeplural(body_part(FINGER)));
1832             if (otmp->quan > 1L) {
1833                 otmp = splitobj(otmp, 1L);
1834             }
1835             if (carried(otmp))
1836                 dropx(otmp);
1837             else
1838                 stackobj(otmp);
1839             return;
1840         }
1841         tmp = rn1(1 + 500 / ((int) (ACURR(A_DEX) + ACURRSTR)), 10);
1842     }
1843
1844     context.tin.tin = otmp;
1845     context.tin.o_id = otmp->o_id;
1846     if (!tmp) {
1847         consume_tin(mesg); /* begin immediately */
1848     } else {
1849         context.tin.reqtime = tmp;
1850         context.tin.usedtime = 0;
1851 /*JP
1852         set_occupation(opentin, "opening the tin", 0);
1853 */
1854         set_occupation(opentin, "\8aÊ\82ð\8aJ\82¯\82é", 0);
1855     }
1856     return;
1857 }
1858
1859 /* called when waking up after fainting */
1860 int
1861 Hear_again(VOID_ARGS)
1862 {
1863     /* Chance of deafness going away while fainted/sleeping/etc. */
1864     if (!rn2(2)) {
1865         make_deaf(0L, FALSE);
1866         context.botl = TRUE;
1867     }
1868     return 0;
1869 }
1870
1871 /* called on the "first bite" of rotten food */
1872 STATIC_OVL int
1873 rottenfood(obj)
1874 struct obj *obj;
1875 {
1876 /*JP
1877     pline("Blecch!  Rotten %s!", foodword(obj));
1878 */
1879     pline("\83Q\83F\81I\95\85\82Á\82½%s\82¾\81I", foodword(obj));
1880     if (!rn2(4)) {
1881         if (Hallucination)
1882 /*JP
1883             You_feel("rather trippy.");
1884 */
1885             You("\82Ö\82ë\82Ö\82ë\82µ\82½\81D");
1886         else
1887 /*JP
1888             You_feel("rather %s.", body_part(LIGHT_HEADED));
1889 */
1890             You("%s\81D", body_part(LIGHT_HEADED));
1891         make_confused(HConfusion + d(2, 4), FALSE);
1892     } else if (!rn2(4) && !Blind) {
1893 /*JP
1894         pline("Everything suddenly goes dark.");
1895 */
1896         pline("\93Ë\91R\91S\82Ä\82ª\88Ã\82­\82È\82Á\82½\81D");
1897         /* hero is not Blind, but Blinded timer might be nonzero if
1898            blindness is being overridden by the Eyes of the Overworld */
1899         make_blinded((Blinded & TIMEOUT) + (long) d(2, 10), FALSE);
1900         if (!Blind)
1901             Your1(vision_clears);
1902     } else if (!rn2(3)) {
1903         const char *what, *where;
1904         int duration = rnd(10);
1905
1906         if (!Blind)
1907 /*JP
1908             what = "goes", where = "dark";
1909 */
1910             what = "\82È\82Á\82½", where = "\88Ã\88Å\82É";
1911         else if (Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz))
1912 /*JP
1913             what = "you lose control of", where = "yourself";
1914 */
1915             what = "\90§\8cä\82Å\82«\82È\82­\82È\82Á\82½", where = "\8e©\95ª\82ð";
1916         else
1917 /*JP
1918             what = "you slap against the",
1919 */
1920             what = "\82É\82Ô\82Â\82©\82Á\82½",
1921 /*JP
1922             where = (u.usteed) ? "saddle" : surface(u.ux, u.uy);
1923 */
1924             where = (u.usteed) ? "\88Æ" : surface(u.ux, u.uy);
1925 /*JP
1926         pline_The("world spins and %s %s.", what, where);
1927 */
1928         pline("\90¢\8aE\82ª\89ñ\93]\82µ\81C%s%s\81D", where, what);
1929         incr_itimeout(&HDeaf, duration);
1930         context.botl = TRUE;
1931         nomul(-duration);
1932 /*JP
1933         multi_reason = "unconscious from rotten food";
1934 */
1935         multi_reason = "\95\85\82Á\82½\90H\82×\95¨\82Å\88Ó\8e¯\82ð\8e¸\82Á\82Ä\82¢\82é\8aÔ\82É";
1936 /*JP
1937         nomovemsg = "You are conscious again.";
1938 */
1939         nomovemsg = "\82 \82È\82½\82Í\82Ü\82½\90³\8bC\82Ã\82¢\82½\81D";
1940         afternmv = Hear_again;
1941         return 1;
1942     }
1943     return 0;
1944 }
1945
1946 /* called when a corpse is selected as food */
1947 STATIC_OVL int
1948 eatcorpse(otmp)
1949 struct obj *otmp;
1950 {
1951     int retcode = 0, tp = 0, mnum = otmp->corpsenm;
1952     long rotted = 0L;
1953     boolean stoneable = (flesh_petrifies(&mons[mnum]) && !Stone_resistance
1954                          && !poly_when_stoned(youmonst.data)),
1955             slimeable = (mnum == PM_GREEN_SLIME && !Slimed && !Unchanging
1956                          && !slimeproof(youmonst.data)),
1957             glob = otmp->globby ? TRUE : FALSE;
1958
1959     /* KMH, conduct */
1960     if (!vegan(&mons[mnum]))
1961         u.uconduct.unvegan++;
1962     if (!vegetarian(&mons[mnum]))
1963         violated_vegetarian();
1964
1965     if (!nonrotting_corpse(mnum)) {
1966         long age = peek_at_iced_corpse_age(otmp);
1967
1968         rotted = (monstermoves - age) / (10L + rn2(20));
1969         if (otmp->cursed)
1970             rotted += 2L;
1971         else if (otmp->blessed)
1972             rotted -= 2L;
1973     }
1974
1975     if (mnum != PM_ACID_BLOB && !stoneable && !slimeable && rotted > 5L) {
1976         boolean cannibal = maybe_cannibal(mnum, FALSE);
1977
1978 #if 0 /*JP*/
1979         pline("Ulch - that %s was tainted%s!",
1980               (mons[mnum].mlet == S_FUNGUS) ? "fungoid vegetation"
1981                   : glob ? "glob"
1982                       : vegetarian(&mons[mnum]) ? "protoplasm"
1983                           : "meat",
1984               cannibal ? ", you cannibal" : "");
1985 #else /* \93ú\96{\8cê\82Å\82Í\92P\8f\83\82É */
1986         pline("\83I\83F\81I\82±\82ê\82Í\95\85\82Á\82Ä\82¢\82é\81I%s", 
1987               cannibal ? "\82µ\82©\82à\8b¤\90H\82¢\82¾\81I" : "");
1988 #endif
1989         if (Sick_resistance) {
1990 /*JP
1991             pline("It doesn't seem at all sickening, though...");
1992 */
1993             pline("\82µ\82©\82µ\81C\82¢\82½\82Á\82Ä\8c³\8bC\82¾\81D\81D\81D");
1994         } else {
1995             long sick_time;
1996
1997             sick_time = (long) rn1(10, 10);
1998             /* make sure new ill doesn't result in improvement */
1999             if (Sick && (sick_time > Sick))
2000                 sick_time = (Sick > 1L) ? Sick - 1L : 1L;
2001 #if 0 /*JP:T*/
2002             make_sick(sick_time, corpse_xname(otmp, "rotted", CXN_NORMAL),
2003                       TRUE, SICK_VOMITABLE);
2004 #else
2005             make_sick(sick_time, corpse_xname(otmp, "\95\85\82Á\82½", CXN_NORMAL),
2006                       TRUE, SICK_VOMITABLE);
2007 #endif
2008
2009 /*JP
2010             pline("(It must have died too long ago to be safe to eat.)");
2011 */
2012             pline("(\82±\82Ì\93÷\82Í\88À\91S\82É\90H\82×\82ç\82ê\82é\8e\9e\8aÔ\82ð\89ß\82¬\82Ä\82µ\82Ü\82Á\82Ä\82¢\82½\82æ\82¤\82¾\81D)");
2013         }
2014         if (carried(otmp))
2015             useup(otmp);
2016         else
2017             useupf(otmp, 1L);
2018         return 2;
2019     } else if (acidic(&mons[mnum]) && !Acid_resistance) {
2020         tp++;
2021 #if 0 /*JP:T*/
2022         You("have a very bad case of stomach acid.");   /* not body_part() */
2023 #else
2024         pline("\88Ý\8e_\82Ì\92²\8eq\82ª\82Æ\82Ä\82à\88«\82¢\81D");
2025 #endif
2026 #if 0 /*JP:T*/
2027         losehp(rnd(15), !glob ? "acidic corpse" : "acidic glob",
2028                KILLED_BY_AN); /* acid damage */
2029 #else /* \93ú\96{\8cê\82Å\82Í\8bæ\95Ê\82µ\82È\82¢ */
2030         losehp(rnd(15), "\8e_\82Ì\8e\80\91Ì\82Å", KILLED_BY_AN);
2031 #endif
2032     } else if (poisonous(&mons[mnum]) && rn2(5)) {
2033         tp++;
2034 /*JP
2035         pline("Ecch - that must have been poisonous!");
2036 */
2037         pline("\83E\83Q\83F\81[\81C\97L\93Å\82¾\82Á\82½\82É\82¿\82ª\82¢\82È\82¢\81I");  
2038         if (!Poison_resistance) {
2039             losestr(rnd(4));
2040 #if 0 /*JP*/
2041             losehp(rnd(15), !glob ? "poisonous corpse" : "poisonous glob",
2042                    KILLED_BY_AN);
2043 #else
2044             losehp(rnd(15), "\93Å\82Ì\8e\80\91Ì\82Å", KILLED_BY_AN);
2045 #endif
2046         } else
2047 /*JP
2048             You("seem unaffected by the poison.");
2049 */
2050             You("\93Å\82Ì\89e\8b¿\82ð\8eó\82¯\82È\82¢\82æ\82¤\82¾\81D");
2051     /* now any corpse left too long will make you mildly ill */
2052     } else if ((rotted > 5L || (rotted > 3L && rn2(5))) && !Sick_resistance) {
2053         tp++;
2054 /*JP
2055         You_feel("%ssick.", (Sick) ? "very " : "");
2056 */
2057         You("%s\8bC\95ª\82ª\88«\82¢\81D", (Sick) ? "\82Æ\82Ä\82à" : "");
2058 /*JP
2059         losehp(rnd(8), !glob ? "cadaver" : "rotted glob", KILLED_BY_AN);
2060 */
2061         losehp(rnd(8), "\95\85\97\90\8e\80\91Ì\82Å", KILLED_BY_AN);
2062     }
2063
2064     /* delay is weight dependent */
2065     context.victual.reqtime = 3 + ((!glob ? mons[mnum].cwt : otmp->owt) >> 6);
2066
2067     if (!tp && !nonrotting_corpse(mnum) && (otmp->orotten || !rn2(7))) {
2068         if (rottenfood(otmp)) {
2069             otmp->orotten = TRUE;
2070             (void) touchfood(otmp);
2071             retcode = 1;
2072         }
2073
2074         if (!mons[otmp->corpsenm].cnutrit) {
2075             /* no nutrition: rots away, no message if you passed out */
2076             if (!retcode)
2077 /*JP
2078                 pline_The("corpse rots away completely.");
2079 */
2080                 pline("\8e\80\91Ì\82Í\8a®\91S\82É\95\85\82Á\82Ä\82µ\82Ü\82Á\82½\81D");
2081             if (carried(otmp))
2082                 useup(otmp);
2083             else
2084                 useupf(otmp, 1L);
2085             retcode = 2;
2086         }
2087
2088         if (!retcode)
2089             consume_oeaten(otmp, 2); /* oeaten >>= 2 */
2090     } else if ((mnum == PM_COCKATRICE || mnum == PM_CHICKATRICE)
2091                && (Stone_resistance || Hallucination)) {
2092 /*JP
2093         pline("This tastes just like chicken!");
2094 */
2095         pline("\82±\82ê\82Í\8c{\93÷\82Ì\96¡\82¾\81I");
2096     } else if (mnum == PM_FLOATING_EYE && u.umonnum == PM_RAVEN) {
2097 /*JP
2098         You("peck the eyeball with delight.");
2099 */
2100         You("\96Ú\8bÊ\82ð\82Â\82ñ\82Â\82ñ\82Â\82Â\82¢\82½\81D");
2101     } else {
2102         /* yummy is always False for omnivores, palatable always True */
2103         boolean yummy = (vegan(&mons[mnum])
2104                             ? (!carnivorous(youmonst.data)
2105                                && herbivorous(youmonst.data))
2106                             : (carnivorous(youmonst.data)
2107                                && !herbivorous(youmonst.data))),
2108             palatable = ((vegetarian(&mons[mnum])
2109                           ? herbivorous(youmonst.data)
2110                           : carnivorous(youmonst.data))
2111                          && rn2(10)
2112                          && ((rotted < 1) ? TRUE : !rn2(rotted+1)));
2113         const char *pmxnam = food_xname(otmp, FALSE);
2114
2115 #if 0 /*JP*/
2116         if (!strncmpi(pmxnam, "the ", 4))
2117             pmxnam += 4;
2118         pline("%s%s %s %s%c",
2119               type_is_pname(&mons[mnum])
2120                  ? "" : the_unique_pm(&mons[mnum]) ? "The " : "This ",
2121               pmxnam,
2122               Hallucination ? "is" : "tastes",
2123                   /* tiger reference is to TV ads for "Frosted Flakes",
2124                      breakfast cereal targeted at kids by "Tony the tiger" */
2125               Hallucination
2126                  ? (yummy ? ((u.umonnum == PM_TIGER) ? "gr-r-reat" : "gnarly")
2127                           : palatable ? "copacetic" : "grody")
2128                  : (yummy ? "delicious" : palatable ? "okay" : "terrible"),
2129               (yummy || !palatable) ? '!' : '.');
2130 #else
2131         pline("\82±\82Ì%s\82Í%s%s",
2132               pmxnam,
2133               Hallucination
2134                  ? (yummy ? ((u.umonnum == PM_TIGER) ? "\83O\83D\83\8c\83C\83g\83D"
2135                                                      : "\83C\83P\82Ä\82é")
2136                           : palatable ? "\82Ü\82 \82 \82è\82¾" : "\83C\83P\82Ä\82È\82¢")
2137                  : (yummy ? "\82Æ\82Ä\82à\8e|\82¢" : palatable ? "\82Ü\82 \82Ü\82 \82¾"
2138                                                      : "\82Ð\82Ç\82¢\96¡\82¾"),
2139               (yummy || !palatable) ? "\81I" : "\81D");
2140 #endif
2141     }
2142
2143     return retcode;
2144 }
2145
2146 /* called as you start to eat */
2147 STATIC_OVL void
2148 start_eating(otmp)
2149 struct obj *otmp;
2150 {
2151     const char *old_nomovemsg, *save_nomovemsg;
2152
2153     debugpline2("start_eating: %s (victual = %s)",
2154                 /* note: fmt_ptr() returns a static buffer but supports
2155                    several such so we don't need to copy the first result
2156                    before calling it a second time */
2157                 fmt_ptr((genericptr_t) otmp),
2158                 fmt_ptr((genericptr_t) context.victual.piece));
2159     debugpline1("reqtime = %d", context.victual.reqtime);
2160     debugpline1("(original reqtime = %d)", objects[otmp->otyp].oc_delay);
2161     debugpline1("nmod = %d", context.victual.nmod);
2162     debugpline1("oeaten = %d", otmp->oeaten);
2163     context.victual.fullwarn = context.victual.doreset = FALSE;
2164     context.victual.eating = TRUE;
2165
2166     if (otmp->otyp == CORPSE || otmp->globby) {
2167         cprefx(context.victual.piece->corpsenm);
2168         if (!context.victual.piece || !context.victual.eating) {
2169             /* rider revived, or died and lifesaved */
2170             return;
2171         }
2172     }
2173
2174     old_nomovemsg = nomovemsg;
2175     if (bite()) {
2176         /* survived choking, finish off food that's nearly done;
2177            need this to handle cockatrice eggs, fortune cookies, etc */
2178         if (++context.victual.usedtime >= context.victual.reqtime) {
2179             /* don't want done_eating() to issue nomovemsg if it
2180                is due to vomit() called by bite() */
2181             save_nomovemsg = nomovemsg;
2182             if (!old_nomovemsg)
2183                 nomovemsg = 0;
2184             done_eating(FALSE);
2185             if (!old_nomovemsg)
2186                 nomovemsg = save_nomovemsg;
2187         }
2188         return;
2189     }
2190
2191     if (++context.victual.usedtime >= context.victual.reqtime) {
2192         /* print "finish eating" message if they just resumed -dlc */
2193         done_eating(context.victual.reqtime > 1 ? TRUE : FALSE);
2194         return;
2195     }
2196
2197 /*JP
2198     Sprintf(msgbuf, "eating %s", food_xname(otmp, TRUE));
2199 */
2200     Sprintf(msgbuf, "%s\82ð\90H\82×\82é", food_xname(otmp, TRUE));
2201     set_occupation(eatfood, msgbuf, 0);
2202 }
2203
2204 /*
2205  * called on "first bite" of (non-corpse) food.
2206  * used for non-rotten non-tin non-corpse food
2207  */
2208 STATIC_OVL void
2209 fprefx(otmp)
2210 struct obj *otmp;
2211 {
2212     switch (otmp->otyp) {
2213     case FOOD_RATION:
2214         if (u.uhunger <= 200)
2215 /*JP
2216             pline(Hallucination ? "Oh wow, like, superior, man!"
2217 */
2218             pline(Hallucination ? "\82Ü\82Á\82½\82è\82Æ\82µ\82Ä\81C\82»\82ê\82Å\82¢\82Ä\82µ\82Â\82±\82­\82È\82¢\81I\82±\82ê\82¼\8b\86\8bÉ\82Ì\83\81\83j\83\85\81[\82¾\81I"
2219 /*JP
2220                                 : "That food really hit the spot!");
2221 */
2222                                 : "\82±\82Ì\90H\82×\95¨\82Í\96{\93\96\82É\90\\82µ\95ª\82È\82¢\81I");
2223         else if (u.uhunger <= 700)
2224 /*JP
2225             pline("That satiated your %s!", body_part(STOMACH));
2226 */
2227             pline("\96\9e\95 \82É\82È\82Á\82½\81I");
2228         break;
2229     case TRIPE_RATION:
2230         if (carnivorous(youmonst.data) && !humanoid(youmonst.data))
2231 /*JP
2232             pline("That tripe ration was surprisingly good!");
2233 */
2234             pline("\82±\82Ì\83\82\83c\93÷\82Í\82¨\82Ç\82ë\82­\82Ù\82Ç\8e|\82¢\81I");
2235         else if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC)))
2236 /*JP
2237             pline(Hallucination ? "Tastes great! Less filling!"
2238 */
2239             pline(Hallucination ? "\82¤\82Ü\82¢\81I\82à\82Á\82Æ\82Ù\82µ\82­\82È\82é\82Ë\81I"
2240 /*JP
2241                                 : "Mmm, tripe... not bad!");
2242 */
2243                                 : "\82ñ\81[\81C\83\82\83c\82©\81D\81D\81D\88«\82­\82È\82¢\81I");
2244         else {
2245 /*JP
2246             pline("Yak - dog food!");
2247 */
2248             pline("\82¤\82°\81C\83h\83b\83O\83t\81[\83h\82¾\81I");
2249             more_experienced(1, 0);
2250             newexplevel();
2251             /* not cannibalism, but we use similar criteria
2252                for deciding whether to be sickened by this meal */
2253             if (rn2(2) && !CANNIBAL_ALLOWED())
2254                 make_vomiting((long) rn1(context.victual.reqtime, 14), FALSE);
2255         }
2256         break;
2257     case LEMBAS_WAFER:
2258         if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC))) {
2259 /*JP
2260             pline("%s", "!#?&* elf kibble!");
2261 */
2262             pline("%s", "\81I\81\94\81H\81\95\81\96 \83G\83\8b\83N\82Ì\90H\82¢\95¨\81I");
2263             break;
2264         } else if (maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF))) {
2265 /*JP
2266             pline("A little goes a long way.");
2267 */
2268             pline("\8f­\82µ\82Å\8f\\95ª\82¾\81D");
2269             break;
2270         }
2271         goto give_feedback;
2272     case MEATBALL:
2273     case MEAT_STICK:
2274     case HUGE_CHUNK_OF_MEAT:
2275     case MEAT_RING:
2276         goto give_feedback;
2277     case CLOVE_OF_GARLIC:
2278         if (is_undead(youmonst.data)) {
2279             make_vomiting((long) rn1(context.victual.reqtime, 5), FALSE);
2280             break;
2281         }
2282         /*FALLTHRU*/
2283     default:
2284         if (otmp->otyp == SLIME_MOLD && !otmp->cursed
2285             && otmp->spe == context.current_fruit) {
2286 #if 0 /*JP*/
2287             pline("My, that was a %s %s!",
2288                   Hallucination ? "primo" : "yummy",
2289                   singular(otmp, xname));
2290 #else
2291             pline("\82¨\82â\81C\82È\82ñ\82Ä%s%s\82¾\81I",
2292                   Hallucination ? "\8fã\95i\82È" : "\82¨\82¢\82µ\82¢",
2293                   singular(otmp, xname));
2294 #endif
2295         } else if (otmp->otyp == APPLE && otmp->cursed && !Sleep_resistance) {
2296             ; /* skip core joke; feedback deferred til fpostfx() */
2297
2298 #if defined(MAC) || defined(MACOSX)
2299         /* KMH -- Why should Unix have all the fun?
2300            We check MACOSX before UNIX to get the Apple-specific apple
2301            message; the '#if UNIX' code will still kick in for pear. */
2302         } else if (otmp->otyp == APPLE) {
2303 /*JP
2304             pline("Delicious!  Must be a Macintosh!");
2305 */
2306             pline("\82·\82Î\82ç\82µ\82¢\81I\83}\83b\83L\83\93\83g\83b\83V\83\85\82É\88á\82¢\82È\82¢\81I");
2307 #endif
2308
2309 #ifdef UNIX
2310         } else if (otmp->otyp == APPLE || otmp->otyp == PEAR) {
2311             if (!Hallucination) {
2312                 pline("Core dumped.");
2313             } else {
2314                 /* This is based on an old Usenet joke, a fake a.out manual
2315                  * page
2316                  */
2317                 int x = rnd(100);
2318
2319                 pline("%s -- core dumped.",
2320                       (x <= 75)
2321                          ? "Segmentation fault"
2322                          : (x <= 99)
2323                             ? "Bus error"
2324                             : "Yo' mama");
2325             }
2326 #endif
2327         } else if (otmp->otyp == EGG && stale_egg(otmp)) {
2328 #if 0 /*JP*/
2329             pline("Ugh.  Rotten egg."); /* perhaps others like it */
2330 #else
2331             pline("\83E\83Q\83F\81[\95\85\82Á\82½\97\91\82¾\81D");
2332 #endif
2333             /* increasing existing nausea means that it will take longer
2334                before eventual vomit, but also means that constitution
2335                will be abused more times before illness completes */
2336             make_vomiting((Vomiting & TIMEOUT) + (long) d(10, 4), TRUE);
2337         } else {
2338         give_feedback:
2339 #if 0 /*JP*/
2340             pline("This %s is %s", singular(otmp, xname),
2341                   otmp->cursed
2342                      ? (Hallucination ? "grody!" : "terrible!")
2343                      : (otmp->otyp == CRAM_RATION
2344                         || otmp->otyp == K_RATION
2345                         || otmp->otyp == C_RATION)
2346                         ? "bland."
2347                         : Hallucination ? "gnarly!" : "delicious!");
2348 #else
2349             pline("\82±\82Ì%s\82Í%s", singular(otmp, xname),
2350                   otmp->cursed
2351                     ? (Hallucination ? "\83C\83P\82Ä\82È\82¢\81I" : "\82Ð\82Ç\82¢\96¡\82¾\81I")
2352                     : (otmp->otyp == CRAM_RATION
2353                         || otmp->otyp == K_RATION
2354                         || otmp->otyp == C_RATION)
2355                         ? "\96¡\8bC\82È\82¢\81D"
2356                         : Hallucination ? "\83C\83P\82Ä\82é\81I" : "\82¤\82Ü\82¢\81I");
2357 #endif
2358         }
2359         break; /* default */
2360     } /* switch */
2361 }
2362
2363 /* increment a combat intrinsic with limits on its growth */
2364 STATIC_OVL int
2365 bounded_increase(old, inc, typ)
2366 int old, inc, typ;
2367 {
2368     int absold, absinc, sgnold, sgninc;
2369
2370     /* don't include any amount coming from worn rings */
2371     if (uright && uright->otyp == typ)
2372         old -= uright->spe;
2373     if (uleft && uleft->otyp == typ)
2374         old -= uleft->spe;
2375     absold = abs(old), absinc = abs(inc);
2376     sgnold = sgn(old), sgninc = sgn(inc);
2377
2378     if (absinc == 0 || sgnold != sgninc || absold + absinc < 10) {
2379         ; /* use inc as-is */
2380     } else if (absold + absinc < 20) {
2381         absinc = rnd(absinc); /* 1..n */
2382         if (absold + absinc < 10)
2383             absinc = 10 - absold;
2384         inc = sgninc * absinc;
2385     } else if (absold + absinc < 40) {
2386         absinc = rn2(absinc) ? 1 : 0;
2387         if (absold + absinc < 20)
2388             absinc = rnd(20 - absold);
2389         inc = sgninc * absinc;
2390     } else {
2391         inc = 0; /* no further increase allowed via this method */
2392     }
2393     return old + inc;
2394 }
2395
2396 STATIC_OVL void
2397 accessory_has_effect(otmp)
2398 struct obj *otmp;
2399 {
2400 #if 0 /*JP*/
2401     pline("Magic spreads through your body as you digest the %s.",
2402           otmp->oclass == RING_CLASS ? "ring" : "amulet");
2403 #else
2404     pline("\82 \82È\82½\82ª%s\82ð\8fÁ\89»\82·\82é\82Æ\81C\82»\82Ì\96\82\97Í\82ª\91Ì\82É\82µ\82Ý\82±\82ñ\82¾\81D",
2405           otmp->oclass == RING_CLASS ? "\8ew\97Ö" : "\96\82\8f\9c\82¯");
2406 #endif
2407 }
2408
2409 STATIC_OVL void
2410 eataccessory(otmp)
2411 struct obj *otmp;
2412 {
2413     int typ = otmp->otyp;
2414     long oldprop;
2415
2416     /* Note: rings are not so common that this is unbalancing. */
2417     /* (How often do you even _find_ 3 rings of polymorph in a game?) */
2418     oldprop = u.uprops[objects[typ].oc_oprop].intrinsic;
2419     if (otmp == uleft || otmp == uright) {
2420         Ring_gone(otmp);
2421         if (u.uhp <= 0)
2422             return; /* died from sink fall */
2423     }
2424     otmp->known = otmp->dknown = 1; /* by taste */
2425     if (!rn2(otmp->oclass == RING_CLASS ? 3 : 5)) {
2426         switch (otmp->otyp) {
2427         default:
2428             if (!objects[typ].oc_oprop)
2429                 break; /* should never happen */
2430
2431             if (!(u.uprops[objects[typ].oc_oprop].intrinsic & FROMOUTSIDE))
2432                 accessory_has_effect(otmp);
2433
2434             u.uprops[objects[typ].oc_oprop].intrinsic |= FROMOUTSIDE;
2435
2436             switch (typ) {
2437             case RIN_SEE_INVISIBLE:
2438                 set_mimic_blocking();
2439                 see_monsters();
2440                 if (Invis && !oldprop && !ESee_invisible
2441                     && !perceives(youmonst.data) && !Blind) {
2442                     newsym(u.ux, u.uy);
2443 /*JP
2444                     pline("Suddenly you can see yourself.");
2445 */
2446                     pline("\93Ë\91R\8e©\95ª\8e©\90g\82ª\8c©\82¦\82é\82æ\82¤\82É\82È\82Á\82½\81D");
2447                     makeknown(typ);
2448                 }
2449                 break;
2450             case RIN_INVISIBILITY:
2451                 if (!oldprop && !EInvis && !BInvis && !See_invisible
2452                     && !Blind) {
2453                     newsym(u.ux, u.uy);
2454 #if 0 /*JP*/
2455                     Your("body takes on a %s transparency...",
2456                          Hallucination ? "normal" : "strange");
2457 #else
2458                     pline("%s\82 \82È\82½\82Ì\91Ì\82Í\93§\89ß\90«\82ð\82à\82Á\82½\81D\81D\81D",
2459                           Hallucination ? "\82 \82½\82è\82Ü\82¦\82È\82±\82Æ\82¾\82ª" : "\8aï\96­\82È\82±\82Æ\82É");
2460 #endif
2461                     makeknown(typ);
2462                 }
2463                 break;
2464             case RIN_PROTECTION_FROM_SHAPE_CHAN:
2465                 rescham();
2466                 break;
2467             case RIN_LEVITATION:
2468                 /* undo the `.intrinsic |= FROMOUTSIDE' done above */
2469                 u.uprops[LEVITATION].intrinsic = oldprop;
2470                 if (!Levitation) {
2471                     float_up();
2472                     incr_itimeout(&HLevitation, d(10, 20));
2473                     makeknown(typ);
2474                 }
2475                 break;
2476             } /* inner switch */
2477             break; /* default case of outer switch */
2478
2479         case RIN_ADORNMENT:
2480             accessory_has_effect(otmp);
2481             if (adjattrib(A_CHA, otmp->spe, -1))
2482                 makeknown(typ);
2483             break;
2484         case RIN_GAIN_STRENGTH:
2485             accessory_has_effect(otmp);
2486             if (adjattrib(A_STR, otmp->spe, -1))
2487                 makeknown(typ);
2488             break;
2489         case RIN_GAIN_CONSTITUTION:
2490             accessory_has_effect(otmp);
2491             if (adjattrib(A_CON, otmp->spe, -1))
2492                 makeknown(typ);
2493             break;
2494         case RIN_INCREASE_ACCURACY:
2495             accessory_has_effect(otmp);
2496             u.uhitinc = (schar) bounded_increase((int) u.uhitinc, otmp->spe,
2497                                                  RIN_INCREASE_ACCURACY);
2498             break;
2499         case RIN_INCREASE_DAMAGE:
2500             accessory_has_effect(otmp);
2501             u.udaminc = (schar) bounded_increase((int) u.udaminc, otmp->spe,
2502                                                  RIN_INCREASE_DAMAGE);
2503             break;
2504         case RIN_PROTECTION:
2505             accessory_has_effect(otmp);
2506             HProtection |= FROMOUTSIDE;
2507             u.ublessed = bounded_increase(u.ublessed, otmp->spe,
2508                                           RIN_PROTECTION);
2509             context.botl = 1;
2510             break;
2511         case RIN_FREE_ACTION:
2512             /* Give sleep resistance instead */
2513             if (!(HSleep_resistance & FROMOUTSIDE))
2514                 accessory_has_effect(otmp);
2515             if (!Sleep_resistance)
2516 /*JP
2517                 You_feel("wide awake.");
2518 */
2519                 You("\82Ï\82Á\82¿\82è\96Ú\82ª\82³\82ß\82½\81D");
2520             HSleep_resistance |= FROMOUTSIDE;
2521             break;
2522         case AMULET_OF_CHANGE:
2523             accessory_has_effect(otmp);
2524             makeknown(typ);
2525             change_sex();
2526 #if 0 /*JP*/
2527             You("are suddenly very %s!",
2528                 flags.female ? "feminine" : "masculine");
2529 #else
2530             You("\93Ë\91R\82Æ\82Ä\82à%s\82Á\82Û\82­\82È\82Á\82½\81I", 
2531                 flags.female ? "\8f\97" : "\92j");
2532 #endif
2533             context.botl = 1;
2534             break;
2535         case AMULET_OF_UNCHANGING:
2536             /* un-change: it's a pun */
2537             if (!Unchanging && Upolyd) {
2538                 accessory_has_effect(otmp);
2539                 makeknown(typ);
2540                 rehumanize();
2541             }
2542             break;
2543         case AMULET_OF_STRANGULATION: /* bad idea! */
2544             /* no message--this gives no permanent effect */
2545             choke(otmp);
2546             break;
2547         case AMULET_OF_RESTFUL_SLEEP: { /* another bad idea! */
2548             long newnap = (long) rnd(100), oldnap = (HSleepy & TIMEOUT);
2549
2550             if (!(HSleepy & FROMOUTSIDE))
2551                 accessory_has_effect(otmp);
2552             HSleepy |= FROMOUTSIDE;
2553             /* might also be wearing one; use shorter of two timeouts */
2554             if (newnap < oldnap || oldnap == 0L)
2555                 HSleepy = (HSleepy & ~TIMEOUT) | newnap;
2556             break;
2557         }
2558         case RIN_SUSTAIN_ABILITY:
2559         case AMULET_OF_LIFE_SAVING:
2560         case AMULET_OF_REFLECTION: /* nice try */
2561             /* can't eat Amulet of Yendor or fakes,
2562              * and no oc_prop even if you could -3.
2563              */
2564             break;
2565         }
2566     }
2567 }
2568
2569 /* called after eating non-food */
2570 STATIC_OVL void
2571 eatspecial()
2572 {
2573     struct obj *otmp = context.victual.piece;
2574
2575     /* lesshungry wants an occupation to handle choke messages correctly */
2576 /*JP
2577     set_occupation(eatfood, "eating non-food", 0);
2578 */
2579     set_occupation(eatfood, "\90H\82×\82é", 0);
2580     lesshungry(context.victual.nmod);
2581     occupation = 0;
2582     context.victual.piece = (struct obj *) 0;
2583     context.victual.o_id = 0;
2584     context.victual.eating = 0;
2585     if (otmp->oclass == COIN_CLASS) {
2586         if (carried(otmp))
2587             useupall(otmp);
2588         else
2589             useupf(otmp, otmp->quan);
2590         vault_gd_watching(GD_EATGOLD);
2591         return;
2592     }
2593     if (objects[otmp->otyp].oc_material == PAPER) {
2594 #ifdef MAIL
2595         if (otmp->otyp == SCR_MAIL)
2596             /* no nutrition */
2597 /*JP
2598             pline("This junk mail is less than satisfying.");
2599 */
2600             pline("\82±\82Ì\83S\83~\83\81\81[\83\8b\82Í\96\9e\91«\82É\82Í\82Ù\82Ç\89\93\82¢\81D");
2601         else
2602 #endif
2603         if (otmp->otyp == SCR_SCARE_MONSTER)
2604             /* to eat scroll, hero is currently polymorphed into a monster */
2605 /*JP
2606             pline("Yuck%c", otmp->blessed ? '!' : '.');
2607 */
2608             pline("\82¨\82¦\82Á%s", otmp->blessed ? "\81I" : "\81D");
2609         else if (otmp->oclass == SCROLL_CLASS
2610                  /* check description after checking for specific scrolls */
2611                  && !strcmpi(OBJ_DESCR(objects[otmp->otyp]), "YUM YUM"))
2612 /*JP
2613             pline("Yum%c", otmp->blessed ? '!' : '.');
2614 */
2615             pline("\82¤\82Ü\82¢%s", otmp->blessed ? "\81I" : "\81D");
2616         else
2617 /*JP
2618             pline("Needs salt...");
2619 */
2620             pline("\96¡\82ª\82¤\82·\82¢\81D\81D\81D");
2621     }
2622     if (otmp->oclass == POTION_CLASS) {
2623         otmp->quan++; /* dopotion() does a useup() */
2624         (void) dopotion(otmp);
2625     } else if (otmp->oclass == RING_CLASS || otmp->oclass == AMULET_CLASS) {
2626         eataccessory(otmp);
2627     } else if (otmp->otyp == LEASH && otmp->leashmon) {
2628         o_unleash(otmp);
2629     }
2630
2631     /* KMH -- idea by "Tommy the Terrorist" */
2632     if (otmp->otyp == TRIDENT && !otmp->cursed) {
2633         /* sugarless chewing gum which used to be heavily advertised on TV */
2634 #if 0 /*JP*/
2635         pline(Hallucination ? "Four out of five dentists agree."
2636                             : "That was pure chewing satisfaction!");
2637 #else
2638         pline(Hallucination ? "\8cÜ\90l\82É\8el\90l\82Ì\8e\95\88ã\8eÒ\82ª\83g\83\89\83C\83f\83\93\83g\82ð\82¨\91E\82ß\82µ\82Ä\82¢\82Ü\82·\81D"
2639                             : "\8f\83\90\88\82É\8a\9a\82Ý\82½\82¢\8bC\8e\9d\82ð\96\9e\82½\82µ\82½\81I");
2640 #endif
2641         exercise(A_WIS, TRUE);
2642     }
2643     if (otmp->otyp == FLINT && !otmp->cursed) {
2644         /* chewable vitamin for kids based on "The Flintstones" TV cartoon */
2645 /*JP
2646         pline("Yabba-dabba delicious!");
2647 */
2648         pline("\83\84\83b\83o\83_\83b\83o\82¤\82Ü\82¢\81I");
2649         exercise(A_CON, TRUE);
2650     }
2651
2652     if (otmp == uwep && otmp->quan == 1L)
2653         uwepgone();
2654     if (otmp == uquiver && otmp->quan == 1L)
2655         uqwepgone();
2656     if (otmp == uswapwep && otmp->quan == 1L)
2657         uswapwepgone();
2658
2659     if (otmp == uball)
2660         unpunish();
2661     if (otmp == uchain)
2662         unpunish(); /* but no useup() */
2663     else if (carried(otmp))
2664         useup(otmp);
2665     else
2666         useupf(otmp, 1L);
2667 }
2668
2669 /* NOTE: the order of these words exactly corresponds to the
2670    order of oc_material values #define'd in objclass.h. */
2671 static const char *foodwords[] = {
2672 #if 0 /*JP*/
2673     "meal",    "liquid",  "wax",       "food", "meat",     "paper",
2674     "cloth",   "leather", "wood",      "bone", "scale",    "metal",
2675     "metal",   "metal",   "silver",    "gold", "platinum", "mithril",
2676     "plastic", "glass",   "rich food", "stone"
2677 #else
2678     "\93÷",           "\89t\91Ì",   "\96û",       "\90H\97¿", "\93÷",       "\8e\86",
2679     "\95\9e",           "\94ç",     "\96Ø",       "\8d\9c",   "\97Ø",       "\8bà\91®",
2680     "\8bà\91®",         "\8bà\91®",   "\8bâ",       "\8bà",   "\83v\83\89\83`\83i", "\83~\83X\83\8a\83\8b",
2681     "\83v\83\89\83X\83`\83b\83N", "\83K\83\89\83X", "\8d\82\8b\89\97¿\97\9d", "\90Î"
2682 #endif
2683 };
2684
2685 STATIC_OVL const char *
2686 foodword(otmp)
2687 struct obj *otmp;
2688 {
2689     if (otmp->oclass == FOOD_CLASS)
2690 /*JP
2691         return "food";
2692 */
2693         return "\90H\97¿";
2694     if (otmp->oclass == GEM_CLASS && objects[otmp->otyp].oc_material == GLASS
2695         && otmp->dknown)
2696         makeknown(otmp->otyp);
2697     return foodwords[objects[otmp->otyp].oc_material];
2698 }
2699
2700 /* called after consuming (non-corpse) food */
2701 STATIC_OVL void
2702 fpostfx(otmp)
2703 struct obj *otmp;
2704 {
2705     switch (otmp->otyp) {
2706     case SPRIG_OF_WOLFSBANE:
2707         if (u.ulycn >= LOW_PM || is_were(youmonst.data))
2708             you_unwere(TRUE);
2709         break;
2710     case CARROT:
2711         if (!u.uswallow
2712             || !attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_BLND))
2713             make_blinded((long) u.ucreamed, TRUE);
2714         break;
2715     case FORTUNE_COOKIE:
2716         outrumor(bcsign(otmp), BY_COOKIE);
2717         if (!Blind)
2718             u.uconduct.literate++;
2719         break;
2720     case LUMP_OF_ROYAL_JELLY:
2721         /* This stuff seems to be VERY healthy! */
2722         gainstr(otmp, 1, TRUE);
2723         if (Upolyd) {
2724             u.mh += otmp->cursed ? -rnd(20) : rnd(20);
2725             if (u.mh > u.mhmax) {
2726                 if (!rn2(17))
2727                     u.mhmax++;
2728                 u.mh = u.mhmax;
2729             } else if (u.mh <= 0) {
2730                 rehumanize();
2731             }
2732         } else {
2733             u.uhp += otmp->cursed ? -rnd(20) : rnd(20);
2734             if (u.uhp > u.uhpmax) {
2735                 if (!rn2(17))
2736                     u.uhpmax++;
2737                 u.uhp = u.uhpmax;
2738             } else if (u.uhp <= 0) {
2739                 killer.format = KILLED_BY_AN;
2740 #if 0 /*JP*/
2741                 Strcpy(killer.name, "rotten lump of royal jelly");
2742                 done(POISONING);
2743 #else
2744                 Strcpy(killer.name, "\95\85\82Á\82½\83\8d\83C\83\84\83\8b\83[\83\8a\81[\82ð\90H\82×\90H\92\86\93Å\82Å");
2745                 done(DIED);
2746 #endif
2747             }
2748         }
2749         if (!otmp->cursed)
2750             heal_legs();
2751         break;
2752     case EGG:
2753         if (flesh_petrifies(&mons[otmp->corpsenm])) {
2754             if (!Stone_resistance
2755                 && !(poly_when_stoned(youmonst.data)
2756                      && polymon(PM_STONE_GOLEM))) {
2757                 if (!Stoned) {
2758 /*JP
2759                     Sprintf(killer.name, "%s egg",
2760 */
2761                     Sprintf(killer.name, "%s\82Ì\97\91\82Å",
2762                             mons[otmp->corpsenm].mname);
2763                     make_stoned(5L, (char *) 0, KILLED_BY_AN, killer.name);
2764                 }
2765             }
2766             /* note: no "tastes like chicken" message for eggs */
2767         }
2768         break;
2769     case EUCALYPTUS_LEAF:
2770         if (Sick && !otmp->cursed)
2771             make_sick(0L, (char *) 0, TRUE, SICK_ALL);
2772         if (Vomiting && !otmp->cursed)
2773             make_vomiting(0L, TRUE);
2774         break;
2775     case APPLE:
2776         if (otmp->cursed && !Sleep_resistance) {
2777             /* Snow White; 'poisoned' applies to [a subset of] weapons,
2778                not food, so we substitute cursed; fortunately our hero
2779                won't have to wait for a prince to be rescued/revived */
2780             if (Race_if(PM_DWARF) && Hallucination)
2781 /*JP
2782                 verbalize("Heigh-ho, ho-hum, I think I'll skip work today.");
2783 */
2784                 verbalize("\83n\83C\83z\81[\81C\83n\83C\83z\81[\81C\8d¡\93ú\82Í\8bx\82Ý\81D");
2785             else if (Deaf || !flags.acoustics)
2786 /*JP
2787                 You("fall asleep.");
2788 */
2789                 You("\96°\82è\82É\97\8e\82¿\82½\81D");
2790             else
2791 /*JP
2792                 You_hear("sinister laughter as you fall asleep...");
2793 */
2794                 You_hear("\96°\82è\82É\97\8e\82¿\82é\82Æ\82«\82É\8e×\88«\82È\8fÎ\82¢\90º\82ð\95·\82¢\82½\81D\81D\81D");
2795             fall_asleep(-rn1(11, 20), TRUE);
2796         }
2797         break;
2798     }
2799     return;
2800 }
2801
2802 #if 0
2803 /* intended for eating a spellbook while polymorphed, but not used;
2804    "leather" applied to appearance, not composition, and has been
2805    changed to "leathery" to reflect that */
2806 STATIC_DCL boolean FDECL(leather_cover, (struct obj *));
2807
2808 STATIC_OVL boolean
2809 leather_cover(otmp)
2810 struct obj *otmp;
2811 {
2812     const char *odesc = OBJ_DESCR(objects[otmp->otyp]);
2813
2814     if (odesc && (otmp->oclass == SPBOOK_CLASS)) {
2815         if (!strcmp(odesc, "leather"))
2816             return TRUE;
2817     }
2818     return FALSE;
2819 }
2820 #endif
2821
2822 /*
2823  * return 0 if the food was not dangerous.
2824  * return 1 if the food was dangerous and you chose to stop.
2825  * return 2 if the food was dangerous and you chose to eat it anyway.
2826  */
2827 STATIC_OVL int
2828 edibility_prompts(otmp)
2829 struct obj *otmp;
2830 {
2831     /* Blessed food detection grants hero a one-use
2832      * ability to detect food that is unfit for consumption
2833      * or dangerous and avoid it.
2834      */
2835 #if 0 /*JP*/
2836     char buf[BUFSZ], foodsmell[BUFSZ],
2837          it_or_they[QBUFSZ], eat_it_anyway[QBUFSZ];
2838 #else
2839     char buf[BUFSZ], foodsmell[BUFSZ],
2840          eat_it_anyway[QBUFSZ];
2841 #endif
2842     boolean cadaver = (otmp->otyp == CORPSE || otmp->globby),
2843             stoneorslime = FALSE;
2844     int material = objects[otmp->otyp].oc_material, mnum = otmp->corpsenm;
2845     long rotted = 0L;
2846
2847 #if 0 /*JP*/
2848     Strcpy(foodsmell, Tobjnam(otmp, "smell"));
2849 #else
2850     Strcpy(foodsmell, xname(otmp));
2851 #endif
2852 #if 0 /*JP*/
2853     Strcpy(it_or_they, (otmp->quan == 1L) ? "it" : "they");
2854 #endif
2855 #if 0 /*JP*/
2856     Sprintf(eat_it_anyway, "Eat %s anyway?",
2857             (otmp->quan == 1L) ? "it" : "one");
2858 #else
2859     Strcpy(eat_it_anyway, "\82»\82ê\82Å\82à\90H\82×\82é\81H");
2860 #endif
2861
2862     if (cadaver || otmp->otyp == EGG || otmp->otyp == TIN) {
2863         /* These checks must match those in eatcorpse() */
2864         stoneorslime = (flesh_petrifies(&mons[mnum]) && !Stone_resistance
2865                         && !poly_when_stoned(youmonst.data));
2866
2867         if (mnum == PM_GREEN_SLIME || otmp->otyp == GLOB_OF_GREEN_SLIME)
2868             stoneorslime = (!Unchanging && !slimeproof(youmonst.data));
2869
2870         if (cadaver && !nonrotting_corpse(mnum)) {
2871             long age = peek_at_iced_corpse_age(otmp);
2872
2873             /* worst case rather than random
2874                in this calculation to force prompt */
2875             rotted = (monstermoves - age) / (10L + 0 /* was rn2(20) */);
2876             if (otmp->cursed)
2877                 rotted += 2L;
2878             else if (otmp->blessed)
2879                 rotted -= 2L;
2880         }
2881     }
2882
2883     /*
2884      * These problems with food should be checked in
2885      * order from most detrimental to least detrimental.
2886      */
2887     if (cadaver && mnum != PM_ACID_BLOB && rotted > 5L && !Sick_resistance) {
2888         /* Tainted meat */
2889 #if 0 /*JP*/
2890         Sprintf(buf, "%s like %s could be tainted! %s", foodsmell, it_or_they,
2891                 eat_it_anyway);
2892 #else
2893         Sprintf(buf, "%s\82Í\89\98\90õ\82³\82ê\82Ä\82¢\82é\82æ\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81I%s",
2894                 foodsmell, eat_it_anyway);
2895 #endif
2896         if (yn_function(buf, ynchars, 'n') == 'n')
2897             return 1;
2898         else
2899             return 2;
2900     }
2901     if (stoneorslime) {
2902 #if 0 /*JP*/
2903         Sprintf(buf, "%s like %s could be something very dangerous! %s",
2904                 foodsmell, it_or_they, eat_it_anyway);
2905 #else
2906         Sprintf(buf, "%s\82Í\82È\82ñ\82¾\82©\82·\82²\82­\8aë\8c¯\82»\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81I%s",
2907                 foodsmell, eat_it_anyway);
2908 #endif
2909         if (yn_function(buf, ynchars, 'n') == 'n')
2910             return 1;
2911         else
2912             return 2;
2913     }
2914     if (otmp->orotten || (cadaver && rotted > 3L)) {
2915         /* Rotten */
2916 #if 0 /*JP*/
2917         Sprintf(buf, "%s like %s could be rotten! %s", foodsmell, it_or_they,
2918                 eat_it_anyway);
2919 #else
2920         Sprintf(buf, "%s\82Í\95\85\82Á\82½\82æ\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81I%s",
2921                 foodsmell, eat_it_anyway);
2922 #endif
2923         if (yn_function(buf, ynchars, 'n') == 'n')
2924             return 1;
2925         else
2926             return 2;
2927     }
2928     if (cadaver && poisonous(&mons[mnum]) && !Poison_resistance) {
2929         /* poisonous */
2930 #if 0 /*JP*/
2931         Sprintf(buf, "%s like %s might be poisonous! %s", foodsmell,
2932                 it_or_they, eat_it_anyway);
2933 #else
2934         Sprintf(buf, "%s\82Í\93Å\82ð\82à\82Á\82Ä\82¢\82»\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81I%s",
2935                 foodsmell, eat_it_anyway);
2936 #endif
2937         if (yn_function(buf, ynchars, 'n') == 'n')
2938             return 1;
2939         else
2940             return 2;
2941     }
2942     if (otmp->otyp == APPLE && otmp->cursed && !Sleep_resistance) {
2943         /* causes sleep, for long enough to be dangerous */
2944 #if 0 /*JP*/
2945         Sprintf(buf, "%s like %s might have been poisoned. %s", foodsmell,
2946                 it_or_they, eat_it_anyway);
2947 #else
2948         Sprintf(buf, "%s\82Í\93Å\82ª\93ü\82ê\82ç\82ê\82Ä\82¢\82»\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81I%s",
2949                 foodsmell, eat_it_anyway);
2950 #endif
2951         return (yn_function(buf, ynchars, 'n') == 'n') ? 1 : 2;
2952     }
2953     if (cadaver && !vegetarian(&mons[mnum]) && !u.uconduct.unvegetarian
2954         && Role_if(PM_MONK)) {
2955 /*JP
2956         Sprintf(buf, "%s unhealthy. %s", foodsmell, eat_it_anyway);
2957 */
2958         Sprintf(buf, "%s\82Í\8c\92\8dN\82É\88«\82»\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81D%s", foodsmell, eat_it_anyway);
2959         if (yn_function(buf, ynchars, 'n') == 'n')
2960             return 1;
2961         else
2962             return 2;
2963     }
2964     if (cadaver && acidic(&mons[mnum]) && !Acid_resistance) {
2965 /*JP
2966         Sprintf(buf, "%s rather acidic. %s", foodsmell, eat_it_anyway);
2967 */
2968         Sprintf(buf, "%s\82Í\8f­\82µ\8e_\82Á\82Ï\82»\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81D%s", foodsmell, eat_it_anyway);
2969         if (yn_function(buf, ynchars, 'n') == 'n')
2970             return 1;
2971         else
2972             return 2;
2973     }
2974     if (Upolyd && u.umonnum == PM_RUST_MONSTER && is_metallic(otmp)
2975         && otmp->oerodeproof) {
2976 #if 0 /*JP*/
2977         Sprintf(buf, "%s disgusting to you right now. %s", foodsmell,
2978                 eat_it_anyway);
2979 #else
2980         Sprintf(buf, "%s\82Í\8bC\95ª\82ª\88«\82­\82È\82é\82É\82¨\82¢\82ª\82·\82é\81D%s", foodsmell,
2981                 eat_it_anyway);
2982 #endif
2983         if (yn_function(buf, ynchars, 'n') == 'n')
2984             return 1;
2985         else
2986             return 2;
2987     }
2988
2989     /*
2990      * Breaks conduct, but otherwise safe.
2991      */
2992     if (!u.uconduct.unvegan
2993         && ((material == LEATHER || material == BONE
2994              || material == DRAGON_HIDE || material == WAX)
2995             || (cadaver && !vegan(&mons[mnum])))) {
2996 #if 0 /*JP*/
2997         Sprintf(buf, "%s foul and unfamiliar to you. %s", foodsmell,
2998                 eat_it_anyway);
2999 #else
3000         Sprintf(buf, "%s\82Í\89\98\82ê\82Ä\82¢\82Ä\81C\82 \82È\82½\82É\82È\82\82Ü\82È\82¢\82æ\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81D%s", foodsmell,
3001                 eat_it_anyway);
3002 #endif
3003         if (yn_function(buf, ynchars, 'n') == 'n')
3004             return 1;
3005         else
3006             return 2;
3007     }
3008     if (!u.uconduct.unvegetarian
3009         && ((material == LEATHER || material == BONE
3010              || material == DRAGON_HIDE)
3011             || (cadaver && !vegetarian(&mons[mnum])))) {
3012 /*JP
3013         Sprintf(buf, "%s unfamiliar to you. %s", foodsmell, eat_it_anyway);
3014 */
3015         Sprintf(buf, "%s\82Í\82 \82È\82½\82É\82È\82\82Ü\82È\82¢\82æ\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81D%s", foodsmell, eat_it_anyway);
3016         if (yn_function(buf, ynchars, 'n') == 'n')
3017             return 1;
3018         else
3019             return 2;
3020     }
3021
3022     if (cadaver && mnum != PM_ACID_BLOB && rotted > 5L && Sick_resistance) {
3023         /* Tainted meat with Sick_resistance */
3024 #if 0 /*JP*/
3025         Sprintf(buf, "%s like %s could be tainted! %s", foodsmell, it_or_they,
3026                 eat_it_anyway);
3027 #else
3028         Sprintf(buf, "%s\82Í\89\98\90õ\82³\82ê\82Ä\82¢\82é\82æ\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81I%s", foodsmell,
3029                 eat_it_anyway);
3030 #endif
3031         if (yn_function(buf, ynchars, 'n') == 'n')
3032             return 1;
3033         else
3034             return 2;
3035     }
3036     return 0;
3037 }
3038
3039 /* 'e' command */
3040 int
3041 doeat()
3042 {
3043     struct obj *otmp;
3044     int basenutrit; /* nutrition of full item */
3045     boolean dont_start = FALSE, nodelicious = FALSE;
3046
3047     if (Strangled) {
3048 /*JP
3049         pline("If you can't breathe air, how can you consume solids?");
3050 */
3051         pline("\91§\82à\82Å\82«\82È\82¢\82Ì\82É\81C\82Ç\82¤\82â\82Á\82Ä\90H\82×\82½\82ç\82¢\82¢\82ñ\82¾\82¢\81H");
3052         return 0;
3053     }
3054     if (!(otmp = floorfood("eat", 0)))
3055         return 0;
3056     if (check_capacity((char *) 0))
3057         return 0;
3058
3059     if (u.uedibility) {
3060         int res = edibility_prompts(otmp);
3061
3062         if (res) {
3063 #if 0 /*JP*/
3064             Your(
3065                "%s stops tingling and your sense of smell returns to normal.",
3066                  body_part(NOSE));
3067 #else
3068             Your("%s\82ª\82¤\82¸\82¤\82¸\82·\82é\82Ì\82Í\8e~\82Ü\82è\81C\9ak\8ao\82Í\95\81\92Ê\82É\96ß\82Á\82½\81D",
3069                  body_part(NOSE));
3070 #endif
3071             u.uedibility = 0;
3072             if (res == 1)
3073                 return 0;
3074         }
3075     }
3076
3077     /* We have to make non-foods take 1 move to eat, unless we want to
3078      * do ridiculous amounts of coding to deal with partly eaten plate
3079      * mails, players who polymorph back to human in the middle of their
3080      * metallic meal, etc....
3081      */
3082     if (!is_edible(otmp)) {
3083 /*JP
3084         You("cannot eat that!");
3085 */
3086         You("\82»\82ê\82ð\90H\82×\82ç\82ê\82È\82¢\81I");
3087         return 0;
3088     } else if ((otmp->owornmask & (W_ARMOR | W_TOOL | W_AMUL | W_SADDLE))
3089                != 0) {
3090         /* let them eat rings */
3091 /*JP
3092         You_cant("eat %s you're wearing.", something);
3093 */
3094         You("\90g\82É\82Â\82¯\82Ä\82¢\82é\8aÔ\82Í\90H\82×\82ê\82È\82¢\81D");
3095         return 0;
3096     } else if (!(carried(otmp) ? retouch_object(&otmp, FALSE)
3097                                : touch_artifact(otmp, &youmonst))) {
3098         return 1; /* got blasted so use a turn */
3099     }
3100     if (is_metallic(otmp) && u.umonnum == PM_RUST_MONSTER
3101         && otmp->oerodeproof) {
3102         otmp->rknown = TRUE;
3103         if (otmp->quan > 1L) {
3104             if (!carried(otmp))
3105                 (void) splitobj(otmp, otmp->quan - 1L);
3106             else
3107                 otmp = splitobj(otmp, 1L);
3108         }
3109 /*JP
3110         pline("Ulch - that %s was rustproofed!", xname(otmp));
3111 */
3112         pline("\83E\83Q\83F\81[\81I%s\82Í\96h\8eK\82³\82ê\82Ä\82¢\82é\81I", xname(otmp));
3113         /* The regurgitated object's rustproofing is gone now */
3114         otmp->oerodeproof = 0;
3115         make_stunned((HStun & TIMEOUT) + (long) rn2(10), TRUE);
3116         /*
3117          * We don't expect rust monsters to be wielding welded weapons
3118          * or wearing cursed rings which were rustproofed, but guard
3119          * against the possibility just in case.
3120          */
3121         if (welded(otmp) || (otmp->cursed && (otmp->owornmask & W_RING))) {
3122             otmp->bknown = 1; /* for ring; welded() does this for weapon */
3123 /*JP
3124             You("spit out %s.", the(xname(otmp)));
3125 */
3126             You("%s\82ð\93f\82«\8fo\82µ\82½\81D", xname(otmp));
3127         } else {
3128 #if 0 /*JP*/
3129             You("spit %s out onto the %s.", the(xname(otmp)),
3130                 surface(u.ux, u.uy));
3131 #else
3132             You("%s\82ð%s\82É\93f\82«\8fo\82µ\82½\81D", the(xname(otmp)),
3133                 surface(u.ux, u.uy));
3134 #endif
3135             if (carried(otmp)) {
3136                 /* no need to check for leash in use; it's not metallic */
3137                 if (otmp->owornmask)
3138                     remove_worn_item(otmp, FALSE);
3139                 freeinv(otmp);
3140                 dropy(otmp);
3141             }
3142             stackobj(otmp);
3143         }
3144         return 1;
3145     }
3146     /* KMH -- Slow digestion is... indigestible */
3147     if (otmp->otyp == RIN_SLOW_DIGESTION) {
3148 /*JP
3149         pline("This ring is indigestible!");
3150 */
3151         pline("\82±\82Ì\8ew\97Ö\82Í\8fÁ\89»\82µ\82É\82­\82¢\81I");
3152         (void) rottenfood(otmp);
3153         if (otmp->dknown && !objects[otmp->otyp].oc_name_known
3154             && !objects[otmp->otyp].oc_uname)
3155             docall(otmp);
3156         return 1;
3157     }
3158     if (otmp->oclass != FOOD_CLASS) {
3159         int material;
3160
3161         context.victual.reqtime = 1;
3162         context.victual.piece = otmp;
3163         context.victual.o_id = otmp->o_id;
3164         /* Don't split it, we don't need to if it's 1 move */
3165         context.victual.usedtime = 0;
3166         context.victual.canchoke = (u.uhs == SATIATED);
3167         /* Note: gold weighs 1 pt. for each 1000 pieces (see
3168            pickup.c) so gold and non-gold is consistent. */
3169         if (otmp->oclass == COIN_CLASS)
3170             basenutrit = ((otmp->quan > 200000L)
3171                              ? 2000
3172                              : (int) (otmp->quan / 100L));
3173         else if (otmp->oclass == BALL_CLASS || otmp->oclass == CHAIN_CLASS)
3174             basenutrit = weight(otmp);
3175         /* oc_nutrition is usually weight anyway */
3176         else
3177             basenutrit = objects[otmp->otyp].oc_nutrition;
3178 #ifdef MAIL
3179         if (otmp->otyp == SCR_MAIL) {
3180             basenutrit = 0;
3181             nodelicious = TRUE;
3182         }
3183 #endif
3184         context.victual.nmod = basenutrit;
3185         context.victual.eating = TRUE; /* needed for lesshungry() */
3186
3187         material = objects[otmp->otyp].oc_material;
3188         if (material == LEATHER || material == BONE
3189             || material == DRAGON_HIDE) {
3190             u.uconduct.unvegan++;
3191             violated_vegetarian();
3192         } else if (material == WAX)
3193             u.uconduct.unvegan++;
3194         u.uconduct.food++;
3195
3196         if (otmp->cursed) {
3197             (void) rottenfood(otmp);
3198             nodelicious = TRUE;
3199         } else if (objects[otmp->otyp].oc_material == PAPER)
3200             nodelicious = TRUE;
3201
3202         if (otmp->oclass == WEAPON_CLASS && otmp->opoisoned) {
3203 /*JP
3204             pline("Ecch - that must have been poisonous!");
3205 */
3206             pline("\83E\83Q\83F\81[\81C\97L\93Å\82¾\82Á\82½\82É\88á\82¢\82È\82¢\81I");  
3207             if (!Poison_resistance) {
3208                 losestr(rnd(4));
3209 #if 0 /*JP*/
3210                 losehp(rnd(15), xname(otmp), KILLED_BY_AN);
3211 #else
3212                 {
3213                     char jbuf[BUFSZ];
3214                     Sprintf(jbuf, "%s\82Å", xname(otmp));
3215                     losehp(rnd(15), jbuf, KILLED_BY_AN);
3216                 }
3217 #endif
3218             } else
3219 /*JP
3220                 You("seem unaffected by the poison.");
3221 */
3222                 You("\93Å\82Ì\89e\8b¿\82ð\8eó\82¯\82È\82¢\82æ\82¤\82¾\81D");
3223         } else if (!nodelicious) {
3224 #if 0 /*JP*/
3225             pline("%s%s is delicious!",
3226                   (obj_is_pname(otmp)
3227                    && otmp->oartifact < ART_ORB_OF_DETECTION)
3228                       ? ""
3229                       : "This ",
3230                   (otmp->oclass == COIN_CLASS)
3231                       ? foodword(otmp)
3232                       : singular(otmp, xname));
3233 #else
3234             pline("\82±\82Ì%s\82Í\8e|\82¢\81I",
3235                   otmp->oclass == COIN_CLASS
3236                       ? foodword(otmp)
3237                       : singular(otmp, xname));
3238 #endif
3239         }
3240         eatspecial();
3241         return 1;
3242     }
3243
3244     if (otmp == context.victual.piece) {
3245         /* If they weren't able to choke, they don't suddenly become able to
3246          * choke just because they were interrupted.  On the other hand, if
3247          * they were able to choke before, if they lost food it's possible
3248          * they shouldn't be able to choke now.
3249          */
3250         if (u.uhs != SATIATED)
3251             context.victual.canchoke = FALSE;
3252         context.victual.o_id = 0;
3253         context.victual.piece = touchfood(otmp);
3254         if (context.victual.piece)
3255             context.victual.o_id = context.victual.piece->o_id;
3256 /*JP
3257         You("resume your meal.");
3258 */
3259         You("\90H\8e\96\82ð\8dÄ\8aJ\82µ\82½\81D");
3260         start_eating(context.victual.piece);
3261         return 1;
3262     }
3263
3264     /* nothing in progress - so try to find something. */
3265     /* tins are a special case */
3266     /* tins must also check conduct separately in case they're discarded */
3267     if (otmp->otyp == TIN) {
3268         start_tin(otmp);
3269         return 1;
3270     }
3271
3272     /* KMH, conduct */
3273     u.uconduct.food++;
3274
3275     context.victual.o_id = 0;
3276     context.victual.piece = otmp = touchfood(otmp);
3277     if (context.victual.piece)
3278         context.victual.o_id = context.victual.piece->o_id;
3279     context.victual.usedtime = 0;
3280
3281     /* Now we need to calculate delay and nutritional info.
3282      * The base nutrition calculated here and in eatcorpse() accounts
3283      * for normal vs. rotten food.  The reqtime and nutrit values are
3284      * then adjusted in accordance with the amount of food left.
3285      */
3286     if (otmp->otyp == CORPSE || otmp->globby) {
3287         int tmp = eatcorpse(otmp);
3288
3289         if (tmp == 2) {
3290             /* used up */
3291             context.victual.piece = (struct obj *) 0;
3292             context.victual.o_id = 0;
3293             return 1;
3294         } else if (tmp)
3295             dont_start = TRUE;
3296         /* if not used up, eatcorpse sets up reqtime and may modify oeaten */
3297     } else {
3298         /* No checks for WAX, LEATHER, BONE, DRAGON_HIDE.  These are
3299          * all handled in the != FOOD_CLASS case, above.
3300          */
3301         switch (objects[otmp->otyp].oc_material) {
3302         case FLESH:
3303             u.uconduct.unvegan++;
3304             if (otmp->otyp != EGG) {
3305                 violated_vegetarian();
3306             }
3307             break;
3308
3309         default:
3310             if (otmp->otyp == PANCAKE || otmp->otyp == FORTUNE_COOKIE /*eggs*/
3311                 || otmp->otyp == CREAM_PIE || otmp->otyp == CANDY_BAR /*milk*/
3312                 || otmp->otyp == LUMP_OF_ROYAL_JELLY)
3313                 u.uconduct.unvegan++;
3314             break;
3315         }
3316
3317         context.victual.reqtime = objects[otmp->otyp].oc_delay;
3318         if (otmp->otyp != FORTUNE_COOKIE
3319             && (otmp->cursed || (!nonrotting_food(otmp->otyp)
3320                                  && (monstermoves - otmp->age)
3321                                         > (otmp->blessed ? 50L : 30L)
3322                                  && (otmp->orotten || !rn2(7))))) {
3323             if (rottenfood(otmp)) {
3324                 otmp->orotten = TRUE;
3325                 dont_start = TRUE;
3326             }
3327             consume_oeaten(otmp, 1); /* oeaten >>= 1 */
3328         } else
3329             fprefx(otmp);
3330     }
3331
3332     /* re-calc the nutrition */
3333     basenutrit = (int) obj_nutrition(otmp);
3334
3335     debugpline3(
3336      "before rounddiv: victual.reqtime == %d, oeaten == %d, basenutrit == %d",
3337                 context.victual.reqtime, otmp->oeaten, basenutrit);
3338
3339     context.victual.reqtime = (basenutrit == 0) ? 0
3340         : rounddiv(context.victual.reqtime * (long) otmp->oeaten, basenutrit);
3341
3342     debugpline1("after rounddiv: victual.reqtime == %d",
3343                 context.victual.reqtime);
3344     /*
3345      * calculate the modulo value (nutrit. units per round eating)
3346      * note: this isn't exact - you actually lose a little nutrition due
3347      *       to this method.
3348      * TODO: add in a "remainder" value to be given at the end of the meal.
3349      */
3350     if (context.victual.reqtime == 0 || otmp->oeaten == 0)
3351         /* possible if most has been eaten before */
3352         context.victual.nmod = 0;
3353     else if ((int) otmp->oeaten >= context.victual.reqtime)
3354         context.victual.nmod = -((int) otmp->oeaten
3355                                  / context.victual.reqtime);
3356     else
3357         context.victual.nmod = context.victual.reqtime % otmp->oeaten;
3358     context.victual.canchoke = (u.uhs == SATIATED);
3359
3360     if (!dont_start)
3361         start_eating(otmp);
3362     return 1;
3363 }
3364
3365 int
3366 use_tin_opener(obj)
3367 struct obj *obj;
3368 {
3369     struct obj *otmp;
3370     int res = 0;
3371
3372     if (!carrying(TIN)) {
3373 /*JP
3374         You("have no tin to open.");
3375 */
3376         You("\8aÊ\82ð\8e\9d\82Á\82Ä\82¢\82È\82¢\81D");
3377         return 0;
3378     }
3379
3380     if (obj != uwep) {
3381         if (obj->cursed && obj->bknown) {
3382             char qbuf[QBUFSZ];
3383
3384 #if 0 /*JP*/
3385             if (ynq(safe_qbuf(qbuf, "Really wield ", "?",
3386                               obj, doname, thesimpleoname, "that")) != 'y')
3387 #else
3388             if (ynq(safe_qbuf(qbuf, "\96{\93\96\82É", "\82ð\91\95\94õ\82·\82é\81H",
3389                               obj, doname, thesimpleoname, "\82»\82ê")) != 'y')
3390 #endif
3391                 return 0;
3392         }
3393         if (!wield_tool(obj, "use"))
3394             return 0;
3395         res = 1;
3396     }
3397
3398     otmp = getobj(comestibles, "open");
3399     if (!otmp)
3400         return res;
3401
3402     start_tin(otmp);
3403     return 1;
3404 }
3405
3406 /* Take a single bite from a piece of food, checking for choking and
3407  * modifying usedtime.  Returns 1 if they choked and survived, 0 otherwise.
3408  */
3409 STATIC_OVL int
3410 bite()
3411 {
3412     if (context.victual.canchoke && u.uhunger >= 2000) {
3413         choke(context.victual.piece);
3414         return 1;
3415     }
3416     if (context.victual.doreset) {
3417         do_reset_eat();
3418         return 0;
3419     }
3420     force_save_hs = TRUE;
3421     if (context.victual.nmod < 0) {
3422         lesshungry(-context.victual.nmod);
3423         consume_oeaten(context.victual.piece,
3424                        context.victual.nmod); /* -= -nmod */
3425     } else if (context.victual.nmod > 0
3426                && (context.victual.usedtime % context.victual.nmod)) {
3427         lesshungry(1);
3428         consume_oeaten(context.victual.piece, -1); /* -= 1 */
3429     }
3430     force_save_hs = FALSE;
3431     recalc_wt();
3432     return 0;
3433 }
3434
3435 /* as time goes by - called by moveloop(every move) & domove(melee attack) */
3436 void
3437 gethungry()
3438 {
3439     if (u.uinvulnerable)
3440         return; /* you don't feel hungrier */
3441
3442     /* being polymorphed into a creature which doesn't eat prevents
3443        this first uhunger decrement, but to stay in such form the hero
3444        will need to wear an Amulet of Unchanging so still burn a small
3445        amount of nutrition in the 'moves % 20' ring/amulet check below */
3446     if ((!Unaware || !rn2(10)) /* slow metabolic rate while asleep */
3447         && (carnivorous(youmonst.data)
3448             || herbivorous(youmonst.data)
3449             || metallivorous(youmonst.data))
3450         && !Slow_digestion)
3451         u.uhunger--; /* ordinary food consumption */
3452
3453     if (moves % 2) { /* odd turns */
3454         /* Regeneration uses up food, unless due to an artifact */
3455         if ((HRegeneration & ~FROMFORM)
3456             || (ERegeneration & ~(W_ARTI | W_WEP)))
3457             u.uhunger--;
3458         if (near_capacity() > SLT_ENCUMBER)
3459             u.uhunger--;
3460     } else { /* even turns */
3461         if (Hunger)
3462             u.uhunger--;
3463         /* Conflict uses up food too */
3464         if (HConflict || (EConflict & (~W_ARTI)))
3465             u.uhunger--;
3466         /* +0 charged rings don't do anything, so don't affect hunger.
3467            Slow digestion cancels move hunger but still causes ring hunger. */
3468         switch ((int) (moves % 20)) { /* note: use even cases only */
3469         case 4:
3470             if (uleft && (uleft->spe || !objects[uleft->otyp].oc_charged))
3471                 u.uhunger--;
3472             break;
3473         case 8:
3474             if (uamul)
3475                 u.uhunger--;
3476             break;
3477         case 12:
3478             if (uright && (uright->spe || !objects[uright->otyp].oc_charged))
3479                 u.uhunger--;
3480             break;
3481         case 16:
3482             if (u.uhave.amulet)
3483                 u.uhunger--;
3484             break;
3485         default:
3486             break;
3487         }
3488     }
3489     newuhs(TRUE);
3490 }
3491
3492 /* called after vomiting and after performing feats of magic */
3493 void
3494 morehungry(num)
3495 int num;
3496 {
3497     u.uhunger -= num;
3498     newuhs(TRUE);
3499 }
3500
3501 /* called after eating (and after drinking fruit juice) */
3502 void
3503 lesshungry(num)
3504 int num;
3505 {
3506     /* See comments in newuhs() for discussion on force_save_hs */
3507     boolean iseating = (occupation == eatfood) || force_save_hs;
3508
3509     debugpline1("lesshungry(%d)", num);
3510     u.uhunger += num;
3511     if (u.uhunger >= 2000) {
3512         if (!iseating || context.victual.canchoke) {
3513             if (iseating) {
3514                 choke(context.victual.piece);
3515                 reset_eat();
3516             } else
3517                 choke(occupation == opentin ? context.tin.tin
3518                                             : (struct obj *) 0);
3519             /* no reset_eat() */
3520         }
3521     } else {
3522         /* Have lesshungry() report when you're nearly full so all eating
3523          * warns when you're about to choke.
3524          */
3525         if (u.uhunger >= 1500) {
3526             if (!context.victual.eating
3527                 || (context.victual.eating && !context.victual.fullwarn)) {
3528 /*JP
3529                 pline("You're having a hard time getting all of it down.");
3530 */
3531                 pline("\91S\82Ä\82ð\88ù\82Ý\82±\82Þ\82É\82Í\8e\9e\8aÔ\82ª\82©\82©\82é\81D");
3532 /*JP
3533                 nomovemsg = "You're finally finished.";
3534 */
3535                 nomovemsg = "\82â\82Á\82Æ\90H\82×\8fI\82¦\82½\81D";
3536                 if (!context.victual.eating) {
3537                     multi = -2;
3538                 } else {
3539                     context.victual.fullwarn = TRUE;
3540                     if (context.victual.canchoke
3541                         && context.victual.reqtime > 1) {
3542                         /* a one-gulp food will not survive a stop */
3543 /*JP
3544                         if (yn_function("Continue eating?", ynchars, 'n')
3545 */
3546                         if (yn_function("\90H\82×\91±\82¯\82Ü\82·\82©\81H", ynchars, 'n')
3547                             != 'y') {
3548                             reset_eat();
3549                             nomovemsg = (char *) 0;
3550                         }
3551                     }
3552                 }
3553             }
3554         }
3555     }
3556     newuhs(FALSE);
3557 }
3558
3559 STATIC_PTR
3560 int
3561 unfaint(VOID_ARGS)
3562 {
3563     (void) Hear_again();
3564     if (u.uhs > FAINTING)
3565         u.uhs = FAINTING;
3566     stop_occupation();
3567     context.botl = 1;
3568     return 0;
3569 }
3570
3571 boolean
3572 is_fainted()
3573 {
3574     return (boolean) (u.uhs == FAINTED);
3575 }
3576
3577 /* call when a faint must be prematurely terminated */
3578 void
3579 reset_faint()
3580 {
3581     if (afternmv == unfaint)
3582 /*JP
3583         unmul("You revive.");
3584 */
3585         unmul("\82 \82È\82½\82Í\8bC\82ª\82Â\82¢\82½\81D");
3586 }
3587
3588 /* compute and comment on your (new?) hunger status */
3589 void
3590 newuhs(incr)
3591 boolean incr;
3592 {
3593     unsigned newhs;
3594     static unsigned save_hs;
3595     static boolean saved_hs = FALSE;
3596     int h = u.uhunger;
3597
3598     newhs = (h > 1000)
3599                 ? SATIATED
3600                 : (h > 150) ? NOT_HUNGRY
3601                             : (h > 50) ? HUNGRY : (h > 0) ? WEAK : FAINTING;
3602
3603     /* While you're eating, you may pass from WEAK to HUNGRY to NOT_HUNGRY.
3604      * This should not produce the message "you only feel hungry now";
3605      * that message should only appear if HUNGRY is an endpoint.  Therefore
3606      * we check to see if we're in the middle of eating.  If so, we save
3607      * the first hunger status, and at the end of eating we decide what
3608      * message to print based on the _entire_ meal, not on each little bit.
3609      */
3610     /* It is normally possible to check if you are in the middle of a meal
3611      * by checking occupation == eatfood, but there is one special case:
3612      * start_eating() can call bite() for your first bite before it
3613      * sets the occupation.
3614      * Anyone who wants to get that case to work _without_ an ugly static
3615      * force_save_hs variable, feel free.
3616      */
3617     /* Note: If you become a certain hunger status in the middle of the
3618      * meal, and still have that same status at the end of the meal,
3619      * this will incorrectly print the associated message at the end of
3620      * the meal instead of the middle.  Such a case is currently
3621      * impossible, but could become possible if a message for SATIATED
3622      * were added or if HUNGRY and WEAK were separated by a big enough
3623      * gap to fit two bites.
3624      */
3625     if (occupation == eatfood || force_save_hs) {
3626         if (!saved_hs) {
3627             save_hs = u.uhs;
3628             saved_hs = TRUE;
3629         }
3630         u.uhs = newhs;
3631         return;
3632     } else {
3633         if (saved_hs) {
3634             u.uhs = save_hs;
3635             saved_hs = FALSE;
3636         }
3637     }
3638
3639     if (newhs == FAINTING) {
3640         /* u,uhunger is likely to be negative at this point */
3641         int uhunger_div_by_10 = sgn(u.uhunger) * ((abs(u.uhunger) + 5) / 10);
3642
3643         if (is_fainted())
3644             newhs = FAINTED;
3645         if (u.uhs <= WEAK || rn2(20 - uhunger_div_by_10) >= 19) {
3646             if (!is_fainted() && multi >= 0 /* %% */) {
3647                 int duration = 10 - uhunger_div_by_10;
3648
3649                 /* stop what you're doing, then faint */
3650                 stop_occupation();
3651 /*JP
3652                 You("faint from lack of food.");
3653 */
3654                 You("\95 \82ª\8c¸\82Á\82Ä\93|\82ê\82½\81D");
3655                 incr_itimeout(&HDeaf, duration);
3656                 context.botl = TRUE;
3657                 nomul(-duration);
3658 /*JP
3659                 multi_reason = "fainted from lack of food";
3660 */
3661                 multi_reason = "\8bó\95 \82Å\91²\93|\82µ\82Ä\82¢\82é\8aÔ\82É";
3662 /*JP
3663                 nomovemsg = "You regain consciousness.";
3664 */
3665                 nomovemsg = "\82 \82È\82½\82Í\90³\8bC\82Ã\82¢\82½\81D";
3666                 afternmv = unfaint;
3667                 newhs = FAINTED;
3668                 if (!Levitation)
3669 /*JP
3670                     selftouch("Falling, you");
3671 */
3672                     selftouch("\97\8e\82¿\82È\82ª\82ç\81C\82 \82È\82½\82Í");
3673             }
3674
3675         /* this used to be -(200 + 20 * Con) but that was when being asleep
3676            suppressed per-turn uhunger decrement but being fainted didn't;
3677            now uhunger becomes more negative at a slower rate */
3678         } else if (u.uhunger < -(100 + 10 * (int) ACURR(A_CON))) {
3679             u.uhs = STARVED;
3680             context.botl = 1;
3681             bot();
3682 /*JP
3683             You("die from starvation.");
3684 */
3685             You("\89ì\8e\80\82µ\82½\81D");
3686             killer.format = KILLED_BY;
3687 /*JP
3688             Strcpy(killer.name, "starvation");
3689 */
3690             Strcpy(killer.name, "\90H\97¿\95s\91«\82Å\89ì\8e\80\82µ\82½");
3691             done(STARVING);
3692             /* if we return, we lifesaved, and that calls newuhs */
3693             return;
3694         }
3695     }
3696
3697     if (newhs != u.uhs) {
3698         if (newhs >= WEAK && u.uhs < WEAK) {
3699             /* this used to be losestr(1) which had the potential to
3700                be fatal (still handled below) by reducing HP if it
3701                tried to take base strength below minimum of 3 */
3702             ATEMP(A_STR) = -1; /* temporary loss overrides Fixed_abil */
3703             /* defer context.botl status update until after hunger message */
3704         } else if (newhs < WEAK && u.uhs >= WEAK) {
3705             /* this used to be losestr(-1) which could be abused by
3706                becoming weak while wearing ring of sustain ability,
3707                removing ring, eating to 'restore' strength which boosted
3708                strength by a point each time the cycle was performed;
3709                substituting "while polymorphed" for sustain ability and
3710                "rehumanize" for ring removal might have done that too */
3711             ATEMP(A_STR) = 0; /* repair of loss also overrides Fixed_abil */
3712             /* defer context.botl status update until after hunger message */
3713         }
3714
3715         switch (newhs) {
3716         case HUNGRY:
3717             if (Hallucination) {
3718 #if 0 /*JP:T*/
3719                 You((!incr) ? "now have a lesser case of the munchies."
3720                             : "are getting the munchies.");
3721 #else
3722                 if (!incr) {
3723                     You("\83n\83\89\83w\83\8a\82ª\8c¸\82Á\82½\81D");
3724                 } else {
3725                     pline("\83n\83\89\83w\83\8a\83w\83\8a\83n\83\89\81D");
3726                 }
3727 #endif
3728             } else
3729 /*JP
3730                 You((!incr) ? "only feel hungry now."
3731 */
3732                 You((!incr) ? "\92P\82É\95 \83y\83R\8fó\91Ô\82É\82È\82Á\82½\81D"
3733                             : (u.uhunger < 145)
3734 /*JP
3735                                   ? "feel hungry."
3736 */
3737                                   ? "\8bó\95 \8a´\82ð\8a´\82\82½\81D"
3738 /*JP
3739                                   : "are beginning to feel hungry.");
3740 */
3741                                   : "\8bó\95 \8a´\82ð\82¨\82Ú\82¦\82Í\82\82ß\82½\81D");
3742             if (incr && occupation
3743                 && (occupation != eatfood && occupation != opentin))
3744                 stop_occupation();
3745             context.travel = context.travel1 = context.mv = context.run = 0;
3746             break;
3747         case WEAK:
3748             if (Hallucination)
3749 /*JP
3750                 pline((!incr) ? "You still have the munchies."
3751 */
3752                 pline((!incr) ? "\83n\83\89\83w\83\8a\82ª\8c¸\82ç\82È\82¢\81D"
3753 /*JP
3754               : "The munchies are interfering with your motor capabilities.");
3755 */
3756               : "\83n\83\89\83w\83\8a\82ª\83\82\81[\83^\81[\90«\94\\82É\89e\8b¿\82ð\97^\82¦\82Ä\82¢\82é\81D");
3757             else if (incr && (Role_if(PM_WIZARD) || Race_if(PM_ELF)
3758                               || Role_if(PM_VALKYRIE)))
3759 /*JP
3760                 pline("%s needs food, badly!",
3761 */
3762                 pline("%s\82É\82Í\8e\8a\8b}\90H\97¿\82ª\95K\97v\82¾\81I",
3763                       (Role_if(PM_WIZARD) || Role_if(PM_VALKYRIE))
3764                           ? urole.name.m
3765 /*JP
3766                           : "Elf");
3767 */
3768                           : "\83G\83\8b\83t");
3769             else
3770                 You((!incr)
3771 /*JP
3772                         ? "feel weak now."
3773 */
3774                         ? "\90\8a\8eã\8fó\91Ô\82É\82È\82Á\82½\81D"
3775 /*JP
3776                         : (u.uhunger < 45) ? "feel weak."
3777 */
3778                         : (u.uhunger < 45) ? "\90\8a\8eã\82µ\82Ä\82«\82½\81D"
3779 /*JP
3780                                            : "are beginning to feel weak.");
3781 */
3782                                            : "\8eã\82­\82È\82Á\82Ä\82«\82½\82æ\82¤\82É\8a´\82\82½\81D");
3783             if (incr && occupation
3784                 && (occupation != eatfood && occupation != opentin))
3785                 stop_occupation();
3786             context.travel = context.travel1 = context.mv = context.run = 0;
3787             break;
3788         }
3789         u.uhs = newhs;
3790         context.botl = 1;
3791         bot();
3792         if ((Upolyd ? u.mh : u.uhp) < 1) {
3793 /*JP
3794             You("die from hunger and exhaustion.");
3795 */
3796             You("\8bó\95 \82Æ\90\8a\8eã\82Å\8e\80\82ñ\82¾\81D");
3797             killer.format = KILLED_BY;
3798 /*JP
3799             Strcpy(killer.name, "exhaustion");
3800 */
3801             Strcpy(killer.name, "\8bó\95 \82Æ\90\8a\8eã\82Å\8e\80\82ñ\82¾");
3802             done(STARVING);
3803             return;
3804         }
3805     }
3806 }
3807
3808 /* Returns an object representing food.
3809  * Object may be either on floor or in inventory.
3810  */
3811 /*JP CHECK: 3.6.1 \82Å\82Ì\8cÄ\82Ñ\8fo\82µ\8c³
3812 apply.c:2478:    if (!(corpse = floorfood("tin", 2)))
3813 eat.c:3050:    if (!(otmp = floorfood("eat", 0)))
3814 pray.c:1659:    otmp = floorfood("sacrifice", 1);
3815   \82±\82Ì\8aÖ\90\94\82Í\89p\8cê\96¼\82Ì\82Ü\82Ü\8cÄ\82Ñ\8fo\82·\82±\82Æ\81B
3816 */
3817 struct obj *
3818 floorfood(verb, corpsecheck)
3819 const char *verb;
3820 int corpsecheck; /* 0, no check, 1, corpses, 2, tinnable corpses */
3821 {
3822     register struct obj *otmp;
3823     char qbuf[QBUFSZ];
3824     char c;
3825     boolean feeding = !strcmp(verb, "eat"),    /* corpsecheck==0 */
3826         offering = !strcmp(verb, "sacrifice"); /* corpsecheck==1 */
3827
3828 #if 1 /*JP*/
3829     const char *jverb = trans_verb(verb)->jp;
3830 #endif
3831
3832     /* if we can't touch floor objects then use invent food only */
3833     if (iflags.menu_requested /* command was preceded by 'm' prefix */
3834         || !can_reach_floor(TRUE) || (feeding && u.usteed)
3835         || (is_pool_or_lava(u.ux, u.uy)
3836             && (Wwalking || is_clinger(youmonst.data)
3837                 || (Flying && !Breathless))))
3838         goto skipfloor;
3839
3840     if (feeding && metallivorous(youmonst.data)) {
3841         struct obj *gold;
3842         struct trap *ttmp = t_at(u.ux, u.uy);
3843
3844         if (ttmp && ttmp->tseen && ttmp->ttyp == BEAR_TRAP) {
3845             /* If not already stuck in the trap, perhaps there should
3846                be a chance to becoming trapped?  Probably not, because
3847                then the trap would just get eaten on the _next_ turn... */
3848 /*JP
3849             Sprintf(qbuf, "There is a bear trap here (%s); eat it?",
3850 */
3851             Sprintf(qbuf, "\82±\82±\82É\82Í\8cF\82Ìã©(%s)\82ª\82 \82é; \90H\82×\82Ü\82·\82©\81H",
3852 /*JP
3853                     (u.utrap && u.utraptype == TT_BEARTRAP) ? "holding you"
3854 */
3855                     (u.utrap && u.utraptype == TT_BEARTRAP) ? "\82 \82È\82½\82ð\92Í\82Ü\82¦\82Ä\82¢\82é"
3856 /*JP
3857                                                             : "armed");
3858 */
3859                                                             : "\89Ò\93®\92\86");
3860             if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
3861                 u.utrap = u.utraptype = 0;
3862                 deltrap(ttmp);
3863                 return mksobj(BEARTRAP, TRUE, FALSE);
3864             } else if (c == 'q') {
3865                 return (struct obj *) 0;
3866             }
3867         }
3868
3869         if (youmonst.data != &mons[PM_RUST_MONSTER]
3870             && (gold = g_at(u.ux, u.uy)) != 0) {
3871 #if 0 /*JP*/
3872             if (gold->quan == 1L)
3873                 Sprintf(qbuf, "There is 1 gold piece here; eat it?");
3874             else
3875                 Sprintf(qbuf, "There are %ld gold pieces here; eat them?",
3876                         gold->quan);
3877 #else
3878             Sprintf(qbuf, "\82±\82±\82É\82Í%ld\96\87\82Ì\8bà\89Ý\82ª\82 \82é\81D\90H\82×\82Ü\82·\82©\81H", gold->quan);
3879 #endif
3880             if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
3881                 return gold;
3882             } else if (c == 'q') {
3883                 return (struct obj *) 0;
3884             }
3885         }
3886     }
3887
3888     /* Is there some food (probably a heavy corpse) here on the ground? */
3889     for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) {
3890         if (corpsecheck
3891                 ? (otmp->otyp == CORPSE
3892                    && (corpsecheck == 1 || tinnable(otmp)))
3893                 : feeding ? (otmp->oclass != COIN_CLASS && is_edible(otmp))
3894                           : otmp->oclass == FOOD_CLASS) {
3895             char qsfx[QBUFSZ];
3896             boolean one = (otmp->quan == 1L);
3897
3898             /* if blind and without gloves, attempting to eat (or tin or
3899                offer) a cockatrice corpse is fatal before asking whether
3900                or not to use it; otherwise, 'm<dir>' followed by 'e' could
3901                be used to locate cockatrice corpses without touching them */
3902             if (otmp->otyp == CORPSE && will_feel_cockatrice(otmp, FALSE)) {
3903                 feel_cockatrice(otmp, FALSE);
3904                 /* if life-saved (or poly'd into stone golem), terminate
3905                    attempt to eat off floor */
3906                 return (struct obj *) 0;
3907             }
3908             /* "There is <an object> here; <verb> it?" or
3909                "There are <N objects> here; <verb> one?" */
3910 #if 0 /*JP*/
3911             Sprintf(qbuf, "There %s ", otense(otmp, "are"));
3912             Sprintf(qsfx, " here; %s %s?", verb, one ? "it" : "one");
3913             (void) safe_qbuf(qbuf, qbuf, qsfx, otmp, doname, ansimpleoname,
3914                              one ? something : (const char *) "things");
3915 #else
3916             Strcpy(qbuf, "\82±\82±\82É");
3917             Sprintf(qsfx, "\82ª\82 \82é; %s%s?", one ? "" : "\88ê\82Â", jverb);
3918             (void) safe_qbuf(qbuf, qbuf, qsfx, otmp, doname, ansimpleoname,
3919                              one ? something : (const char *) "\89½\82©");
3920 #endif
3921             if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y')
3922                 return  otmp;
3923             else if (c == 'q')
3924                 return (struct obj *) 0;
3925         }
3926     }
3927
3928 skipfloor:
3929     /* We cannot use ALL_CLASSES since that causes getobj() to skip its
3930      * "ugly checks" and we need to check for inedible items.
3931      */
3932     otmp = getobj(feeding ? allobj : offering ? offerfodder : comestibles,
3933                   verb);
3934     if (corpsecheck && otmp && !(offering && otmp->oclass == AMULET_CLASS))
3935         if (otmp->otyp != CORPSE || (corpsecheck == 2 && !tinnable(otmp))) {
3936 /*JP
3937             You_cant("%s that!", verb);
3938 */
3939             You_cant("\82»\82ê\82ð%s\82±\82Æ\82Í\82Å\82«\82È\82¢\81I", jverb);
3940             return (struct obj *) 0;
3941         }
3942     return otmp;
3943 }
3944
3945 /* Side effects of vomiting */
3946 /* added nomul (MRS) - it makes sense, you're too busy being sick! */
3947 void
3948 vomit() /* A good idea from David Neves */
3949 {
3950     if (cantvomit(youmonst.data)) {
3951         /* doesn't cure food poisoning; message assumes that we aren't
3952            dealing with some esoteric body_part() */
3953 /*JP
3954         Your("jaw gapes convulsively.");
3955 */
3956         Your("\82 \82²\82Í\94­\8dì\93I\82É\91å\82«\82­\8aJ\82¢\82½\81D");
3957     } else {
3958         make_sick(0L, (char *) 0, TRUE, SICK_VOMITABLE);
3959         /* if not enough in stomach to actually vomit then dry heave;
3960            vomiting_dialog() gives a vomit message when its countdown
3961            reaches 0, but only if u.uhs < FAINTING (and !cantvomit()) */
3962         if (u.uhs >= FAINTING)
3963             Your("%s heaves convulsively!", body_part(STOMACH));
3964     }
3965
3966     /* nomul()/You_can_move_again used to be unconditional, which was
3967        viable while eating but not for Vomiting countdown where hero might
3968        be immobilized for some other reason at the time vomit() is called */
3969     if (multi >= -2) {
3970         nomul(-2);
3971 /*JP
3972     multi_reason = "vomiting";
3973 */
3974     multi_reason = "\9aq\93f\82µ\82Ä\82¢\82é\8dÅ\92\86\82É";
3975         nomovemsg = You_can_move_again;
3976     }
3977 }
3978
3979 int
3980 eaten_stat(base, obj)
3981 int base;
3982 struct obj *obj;
3983 {
3984     long uneaten_amt, full_amount;
3985
3986     /* get full_amount first; obj_nutrition() might modify obj->oeaten */
3987     full_amount = (long) obj_nutrition(obj);
3988     uneaten_amt = (long) obj->oeaten;
3989     if (uneaten_amt > full_amount) {
3990         impossible(
3991           "partly eaten food (%ld) more nutritious than untouched food (%ld)",
3992                    uneaten_amt, full_amount);
3993         uneaten_amt = full_amount;
3994     }
3995
3996     base = (int) (full_amount ? (long) base * uneaten_amt / full_amount : 0L);
3997     return (base < 1) ? 1 : base;
3998 }
3999
4000 /* reduce obj's oeaten field, making sure it never hits or passes 0 */
4001 void
4002 consume_oeaten(obj, amt)
4003 struct obj *obj;
4004 int amt;
4005 {
4006     /*
4007      * This is a hack to try to squelch several long standing mystery
4008      * food bugs.  A better solution would be to rewrite the entire
4009      * victual handling mechanism from scratch using a less complex
4010      * model.  Alternatively, this routine could call done_eating()
4011      * or food_disappears() but its callers would need revisions to
4012      * cope with context.victual.piece unexpectedly going away.
4013      *
4014      * Multi-turn eating operates by setting the food's oeaten field
4015      * to its full nutritional value and then running a counter which
4016      * independently keeps track of whether there is any food left.
4017      * The oeaten field can reach exactly zero on the last turn, and
4018      * the object isn't removed from inventory until the next turn
4019      * when the "you finish eating" message gets delivered, so the
4020      * food would be restored to the status of untouched during that
4021      * interval.  This resulted in unexpected encumbrance messages
4022      * at the end of a meal (if near enough to a threshold) and would
4023      * yield full food if there was an interruption on the critical
4024      * turn.  Also, there have been reports over the years of food
4025      * becoming massively heavy or producing unlimited satiation;
4026      * this would occur if reducing oeaten via subtraction attempted
4027      * to drop it below 0 since its unsigned type would produce a
4028      * huge positive value instead.  So far, no one has figured out
4029      * _why_ that inappropriate subtraction might sometimes happen.
4030      */
4031
4032     if (amt > 0) {
4033         /* bit shift to divide the remaining amount of food */
4034         obj->oeaten >>= amt;
4035     } else {
4036         /* simple decrement; value is negative so we actually add it */
4037         if ((int) obj->oeaten > -amt)
4038             obj->oeaten += amt;
4039         else
4040             obj->oeaten = 0;
4041     }
4042
4043     if (obj->oeaten == 0) {
4044         if (obj == context.victual.piece) /* always true unless wishing... */
4045             context.victual.reqtime =
4046                 context.victual.usedtime; /* no bites left */
4047         obj->oeaten = 1; /* smallest possible positive value */
4048     }
4049 }
4050
4051 /* called when eatfood occupation has been interrupted,
4052    or in the case of theft, is about to be interrupted */
4053 boolean
4054 maybe_finished_meal(stopping)
4055 boolean stopping;
4056 {
4057     /* in case consume_oeaten() has decided that the food is all gone */
4058     if (occupation == eatfood
4059         && context.victual.usedtime >= context.victual.reqtime) {
4060         if (stopping)
4061             occupation = 0; /* for do_reset_eat */
4062         (void) eatfood();   /* calls done_eating() to use up
4063                                context.victual.piece */
4064         return TRUE;
4065     }
4066     return FALSE;
4067 }
4068
4069 /* Tin of <something> to the rescue?  Decide whether current occupation
4070    is an attempt to eat a tin of something capable of saving hero's life.
4071    We don't care about consumption of non-tinned food here because special
4072    effects there take place on first bite rather than at end of occupation.
4073    [Popeye the Sailor gets out of trouble by eating tins of spinach. :-] */
4074 boolean
4075 Popeye(threat)
4076 int threat;
4077 {
4078     struct obj *otin;
4079     int mndx;
4080
4081     if (occupation != opentin)
4082         return FALSE;
4083     otin = context.tin.tin;
4084     /* make sure hero still has access to tin */
4085     if (!carried(otin)
4086         && (!obj_here(otin, u.ux, u.uy) || !can_reach_floor(TRUE)))
4087         return FALSE;
4088     /* unknown tin is assumed to be helpful */
4089     if (!otin->known)
4090         return TRUE;
4091     /* known tin is helpful if it will stop life-threatening problem */
4092     mndx = otin->corpsenm;
4093     switch (threat) {
4094     /* note: not used; hunger code bypasses stop_occupation() when eating */
4095     case HUNGER:
4096         return (boolean) (mndx != NON_PM || otin->spe == 1);
4097     /* flesh from lizards and acidic critters stops petrification */
4098     case STONED:
4099         return (boolean) (mndx >= LOW_PM
4100                           && (mndx == PM_LIZARD || acidic(&mons[mndx])));
4101     /* no tins can cure these (yet?) */
4102     case SLIMED:
4103     case SICK:
4104     case VOMITING:
4105         break;
4106     default:
4107         break;
4108     }
4109     return FALSE;
4110 }
4111
4112 /*eat.c*/