OSDN Git Service

add translation
[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-2016            */
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     char buf[BUFSZ], foodsmell[BUFSZ],
2836          it_or_they[QBUFSZ], eat_it_anyway[QBUFSZ];
2837     boolean cadaver = (otmp->otyp == CORPSE || otmp->globby),
2838             stoneorslime = FALSE;
2839     int material = objects[otmp->otyp].oc_material, mnum = otmp->corpsenm;
2840     long rotted = 0L;
2841
2842 #if 0 /*JP*/
2843     Strcpy(foodsmell, Tobjnam(otmp, "smell"));
2844 #else
2845     Strcpy(foodsmell, xname(otmp));
2846 #endif
2847 #if 0 /*JP*/
2848     Strcpy(it_or_they, (otmp->quan == 1L) ? "it" : "they");
2849 #endif
2850 #if 0 /*JP*/
2851     Sprintf(eat_it_anyway, "Eat %s anyway?",
2852             (otmp->quan == 1L) ? "it" : "one");
2853 #else
2854     Strcpy(eat_it_anyway, "\82»\82ê\82Å\82à\90H\82×\82é\81H");
2855 #endif
2856
2857     if (cadaver || otmp->otyp == EGG || otmp->otyp == TIN) {
2858         /* These checks must match those in eatcorpse() */
2859         stoneorslime = (flesh_petrifies(&mons[mnum]) && !Stone_resistance
2860                         && !poly_when_stoned(youmonst.data));
2861
2862         if (mnum == PM_GREEN_SLIME || otmp->otyp == GLOB_OF_GREEN_SLIME)
2863             stoneorslime = (!Unchanging && !slimeproof(youmonst.data));
2864
2865         if (cadaver && !nonrotting_corpse(mnum)) {
2866             long age = peek_at_iced_corpse_age(otmp);
2867
2868             /* worst case rather than random
2869                in this calculation to force prompt */
2870             rotted = (monstermoves - age) / (10L + 0 /* was rn2(20) */);
2871             if (otmp->cursed)
2872                 rotted += 2L;
2873             else if (otmp->blessed)
2874                 rotted -= 2L;
2875         }
2876     }
2877
2878     /*
2879      * These problems with food should be checked in
2880      * order from most detrimental to least detrimental.
2881      */
2882     if (cadaver && mnum != PM_ACID_BLOB && rotted > 5L && !Sick_resistance) {
2883         /* Tainted meat */
2884 #if 0 /*JP*/
2885         Sprintf(buf, "%s like %s could be tainted! %s", foodsmell, it_or_they,
2886                 eat_it_anyway);
2887 #else
2888         Sprintf(buf, "%s\82Í\89\98\90õ\82³\82ê\82Ä\82¢\82é\82æ\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81I%s",
2889                 foodsmell, eat_it_anyway);
2890 #endif
2891         if (yn_function(buf, ynchars, 'n') == 'n')
2892             return 1;
2893         else
2894             return 2;
2895     }
2896     if (stoneorslime) {
2897 #if 0 /*JP*/
2898         Sprintf(buf, "%s like %s could be something very dangerous! %s",
2899                 foodsmell, it_or_they, eat_it_anyway);
2900 #else
2901         Sprintf(buf, "%s\82Í\82È\82ñ\82¾\82©\82·\82²\82­\8aë\8c¯\82»\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81I%s",
2902                 foodsmell, eat_it_anyway);
2903 #endif
2904         if (yn_function(buf, ynchars, 'n') == 'n')
2905             return 1;
2906         else
2907             return 2;
2908     }
2909     if (otmp->orotten || (cadaver && rotted > 3L)) {
2910         /* Rotten */
2911 #if 0 /*JP*/
2912         Sprintf(buf, "%s like %s could be rotten! %s", foodsmell, it_or_they,
2913                 eat_it_anyway);
2914 #else
2915         Sprintf(buf, "%s\82Í\95\85\82Á\82½\82æ\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81I%s",
2916                 foodsmell, eat_it_anyway);
2917 #endif
2918         if (yn_function(buf, ynchars, 'n') == 'n')
2919             return 1;
2920         else
2921             return 2;
2922     }
2923     if (cadaver && poisonous(&mons[mnum]) && !Poison_resistance) {
2924         /* poisonous */
2925 #if 0 /*JP*/
2926         Sprintf(buf, "%s like %s might be poisonous! %s", foodsmell,
2927                 it_or_they, eat_it_anyway);
2928 #else
2929         Sprintf(buf, "%s\82Í\93Å\82ð\82à\82Á\82Ä\82¢\82»\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81I%s",
2930                 foodsmell, eat_it_anyway);
2931 #endif
2932         if (yn_function(buf, ynchars, 'n') == 'n')
2933             return 1;
2934         else
2935             return 2;
2936     }
2937     if (otmp->otyp == APPLE && otmp->cursed && !Sleep_resistance) {
2938         /* causes sleep, for long enough to be dangerous */
2939 #if 0 /*JP*/
2940         Sprintf(buf, "%s like %s might have been poisoned. %s", foodsmell,
2941                 it_or_they, eat_it_anyway);
2942 #else
2943         Sprintf(buf, "%s\82Í\93Å\82ª\93ü\82ê\82ç\82ê\82Ä\82¢\82»\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81I%s",
2944                 foodsmell, eat_it_anyway);
2945 #endif
2946         return (yn_function(buf, ynchars, 'n') == 'n') ? 1 : 2;
2947     }
2948     if (cadaver && !vegetarian(&mons[mnum]) && !u.uconduct.unvegetarian
2949         && Role_if(PM_MONK)) {
2950 /*JP
2951         Sprintf(buf, "%s unhealthy. %s", foodsmell, eat_it_anyway);
2952 */
2953         Sprintf(buf, "%s\82Í\8c\92\8dN\82É\88«\82»\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81D%s", foodsmell, eat_it_anyway);
2954         if (yn_function(buf, ynchars, 'n') == 'n')
2955             return 1;
2956         else
2957             return 2;
2958     }
2959     if (cadaver && acidic(&mons[mnum]) && !Acid_resistance) {
2960 /*JP
2961         Sprintf(buf, "%s rather acidic. %s", foodsmell, eat_it_anyway);
2962 */
2963         Sprintf(buf, "%s\82Í\8f­\82µ\8e_\82Á\82Ï\82»\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81D%s", foodsmell, eat_it_anyway);
2964         if (yn_function(buf, ynchars, 'n') == 'n')
2965             return 1;
2966         else
2967             return 2;
2968     }
2969     if (Upolyd && u.umonnum == PM_RUST_MONSTER && is_metallic(otmp)
2970         && otmp->oerodeproof) {
2971 #if 0 /*JP*/
2972         Sprintf(buf, "%s disgusting to you right now. %s", foodsmell,
2973                 eat_it_anyway);
2974 #else
2975         Sprintf(buf, "%s\82Í\8bC\95ª\82ª\88«\82­\82È\82é\82É\82¨\82¢\82ª\82·\82é\81D%s", foodsmell,
2976                 eat_it_anyway);
2977 #endif
2978         if (yn_function(buf, ynchars, 'n') == 'n')
2979             return 1;
2980         else
2981             return 2;
2982     }
2983
2984     /*
2985      * Breaks conduct, but otherwise safe.
2986      */
2987     if (!u.uconduct.unvegan
2988         && ((material == LEATHER || material == BONE
2989              || material == DRAGON_HIDE || material == WAX)
2990             || (cadaver && !vegan(&mons[mnum])))) {
2991 #if 0 /*JP*/
2992         Sprintf(buf, "%s foul and unfamiliar to you. %s", foodsmell,
2993                 eat_it_anyway);
2994 #else
2995         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,
2996                 eat_it_anyway);
2997 #endif
2998         if (yn_function(buf, ynchars, 'n') == 'n')
2999             return 1;
3000         else
3001             return 2;
3002     }
3003     if (!u.uconduct.unvegetarian
3004         && ((material == LEATHER || material == BONE
3005              || material == DRAGON_HIDE)
3006             || (cadaver && !vegetarian(&mons[mnum])))) {
3007 /*JP
3008         Sprintf(buf, "%s unfamiliar to you. %s", foodsmell, eat_it_anyway);
3009 */
3010         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);
3011         if (yn_function(buf, ynchars, 'n') == 'n')
3012             return 1;
3013         else
3014             return 2;
3015     }
3016
3017     if (cadaver && mnum != PM_ACID_BLOB && rotted > 5L && Sick_resistance) {
3018         /* Tainted meat with Sick_resistance */
3019 #if 0 /*JP*/
3020         Sprintf(buf, "%s like %s could be tainted! %s", foodsmell, it_or_they,
3021                 eat_it_anyway);
3022 #else
3023         Sprintf(buf, "%s\82Í\89\98\90õ\82³\82ê\82Ä\82¢\82é\82æ\82¤\82È\82É\82¨\82¢\82ª\82·\82é\81I%s", foodsmell,
3024                 eat_it_anyway);
3025 #endif
3026         if (yn_function(buf, ynchars, 'n') == 'n')
3027             return 1;
3028         else
3029             return 2;
3030     }
3031     return 0;
3032 }
3033
3034 /* 'e' command */
3035 int
3036 doeat()
3037 {
3038     struct obj *otmp;
3039     int basenutrit; /* nutrition of full item */
3040     boolean dont_start = FALSE, nodelicious = FALSE;
3041
3042     if (Strangled) {
3043 /*JP
3044         pline("If you can't breathe air, how can you consume solids?");
3045 */
3046         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");
3047         return 0;
3048     }
3049 /*JP
3050     if (!(otmp = floorfood("eat", 0)))
3051 */
3052     if (!(otmp = floorfood("\90H\82×\82é", 0)))
3053         return 0;
3054     if (check_capacity((char *) 0))
3055         return 0;
3056
3057     if (u.uedibility) {
3058         int res = edibility_prompts(otmp);
3059
3060         if (res) {
3061 #if 0 /*JP*/
3062             Your(
3063                "%s stops tingling and your sense of smell returns to normal.",
3064                  body_part(NOSE));
3065 #else
3066             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",
3067                  body_part(NOSE));
3068 #endif
3069             u.uedibility = 0;
3070             if (res == 1)
3071                 return 0;
3072         }
3073     }
3074
3075     /* We have to make non-foods take 1 move to eat, unless we want to
3076      * do ridiculous amounts of coding to deal with partly eaten plate
3077      * mails, players who polymorph back to human in the middle of their
3078      * metallic meal, etc....
3079      */
3080     if (!is_edible(otmp)) {
3081 /*JP
3082         You("cannot eat that!");
3083 */
3084         You("\82»\82ê\82ð\90H\82×\82ç\82ê\82È\82¢\81I");
3085         return 0;
3086     } else if ((otmp->owornmask & (W_ARMOR | W_TOOL | W_AMUL | W_SADDLE))
3087                != 0) {
3088         /* let them eat rings */
3089 /*JP
3090         You_cant("eat %s you're wearing.", something);
3091 */
3092         You("\90g\82É\82Â\82¯\82Ä\82¢\82é\8aÔ\82Í\90H\82×\82ê\82È\82¢\81D");
3093         return 0;
3094     } else if (!(carried(otmp) ? retouch_object(&otmp, FALSE)
3095                                : touch_artifact(otmp, &youmonst))) {
3096         return 1; /* got blasted so use a turn */
3097     }
3098     if (is_metallic(otmp) && u.umonnum == PM_RUST_MONSTER
3099         && otmp->oerodeproof) {
3100         otmp->rknown = TRUE;
3101         if (otmp->quan > 1L) {
3102             if (!carried(otmp))
3103                 (void) splitobj(otmp, otmp->quan - 1L);
3104             else
3105                 otmp = splitobj(otmp, 1L);
3106         }
3107 /*JP
3108         pline("Ulch - that %s was rustproofed!", xname(otmp));
3109 */
3110         pline("\83E\83Q\83F\81[\81I%s\82Í\96h\8eK\82³\82ê\82Ä\82¢\82é\81I", xname(otmp));
3111         /* The regurgitated object's rustproofing is gone now */
3112         otmp->oerodeproof = 0;
3113         make_stunned((HStun & TIMEOUT) + (long) rn2(10), TRUE);
3114         /*
3115          * We don't expect rust monsters to be wielding welded weapons
3116          * or wearing cursed rings which were rustproofed, but guard
3117          * against the possibility just in case.
3118          */
3119         if (welded(otmp) || (otmp->cursed && (otmp->owornmask & W_RING))) {
3120             otmp->bknown = 1; /* for ring; welded() does this for weapon */
3121 /*JP
3122             You("spit out %s.", the(xname(otmp)));
3123 */
3124             You("%s\82ð\93f\82«\8fo\82µ\82½\81D", xname(otmp));
3125         } else {
3126 #if 0 /*JP*/
3127             You("spit %s out onto the %s.", the(xname(otmp)),
3128                 surface(u.ux, u.uy));
3129 #else
3130             You("%s\82ð%s\82É\93f\82«\8fo\82µ\82½\81D", the(xname(otmp)),
3131                 surface(u.ux, u.uy));
3132 #endif
3133             if (carried(otmp)) {
3134                 /* no need to check for leash in use; it's not metallic */
3135                 if (otmp->owornmask)
3136                     remove_worn_item(otmp, FALSE);
3137                 freeinv(otmp);
3138                 dropy(otmp);
3139             }
3140             stackobj(otmp);
3141         }
3142         return 1;
3143     }
3144     /* KMH -- Slow digestion is... indigestible */
3145     if (otmp->otyp == RIN_SLOW_DIGESTION) {
3146 /*JP
3147         pline("This ring is indigestible!");
3148 */
3149         pline("\82±\82Ì\8ew\97Ö\82Í\8fÁ\89»\82µ\82É\82­\82¢\81I");
3150         (void) rottenfood(otmp);
3151         if (otmp->dknown && !objects[otmp->otyp].oc_name_known
3152             && !objects[otmp->otyp].oc_uname)
3153             docall(otmp);
3154         return 1;
3155     }
3156     if (otmp->oclass != FOOD_CLASS) {
3157         int material;
3158
3159         context.victual.reqtime = 1;
3160         context.victual.piece = otmp;
3161         context.victual.o_id = otmp->o_id;
3162         /* Don't split it, we don't need to if it's 1 move */
3163         context.victual.usedtime = 0;
3164         context.victual.canchoke = (u.uhs == SATIATED);
3165         /* Note: gold weighs 1 pt. for each 1000 pieces (see
3166            pickup.c) so gold and non-gold is consistent. */
3167         if (otmp->oclass == COIN_CLASS)
3168             basenutrit = ((otmp->quan > 200000L)
3169                              ? 2000
3170                              : (int) (otmp->quan / 100L));
3171         else if (otmp->oclass == BALL_CLASS || otmp->oclass == CHAIN_CLASS)
3172             basenutrit = weight(otmp);
3173         /* oc_nutrition is usually weight anyway */
3174         else
3175             basenutrit = objects[otmp->otyp].oc_nutrition;
3176 #ifdef MAIL
3177         if (otmp->otyp == SCR_MAIL) {
3178             basenutrit = 0;
3179             nodelicious = TRUE;
3180         }
3181 #endif
3182         context.victual.nmod = basenutrit;
3183         context.victual.eating = TRUE; /* needed for lesshungry() */
3184
3185         material = objects[otmp->otyp].oc_material;
3186         if (material == LEATHER || material == BONE
3187             || material == DRAGON_HIDE) {
3188             u.uconduct.unvegan++;
3189             violated_vegetarian();
3190         } else if (material == WAX)
3191             u.uconduct.unvegan++;
3192         u.uconduct.food++;
3193
3194         if (otmp->cursed) {
3195             (void) rottenfood(otmp);
3196             nodelicious = TRUE;
3197         } else if (objects[otmp->otyp].oc_material == PAPER)
3198             nodelicious = TRUE;
3199
3200         if (otmp->oclass == WEAPON_CLASS && otmp->opoisoned) {
3201 /*JP
3202             pline("Ecch - that must have been poisonous!");
3203 */
3204             pline("\83E\83Q\83F\81[\81C\97L\93Å\82¾\82Á\82½\82É\88á\82¢\82È\82¢\81I");  
3205             if (!Poison_resistance) {
3206                 losestr(rnd(4));
3207 #if 0 /*JP*/
3208                 losehp(rnd(15), xname(otmp), KILLED_BY_AN);
3209 #else
3210                 {
3211                     char jbuf[BUFSZ];
3212                     Sprintf(jbuf, "%s\82Å", xname(otmp));
3213                     losehp(rnd(15), jbuf, KILLED_BY_AN);
3214                 }
3215 #endif
3216             } else
3217 /*JP
3218                 You("seem unaffected by the poison.");
3219 */
3220                 You("\93Å\82Ì\89e\8b¿\82ð\8eó\82¯\82È\82¢\82æ\82¤\82¾\81D");
3221         } else if (!nodelicious) {
3222 #if 0 /*JP*/
3223             pline("%s%s is delicious!",
3224                   (obj_is_pname(otmp)
3225                    && otmp->oartifact < ART_ORB_OF_DETECTION)
3226                       ? ""
3227                       : "This ",
3228                   (otmp->oclass == COIN_CLASS)
3229                       ? foodword(otmp)
3230                       : singular(otmp, xname));
3231 #else
3232             pline("\82±\82Ì%s\82Í\8e|\82¢\81I",
3233                   otmp->oclass == COIN_CLASS
3234                       ? foodword(otmp)
3235                       : singular(otmp, xname));
3236 #endif
3237         }
3238         eatspecial();
3239         return 1;
3240     }
3241
3242     if (otmp == context.victual.piece) {
3243         /* If they weren't able to choke, they don't suddenly become able to
3244          * choke just because they were interrupted.  On the other hand, if
3245          * they were able to choke before, if they lost food it's possible
3246          * they shouldn't be able to choke now.
3247          */
3248         if (u.uhs != SATIATED)
3249             context.victual.canchoke = FALSE;
3250         context.victual.o_id = 0;
3251         context.victual.piece = touchfood(otmp);
3252         if (context.victual.piece)
3253             context.victual.o_id = context.victual.piece->o_id;
3254 /*JP
3255         You("resume your meal.");
3256 */
3257         You("\90H\8e\96\82ð\8dÄ\8aJ\82µ\82½\81D");
3258         start_eating(context.victual.piece);
3259         return 1;
3260     }
3261
3262     /* nothing in progress - so try to find something. */
3263     /* tins are a special case */
3264     /* tins must also check conduct separately in case they're discarded */
3265     if (otmp->otyp == TIN) {
3266         start_tin(otmp);
3267         return 1;
3268     }
3269
3270     /* KMH, conduct */
3271     u.uconduct.food++;
3272
3273     context.victual.o_id = 0;
3274     context.victual.piece = otmp = touchfood(otmp);
3275     if (context.victual.piece)
3276         context.victual.o_id = context.victual.piece->o_id;
3277     context.victual.usedtime = 0;
3278
3279     /* Now we need to calculate delay and nutritional info.
3280      * The base nutrition calculated here and in eatcorpse() accounts
3281      * for normal vs. rotten food.  The reqtime and nutrit values are
3282      * then adjusted in accordance with the amount of food left.
3283      */
3284     if (otmp->otyp == CORPSE || otmp->globby) {
3285         int tmp = eatcorpse(otmp);
3286
3287         if (tmp == 2) {
3288             /* used up */
3289             context.victual.piece = (struct obj *) 0;
3290             context.victual.o_id = 0;
3291             return 1;
3292         } else if (tmp)
3293             dont_start = TRUE;
3294         /* if not used up, eatcorpse sets up reqtime and may modify oeaten */
3295     } else {
3296         /* No checks for WAX, LEATHER, BONE, DRAGON_HIDE.  These are
3297          * all handled in the != FOOD_CLASS case, above.
3298          */
3299         switch (objects[otmp->otyp].oc_material) {
3300         case FLESH:
3301             u.uconduct.unvegan++;
3302             if (otmp->otyp != EGG) {
3303                 violated_vegetarian();
3304             }
3305             break;
3306
3307         default:
3308             if (otmp->otyp == PANCAKE || otmp->otyp == FORTUNE_COOKIE /*eggs*/
3309                 || otmp->otyp == CREAM_PIE || otmp->otyp == CANDY_BAR /*milk*/
3310                 || otmp->otyp == LUMP_OF_ROYAL_JELLY)
3311                 u.uconduct.unvegan++;
3312             break;
3313         }
3314
3315         context.victual.reqtime = objects[otmp->otyp].oc_delay;
3316         if (otmp->otyp != FORTUNE_COOKIE
3317             && (otmp->cursed || (!nonrotting_food(otmp->otyp)
3318                                  && (monstermoves - otmp->age)
3319                                         > (otmp->blessed ? 50L : 30L)
3320                                  && (otmp->orotten || !rn2(7))))) {
3321             if (rottenfood(otmp)) {
3322                 otmp->orotten = TRUE;
3323                 dont_start = TRUE;
3324             }
3325             consume_oeaten(otmp, 1); /* oeaten >>= 1 */
3326         } else
3327             fprefx(otmp);
3328     }
3329
3330     /* re-calc the nutrition */
3331     basenutrit = (int) obj_nutrition(otmp);
3332
3333     debugpline3(
3334      "before rounddiv: victual.reqtime == %d, oeaten == %d, basenutrit == %d",
3335                 context.victual.reqtime, otmp->oeaten, basenutrit);
3336
3337     context.victual.reqtime = (basenutrit == 0) ? 0
3338         : rounddiv(context.victual.reqtime * (long) otmp->oeaten, basenutrit);
3339
3340     debugpline1("after rounddiv: victual.reqtime == %d",
3341                 context.victual.reqtime);
3342     /*
3343      * calculate the modulo value (nutrit. units per round eating)
3344      * note: this isn't exact - you actually lose a little nutrition due
3345      *       to this method.
3346      * TODO: add in a "remainder" value to be given at the end of the meal.
3347      */
3348     if (context.victual.reqtime == 0 || otmp->oeaten == 0)
3349         /* possible if most has been eaten before */
3350         context.victual.nmod = 0;
3351     else if ((int) otmp->oeaten >= context.victual.reqtime)
3352         context.victual.nmod = -((int) otmp->oeaten
3353                                  / context.victual.reqtime);
3354     else
3355         context.victual.nmod = context.victual.reqtime % otmp->oeaten;
3356     context.victual.canchoke = (u.uhs == SATIATED);
3357
3358     if (!dont_start)
3359         start_eating(otmp);
3360     return 1;
3361 }
3362
3363 int
3364 use_tin_opener(obj)
3365 struct obj *obj;
3366 {
3367     struct obj *otmp;
3368     int res = 0;
3369
3370     if (!carrying(TIN)) {
3371 /*JP
3372         You("have no tin to open.");
3373 */
3374         You("\8aÊ\82ð\8e\9d\82Á\82Ä\82¢\82È\82¢\81D");
3375         return 0;
3376     }
3377
3378     if (obj != uwep) {
3379         if (obj->cursed && obj->bknown) {
3380             char qbuf[QBUFSZ];
3381
3382 #if 0 /*JP*/
3383             if (ynq(safe_qbuf(qbuf, "Really wield ", "?",
3384                               obj, doname, thesimpleoname, "that")) != 'y')
3385 #else
3386             if (ynq(safe_qbuf(qbuf, "\96{\93\96\82É", "\82ð\91\95\94õ\82·\82é\81H",
3387                               obj, doname, thesimpleoname, "\82»\82ê")) != 'y')
3388 #endif
3389                 return 0;
3390         }
3391         if (!wield_tool(obj, "use"))
3392             return 0;
3393         res = 1;
3394     }
3395
3396     otmp = getobj(comestibles, "open");
3397     if (!otmp)
3398         return res;
3399
3400     start_tin(otmp);
3401     return 1;
3402 }
3403
3404 /* Take a single bite from a piece of food, checking for choking and
3405  * modifying usedtime.  Returns 1 if they choked and survived, 0 otherwise.
3406  */
3407 STATIC_OVL int
3408 bite()
3409 {
3410     if (context.victual.canchoke && u.uhunger >= 2000) {
3411         choke(context.victual.piece);
3412         return 1;
3413     }
3414     if (context.victual.doreset) {
3415         do_reset_eat();
3416         return 0;
3417     }
3418     force_save_hs = TRUE;
3419     if (context.victual.nmod < 0) {
3420         lesshungry(-context.victual.nmod);
3421         consume_oeaten(context.victual.piece,
3422                        context.victual.nmod); /* -= -nmod */
3423     } else if (context.victual.nmod > 0
3424                && (context.victual.usedtime % context.victual.nmod)) {
3425         lesshungry(1);
3426         consume_oeaten(context.victual.piece, -1); /* -= 1 */
3427     }
3428     force_save_hs = FALSE;
3429     recalc_wt();
3430     return 0;
3431 }
3432
3433 /* as time goes by - called by moveloop(every move) & domove(melee attack) */
3434 void
3435 gethungry()
3436 {
3437     if (u.uinvulnerable)
3438         return; /* you don't feel hungrier */
3439
3440     /* being polymorphed into a creature which doesn't eat prevents
3441        this first uhunger decrement, but to stay in such form the hero
3442        will need to wear an Amulet of Unchanging so still burn a small
3443        amount of nutrition in the 'moves % 20' ring/amulet check below */
3444     if ((!Unaware || !rn2(10)) /* slow metabolic rate while asleep */
3445         && (carnivorous(youmonst.data)
3446             || herbivorous(youmonst.data)
3447             || metallivorous(youmonst.data))
3448         && !Slow_digestion)
3449         u.uhunger--; /* ordinary food consumption */
3450
3451     if (moves % 2) { /* odd turns */
3452         /* Regeneration uses up food, unless due to an artifact */
3453         if ((HRegeneration & ~FROMFORM)
3454             || (ERegeneration & ~(W_ARTI | W_WEP)))
3455             u.uhunger--;
3456         if (near_capacity() > SLT_ENCUMBER)
3457             u.uhunger--;
3458     } else { /* even turns */
3459         if (Hunger)
3460             u.uhunger--;
3461         /* Conflict uses up food too */
3462         if (HConflict || (EConflict & (~W_ARTI)))
3463             u.uhunger--;
3464         /* +0 charged rings don't do anything, so don't affect hunger.
3465            Slow digestion cancels move hunger but still causes ring hunger. */
3466         switch ((int) (moves % 20)) { /* note: use even cases only */
3467         case 4:
3468             if (uleft && (uleft->spe || !objects[uleft->otyp].oc_charged))
3469                 u.uhunger--;
3470             break;
3471         case 8:
3472             if (uamul)
3473                 u.uhunger--;
3474             break;
3475         case 12:
3476             if (uright && (uright->spe || !objects[uright->otyp].oc_charged))
3477                 u.uhunger--;
3478             break;
3479         case 16:
3480             if (u.uhave.amulet)
3481                 u.uhunger--;
3482             break;
3483         default:
3484             break;
3485         }
3486     }
3487     newuhs(TRUE);
3488 }
3489
3490 /* called after vomiting and after performing feats of magic */
3491 void
3492 morehungry(num)
3493 int num;
3494 {
3495     u.uhunger -= num;
3496     newuhs(TRUE);
3497 }
3498
3499 /* called after eating (and after drinking fruit juice) */
3500 void
3501 lesshungry(num)
3502 int num;
3503 {
3504     /* See comments in newuhs() for discussion on force_save_hs */
3505     boolean iseating = (occupation == eatfood) || force_save_hs;
3506
3507     debugpline1("lesshungry(%d)", num);
3508     u.uhunger += num;
3509     if (u.uhunger >= 2000) {
3510         if (!iseating || context.victual.canchoke) {
3511             if (iseating) {
3512                 choke(context.victual.piece);
3513                 reset_eat();
3514             } else
3515                 choke(occupation == opentin ? context.tin.tin
3516                                             : (struct obj *) 0);
3517             /* no reset_eat() */
3518         }
3519     } else {
3520         /* Have lesshungry() report when you're nearly full so all eating
3521          * warns when you're about to choke.
3522          */
3523         if (u.uhunger >= 1500) {
3524             if (!context.victual.eating
3525                 || (context.victual.eating && !context.victual.fullwarn)) {
3526 /*JP
3527                 pline("You're having a hard time getting all of it down.");
3528 */
3529                 pline("\91S\82Ä\82ð\88ù\82Ý\82±\82Þ\82É\82Í\8e\9e\8aÔ\82ª\82©\82©\82é\81D");
3530 /*JP
3531                 nomovemsg = "You're finally finished.";
3532 */
3533                 nomovemsg = "\82â\82Á\82Æ\90H\82×\8fI\82¦\82½\81D";
3534                 if (!context.victual.eating) {
3535                     multi = -2;
3536                 } else {
3537                     context.victual.fullwarn = TRUE;
3538                     if (context.victual.canchoke
3539                         && context.victual.reqtime > 1) {
3540                         /* a one-gulp food will not survive a stop */
3541 /*JP
3542                         if (yn_function("Continue eating?", ynchars, 'n')
3543 */
3544                         if (yn_function("\90H\82×\91±\82¯\82Ü\82·\82©\81H", ynchars, 'n')
3545                             != 'y') {
3546                             reset_eat();
3547                             nomovemsg = (char *) 0;
3548                         }
3549                     }
3550                 }
3551             }
3552         }
3553     }
3554     newuhs(FALSE);
3555 }
3556
3557 STATIC_PTR
3558 int
3559 unfaint(VOID_ARGS)
3560 {
3561     (void) Hear_again();
3562     if (u.uhs > FAINTING)
3563         u.uhs = FAINTING;
3564     stop_occupation();
3565     context.botl = 1;
3566     return 0;
3567 }
3568
3569 boolean
3570 is_fainted()
3571 {
3572     return (boolean) (u.uhs == FAINTED);
3573 }
3574
3575 /* call when a faint must be prematurely terminated */
3576 void
3577 reset_faint()
3578 {
3579     if (afternmv == unfaint)
3580 /*JP
3581         unmul("You revive.");
3582 */
3583         unmul("\82 \82È\82½\82Í\8bC\82ª\82Â\82¢\82½\81D");
3584 }
3585
3586 /* compute and comment on your (new?) hunger status */
3587 void
3588 newuhs(incr)
3589 boolean incr;
3590 {
3591     unsigned newhs;
3592     static unsigned save_hs;
3593     static boolean saved_hs = FALSE;
3594     int h = u.uhunger;
3595
3596     newhs = (h > 1000)
3597                 ? SATIATED
3598                 : (h > 150) ? NOT_HUNGRY
3599                             : (h > 50) ? HUNGRY : (h > 0) ? WEAK : FAINTING;
3600
3601     /* While you're eating, you may pass from WEAK to HUNGRY to NOT_HUNGRY.
3602      * This should not produce the message "you only feel hungry now";
3603      * that message should only appear if HUNGRY is an endpoint.  Therefore
3604      * we check to see if we're in the middle of eating.  If so, we save
3605      * the first hunger status, and at the end of eating we decide what
3606      * message to print based on the _entire_ meal, not on each little bit.
3607      */
3608     /* It is normally possible to check if you are in the middle of a meal
3609      * by checking occupation == eatfood, but there is one special case:
3610      * start_eating() can call bite() for your first bite before it
3611      * sets the occupation.
3612      * Anyone who wants to get that case to work _without_ an ugly static
3613      * force_save_hs variable, feel free.
3614      */
3615     /* Note: If you become a certain hunger status in the middle of the
3616      * meal, and still have that same status at the end of the meal,
3617      * this will incorrectly print the associated message at the end of
3618      * the meal instead of the middle.  Such a case is currently
3619      * impossible, but could become possible if a message for SATIATED
3620      * were added or if HUNGRY and WEAK were separated by a big enough
3621      * gap to fit two bites.
3622      */
3623     if (occupation == eatfood || force_save_hs) {
3624         if (!saved_hs) {
3625             save_hs = u.uhs;
3626             saved_hs = TRUE;
3627         }
3628         u.uhs = newhs;
3629         return;
3630     } else {
3631         if (saved_hs) {
3632             u.uhs = save_hs;
3633             saved_hs = FALSE;
3634         }
3635     }
3636
3637     if (newhs == FAINTING) {
3638         /* u,uhunger is likely to be negative at this point */
3639         int uhunger_div_by_10 = sgn(u.uhunger) * ((abs(u.uhunger) + 5) / 10);
3640
3641         if (is_fainted())
3642             newhs = FAINTED;
3643         if (u.uhs <= WEAK || rn2(20 - uhunger_div_by_10) >= 19) {
3644             if (!is_fainted() && multi >= 0 /* %% */) {
3645                 int duration = 10 - uhunger_div_by_10;
3646
3647                 /* stop what you're doing, then faint */
3648                 stop_occupation();
3649 /*JP
3650                 You("faint from lack of food.");
3651 */
3652                 You("\95 \82ª\8c¸\82Á\82Ä\93|\82ê\82½\81D");
3653                 incr_itimeout(&HDeaf, duration);
3654                 context.botl = TRUE;
3655                 nomul(-duration);
3656 /*JP
3657                 multi_reason = "fainted from lack of food";
3658 */
3659                 multi_reason = "\8bó\95 \82Å\91²\93|\82µ\82Ä\82¢\82é\8aÔ\82É";
3660 /*JP
3661                 nomovemsg = "You regain consciousness.";
3662 */
3663                 nomovemsg = "\82 \82È\82½\82Í\90³\8bC\82Ã\82¢\82½\81D";
3664                 afternmv = unfaint;
3665                 newhs = FAINTED;
3666                 if (!Levitation)
3667 /*JP
3668                     selftouch("Falling, you");
3669 */
3670                     selftouch("\97\8e\82¿\82È\82ª\82ç\81C\82 \82È\82½\82Í");
3671             }
3672
3673         /* this used to be -(200 + 20 * Con) but that was when being asleep
3674            suppressed per-turn uhunger decrement but being fainted didn't;
3675            now uhunger becomes more negative at a slower rate */
3676         } else if (u.uhunger < -(100 + 10 * (int) ACURR(A_CON))) {
3677             u.uhs = STARVED;
3678             context.botl = 1;
3679             bot();
3680 /*JP
3681             You("die from starvation.");
3682 */
3683             You("\89ì\8e\80\82µ\82½\81D");
3684             killer.format = KILLED_BY;
3685 /*JP
3686             Strcpy(killer.name, "starvation");
3687 */
3688             Strcpy(killer.name, "\90H\97¿\95s\91«\82Å\89ì\8e\80\82µ\82½");
3689             done(STARVING);
3690             /* if we return, we lifesaved, and that calls newuhs */
3691             return;
3692         }
3693     }
3694
3695     if (newhs != u.uhs) {
3696         if (newhs >= WEAK && u.uhs < WEAK) {
3697             /* this used to be losestr(1) which had the potential to
3698                be fatal (still handled below) by reducing HP if it
3699                tried to take base strength below minimum of 3 */
3700             ATEMP(A_STR) = -1; /* temporary loss overrides Fixed_abil */
3701             /* defer context.botl status update until after hunger message */
3702         } else if (newhs < WEAK && u.uhs >= WEAK) {
3703             /* this used to be losestr(-1) which could be abused by
3704                becoming weak while wearing ring of sustain ability,
3705                removing ring, eating to 'restore' strength which boosted
3706                strength by a point each time the cycle was performed;
3707                substituting "while polymorphed" for sustain ability and
3708                "rehumanize" for ring removal might have done that too */
3709             ATEMP(A_STR) = 0; /* repair of loss also overrides Fixed_abil */
3710             /* defer context.botl status update until after hunger message */
3711         }
3712
3713         switch (newhs) {
3714         case HUNGRY:
3715             if (Hallucination) {
3716 #if 0 /*JP:T*/
3717                 You((!incr) ? "now have a lesser case of the munchies."
3718                             : "are getting the munchies.");
3719 #else
3720                 if (!incr) {
3721                     You("\83n\83\89\83w\83\8a\82ª\8c¸\82Á\82½\81D");
3722                 } else {
3723                     pline("\83n\83\89\83w\83\8a\83w\83\8a\83n\83\89\81D");
3724                 }
3725 #endif
3726             } else
3727 /*JP
3728                 You((!incr) ? "only feel hungry now."
3729 */
3730                 You((!incr) ? "\92P\82É\95 \83y\83R\8fó\91Ô\82É\82È\82Á\82½\81D"
3731                             : (u.uhunger < 145)
3732 /*JP
3733                                   ? "feel hungry."
3734 */
3735                                   ? "\8bó\95 \8a´\82ð\8a´\82\82½\81D"
3736 /*JP
3737                                   : "are beginning to feel hungry.");
3738 */
3739                                   : "\8bó\95 \8a´\82ð\82¨\82Ú\82¦\82Í\82\82ß\82½\81D");
3740             if (incr && occupation
3741                 && (occupation != eatfood && occupation != opentin))
3742                 stop_occupation();
3743             context.travel = context.travel1 = context.mv = context.run = 0;
3744             break;
3745         case WEAK:
3746             if (Hallucination)
3747 /*JP
3748                 pline((!incr) ? "You still have the munchies."
3749 */
3750                 pline((!incr) ? "\83n\83\89\83w\83\8a\82ª\8c¸\82ç\82È\82¢\81D"
3751 /*JP
3752               : "The munchies are interfering with your motor capabilities.");
3753 */
3754               : "\83n\83\89\83w\83\8a\82ª\83\82\81[\83^\81[\90«\94\\82É\89e\8b¿\82ð\97^\82¦\82Ä\82¢\82é\81D");
3755             else if (incr && (Role_if(PM_WIZARD) || Race_if(PM_ELF)
3756                               || Role_if(PM_VALKYRIE)))
3757 /*JP
3758                 pline("%s needs food, badly!",
3759 */
3760                 pline("%s\82É\82Í\8e\8a\8b}\90H\97¿\82ª\95K\97v\82¾\81I",
3761                       (Role_if(PM_WIZARD) || Role_if(PM_VALKYRIE))
3762                           ? urole.name.m
3763 /*JP
3764                           : "Elf");
3765 */
3766                           : "\83G\83\8b\83t");
3767             else
3768                 You((!incr)
3769 /*JP
3770                         ? "feel weak now."
3771 */
3772                         ? "\90\8a\8eã\8fó\91Ô\82É\82È\82Á\82½\81D"
3773 /*JP
3774                         : (u.uhunger < 45) ? "feel weak."
3775 */
3776                         : (u.uhunger < 45) ? "\90\8a\8eã\82µ\82Ä\82«\82½\81D"
3777 /*JP
3778                                            : "are beginning to feel weak.");
3779 */
3780                                            : "\8eã\82­\82È\82Á\82Ä\82«\82½\82æ\82¤\82É\8a´\82\82½\81D");
3781             if (incr && occupation
3782                 && (occupation != eatfood && occupation != opentin))
3783                 stop_occupation();
3784             context.travel = context.travel1 = context.mv = context.run = 0;
3785             break;
3786         }
3787         u.uhs = newhs;
3788         context.botl = 1;
3789         bot();
3790         if ((Upolyd ? u.mh : u.uhp) < 1) {
3791 /*JP
3792             You("die from hunger and exhaustion.");
3793 */
3794             You("\8bó\95 \82Æ\90\8a\8eã\82Å\8e\80\82ñ\82¾\81D");
3795             killer.format = KILLED_BY;
3796 /*JP
3797             Strcpy(killer.name, "exhaustion");
3798 */
3799             Strcpy(killer.name, "\8bó\95 \82Æ\90\8a\8eã\82Å\8e\80\82ñ\82¾");
3800             done(STARVING);
3801             return;
3802         }
3803     }
3804 }
3805
3806 /* Returns an object representing food.
3807  * Object may be either on floor or in inventory.
3808  */
3809 /*JP CHECK: 3.4.3 \82Å\82Ì\8cÄ\82Ñ\8fo\82µ\8c³
3810 apply.c:1959:   if (!(corpse = floorfood("\8aÊ\8bl\82ß\82É\82·\82é", 2))) return;
3811 eat.c:2404:     if (!(otmp = floorfood("\90H\82×\82é", 0))) return 0;
3812 pray.c:1478:    if (!(otmp = floorfood("\95ù\82°\82é", 1))) return 0;
3813 */
3814 struct obj *
3815 floorfood(verb, corpsecheck)
3816 const char *verb;
3817 int corpsecheck; /* 0, no check, 1, corpses, 2, tinnable corpses */
3818 {
3819     register struct obj *otmp;
3820     char qbuf[QBUFSZ];
3821     char c;
3822 #if 0 /*JP*/
3823     boolean feeding = !strcmp(verb, "eat"),    /* corpsecheck==0 */
3824         offering = !strcmp(verb, "sacrifice"); /* corpsecheck==1 */
3825 #else
3826     boolean feeding = !strcmp(verb, "\90H\82×\82é"), /* corpsecheck==0 */
3827         offering = !strcmp(verb, "\95ù\82°\82é");    /* corpsecheck==1 */
3828 #endif
3829
3830 #if 1 /*JP*/
3831     const char *jverb = trans_verb(verb)->jp;
3832 #endif
3833
3834     /* if we can't touch floor objects then use invent food only */
3835     if (iflags.menu_requested /* command was preceded by 'm' prefix */
3836         || !can_reach_floor(TRUE) || (feeding && u.usteed)
3837         || (is_pool_or_lava(u.ux, u.uy)
3838             && (Wwalking || is_clinger(youmonst.data)
3839                 || (Flying && !Breathless))))
3840         goto skipfloor;
3841
3842     if (feeding && metallivorous(youmonst.data)) {
3843         struct obj *gold;
3844         struct trap *ttmp = t_at(u.ux, u.uy);
3845
3846         if (ttmp && ttmp->tseen && ttmp->ttyp == BEAR_TRAP) {
3847             /* If not already stuck in the trap, perhaps there should
3848                be a chance to becoming trapped?  Probably not, because
3849                then the trap would just get eaten on the _next_ turn... */
3850 /*JP
3851             Sprintf(qbuf, "There is a bear trap here (%s); eat it?",
3852 */
3853             Sprintf(qbuf, "\82±\82±\82É\82Í\8cF\82Ìã©(%s)\82ª\82 \82é; \90H\82×\82Ü\82·\82©\81H",
3854 /*JP
3855                     (u.utrap && u.utraptype == TT_BEARTRAP) ? "holding you"
3856 */
3857                     (u.utrap && u.utraptype == TT_BEARTRAP) ? "\82 \82È\82½\82ð\92Í\82Ü\82¦\82Ä\82¢\82é"
3858 /*JP
3859                                                             : "armed");
3860 */
3861                                                             : "\89Ò\93®\92\86");
3862             if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
3863                 u.utrap = u.utraptype = 0;
3864                 deltrap(ttmp);
3865                 return mksobj(BEARTRAP, TRUE, FALSE);
3866             } else if (c == 'q') {
3867                 return (struct obj *) 0;
3868             }
3869         }
3870
3871         if (youmonst.data != &mons[PM_RUST_MONSTER]
3872             && (gold = g_at(u.ux, u.uy)) != 0) {
3873 #if 0 /*JP*/
3874             if (gold->quan == 1L)
3875                 Sprintf(qbuf, "There is 1 gold piece here; eat it?");
3876             else
3877                 Sprintf(qbuf, "There are %ld gold pieces here; eat them?",
3878                         gold->quan);
3879 #else
3880             Sprintf(qbuf, "\82±\82±\82É\82Í%ld\96\87\82Ì\8bà\89Ý\82ª\82 \82é\81D\90H\82×\82Ü\82·\82©\81H", gold->quan);
3881 #endif
3882             if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
3883                 return gold;
3884             } else if (c == 'q') {
3885                 return (struct obj *) 0;
3886             }
3887         }
3888     }
3889
3890     /* Is there some food (probably a heavy corpse) here on the ground? */
3891     for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) {
3892         if (corpsecheck
3893                 ? (otmp->otyp == CORPSE
3894                    && (corpsecheck == 1 || tinnable(otmp)))
3895                 : feeding ? (otmp->oclass != COIN_CLASS && is_edible(otmp))
3896                           : otmp->oclass == FOOD_CLASS) {
3897             char qsfx[QBUFSZ];
3898             boolean one = (otmp->quan == 1L);
3899
3900             /* if blind and without gloves, attempting to eat (or tin or
3901                offer) a cockatrice corpse is fatal before asking whether
3902                or not to use it; otherwise, 'm<dir>' followed by 'e' could
3903                be used to locate cockatrice corpses without touching them */
3904             if (otmp->otyp == CORPSE && will_feel_cockatrice(otmp, FALSE)) {
3905                 feel_cockatrice(otmp, FALSE);
3906                 /* if life-saved (or poly'd into stone golem), terminate
3907                    attempt to eat off floor */
3908                 return (struct obj *) 0;
3909             }
3910             /* "There is <an object> here; <verb> it?" or
3911                "There are <N objects> here; <verb> one?" */
3912 #if 0 /*JP*/
3913             Sprintf(qbuf, "There %s ", otense(otmp, "are"));
3914             Sprintf(qsfx, " here; %s %s?", verb, one ? "it" : "one");
3915             (void) safe_qbuf(qbuf, qbuf, qsfx, otmp, doname, ansimpleoname,
3916                              one ? something : (const char *) "things");
3917 #else
3918             Strcpy(qbuf, "\82±\82±\82É");
3919             Sprintf(qsfx, "\82ª\82 \82é; %s%s?", one ? "" : "\88ê\82Â", jverb);
3920             (void) safe_qbuf(qbuf, qbuf, qsfx, otmp, doname, ansimpleoname,
3921                              one ? something : (const char *) "\89½\82©");
3922 #endif
3923             if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y')
3924                 return  otmp;
3925             else if (c == 'q')
3926                 return (struct obj *) 0;
3927         }
3928     }
3929
3930 skipfloor:
3931     /* We cannot use ALL_CLASSES since that causes getobj() to skip its
3932      * "ugly checks" and we need to check for inedible items.
3933      */
3934     otmp = getobj(feeding ? allobj : offering ? offerfodder : comestibles,
3935                   verb);
3936     if (corpsecheck && otmp && !(offering && otmp->oclass == AMULET_CLASS))
3937         if (otmp->otyp != CORPSE || (corpsecheck == 2 && !tinnable(otmp))) {
3938 /*JP
3939             You_cant("%s that!", verb);
3940 */
3941             You_cant("\82»\82ê\82ð%s\82±\82Æ\82Í\82Å\82«\82È\82¢\81I", jverb);
3942             return (struct obj *) 0;
3943         }
3944     return otmp;
3945 }
3946
3947 /* Side effects of vomiting */
3948 /* added nomul (MRS) - it makes sense, you're too busy being sick! */
3949 void
3950 vomit() /* A good idea from David Neves */
3951 {
3952     if (cantvomit(youmonst.data)) {
3953         /* doesn't cure food poisoning; message assumes that we aren't
3954            dealing with some esoteric body_part() */
3955 /*JP
3956         Your("jaw gapes convulsively.");
3957 */
3958         Your("\82 \82²\82Í\94­\8dì\93I\82É\91å\82«\82­\8aJ\82¢\82½\81D");
3959     } else {
3960         make_sick(0L, (char *) 0, TRUE, SICK_VOMITABLE);
3961         /* if not enough in stomach to actually vomit then dry heave;
3962            vomiting_dialog() gives a vomit message when its countdown
3963            reaches 0, but only if u.uhs < FAINTING (and !cantvomit()) */
3964         if (u.uhs >= FAINTING)
3965             Your("%s heaves convulsively!", body_part(STOMACH));
3966     }
3967
3968     /* nomul()/You_can_move_again used to be unconditional, which was
3969        viable while eating but not for Vomiting countdown where hero might
3970        be immobilized for some other reason at the time vomit() is called */
3971     if (multi >= -2) {
3972         nomul(-2);
3973 /*JP
3974     multi_reason = "vomiting";
3975 */
3976     multi_reason = "\9aq\93f\82µ\82Ä\82¢\82é\8dÅ\92\86\82É";
3977         nomovemsg = You_can_move_again;
3978     }
3979 }
3980
3981 int
3982 eaten_stat(base, obj)
3983 int base;
3984 struct obj *obj;
3985 {
3986     long uneaten_amt, full_amount;
3987
3988     /* get full_amount first; obj_nutrition() might modify obj->oeaten */
3989     full_amount = (long) obj_nutrition(obj);
3990     uneaten_amt = (long) obj->oeaten;
3991     if (uneaten_amt > full_amount) {
3992         impossible(
3993           "partly eaten food (%ld) more nutritious than untouched food (%ld)",
3994                    uneaten_amt, full_amount);
3995         uneaten_amt = full_amount;
3996     }
3997
3998     base = (int) (full_amount ? (long) base * uneaten_amt / full_amount : 0L);
3999     return (base < 1) ? 1 : base;
4000 }
4001
4002 /* reduce obj's oeaten field, making sure it never hits or passes 0 */
4003 void
4004 consume_oeaten(obj, amt)
4005 struct obj *obj;
4006 int amt;
4007 {
4008     /*
4009      * This is a hack to try to squelch several long standing mystery
4010      * food bugs.  A better solution would be to rewrite the entire
4011      * victual handling mechanism from scratch using a less complex
4012      * model.  Alternatively, this routine could call done_eating()
4013      * or food_disappears() but its callers would need revisions to
4014      * cope with context.victual.piece unexpectedly going away.
4015      *
4016      * Multi-turn eating operates by setting the food's oeaten field
4017      * to its full nutritional value and then running a counter which
4018      * independently keeps track of whether there is any food left.
4019      * The oeaten field can reach exactly zero on the last turn, and
4020      * the object isn't removed from inventory until the next turn
4021      * when the "you finish eating" message gets delivered, so the
4022      * food would be restored to the status of untouched during that
4023      * interval.  This resulted in unexpected encumbrance messages
4024      * at the end of a meal (if near enough to a threshold) and would
4025      * yield full food if there was an interruption on the critical
4026      * turn.  Also, there have been reports over the years of food
4027      * becoming massively heavy or producing unlimited satiation;
4028      * this would occur if reducing oeaten via subtraction attempted
4029      * to drop it below 0 since its unsigned type would produce a
4030      * huge positive value instead.  So far, no one has figured out
4031      * _why_ that inappropriate subtraction might sometimes happen.
4032      */
4033
4034     if (amt > 0) {
4035         /* bit shift to divide the remaining amount of food */
4036         obj->oeaten >>= amt;
4037     } else {
4038         /* simple decrement; value is negative so we actually add it */
4039         if ((int) obj->oeaten > -amt)
4040             obj->oeaten += amt;
4041         else
4042             obj->oeaten = 0;
4043     }
4044
4045     if (obj->oeaten == 0) {
4046         if (obj == context.victual.piece) /* always true unless wishing... */
4047             context.victual.reqtime =
4048                 context.victual.usedtime; /* no bites left */
4049         obj->oeaten = 1; /* smallest possible positive value */
4050     }
4051 }
4052
4053 /* called when eatfood occupation has been interrupted,
4054    or in the case of theft, is about to be interrupted */
4055 boolean
4056 maybe_finished_meal(stopping)
4057 boolean stopping;
4058 {
4059     /* in case consume_oeaten() has decided that the food is all gone */
4060     if (occupation == eatfood
4061         && context.victual.usedtime >= context.victual.reqtime) {
4062         if (stopping)
4063             occupation = 0; /* for do_reset_eat */
4064         (void) eatfood();   /* calls done_eating() to use up
4065                                context.victual.piece */
4066         return TRUE;
4067     }
4068     return FALSE;
4069 }
4070
4071 /* Tin of <something> to the rescue?  Decide whether current occupation
4072    is an attempt to eat a tin of something capable of saving hero's life.
4073    We don't care about consumption of non-tinned food here because special
4074    effects there take place on first bite rather than at end of occupation.
4075    [Popeye the Sailor gets out of trouble by eating tins of spinach. :-] */
4076 boolean
4077 Popeye(threat)
4078 int threat;
4079 {
4080     struct obj *otin;
4081     int mndx;
4082
4083     if (occupation != opentin)
4084         return FALSE;
4085     otin = context.tin.tin;
4086     /* make sure hero still has access to tin */
4087     if (!carried(otin)
4088         && (!obj_here(otin, u.ux, u.uy) || !can_reach_floor(TRUE)))
4089         return FALSE;
4090     /* unknown tin is assumed to be helpful */
4091     if (!otin->known)
4092         return TRUE;
4093     /* known tin is helpful if it will stop life-threatening problem */
4094     mndx = otin->corpsenm;
4095     switch (threat) {
4096     /* note: not used; hunger code bypasses stop_occupation() when eating */
4097     case HUNGER:
4098         return (boolean) (mndx != NON_PM || otin->spe == 1);
4099     /* flesh from lizards and acidic critters stops petrification */
4100     case STONED:
4101         return (boolean) (mndx >= LOW_PM
4102                           && (mndx == PM_LIZARD || acidic(&mons[mndx])));
4103     /* no tins can cure these (yet?) */
4104     case SLIMED:
4105     case SICK:
4106     case VOMITING:
4107         break;
4108     default:
4109         break;
4110     }
4111     return FALSE;
4112 }
4113
4114 /*eat.c*/