OSDN Git Service

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