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. */
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. */
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);
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));
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))
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])
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]))
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)
65 STATIC_OVL NEARDATA const char comestibles[] = { FOOD_CLASS, 0 };
66 STATIC_OVL NEARDATA const char offerfodder[] = { FOOD_CLASS, AMULET_CLASS,
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
77 STATIC_OVL boolean force_save_hs = FALSE;
79 /* see hunger states in hack.h - texts used on bottom line */
81 const char *hu_stat[] = { "Satiated", " ", "Hungry ", "Weak ",
82 "Fainting", "Fainted ", "Starved " };
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 " };
89 * Decide whether a particular object can be eaten by the possibly
90 * polymorphed character. Not used for monster checks.
94 register struct obj *obj;
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)
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] */
103 if (metallivorous(youmonst.data) && is_metallic(obj)
104 && (youmonst.data != &mons[PM_RUST_MONSTER] || is_rustprone(obj)))
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));
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))
119 /* return (boolean) !!index(comestibles, obj->oclass); */
120 return (boolean) (obj->oclass == FOOD_CLASS);
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) */
128 context.botl = (u.uhs != NOT_HUNGRY || ATEMP(A_STR) < 0);
131 if (ATEMP(A_STR) < 0) {
133 (void) encumber_msg();
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 */
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 },
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 },
178 #define TTSZ SIZE(tintxts)
180 static char *eatmbuf = 0; /* set by cpostfx() */
182 /* called after mimicing is over */
186 /* release `eatmbuf' */
188 if (nomovemsg == eatmbuf)
190 free((genericptr_t) eatmbuf), eatmbuf = 0;
194 youmonst.m_ap_type = M_AP_NOTHING;
200 /* called when hallucination is toggled */
204 const char *altmsg = 0;
205 int altapp = 0; /* lint suppression */
207 if (!eatmbuf || nomovemsg != eatmbuf)
210 if (is_obj_mappear(&youmonst,ORANGE) && !Hallucination) {
211 /* revert from hallucinatory to "normal" mimicking */
213 altmsg = "You now prefer mimicking yourself.";
215 altmsg = "
\82 \82È
\82½
\82Í
\8e©
\95ª
\8e©
\90g
\82Ì
\82Ü
\82Ë
\82ð
\82·
\82é
\82±
\82Æ
\82ð
\91I
\82ñ
\82¾
\81D";
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 */
222 altmsg = "Your rind escaped intact.";
224 altmsg = "
\82 \82È
\82½
\82Ì
\94ç
\82ª
\82»
\82Ì
\82Ü
\82Ü
\82Ì
\8c`
\82Å
\93¦
\82°
\82Ä
\82¢
\82Á
\82½
\81D";
229 /* replace end-of-mimicking message */
230 if (strlen(altmsg) > strlen(eatmbuf)) {
231 free((genericptr_t) eatmbuf);
232 eatmbuf = (char *) alloc(strlen(altmsg) + 1);
234 nomovemsg = strcpy(eatmbuf, altmsg);
235 /* update current image */
236 youmonst.mappearance = altapp;
241 /* ``[the(] singular(food, xname) [)]'' */
242 STATIC_OVL const char *
243 food_xname(food, the_pfx)
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]))
257 /* the ordinary case */
258 result = singular(food, xname);
261 result = the(result);
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.
270 * To a full belly all food is bad. (It.)
276 /* only happens if you were satiated */
277 if (u.uhs != SATIATED) {
278 if (!food || food->otyp != AMULET_OF_STRANGULATION)
280 } else if (Role_if(PM_KNIGHT) && u.ualign.type == A_LAWFUL) {
281 adjalign(-1); /* gluttony is unchivalrous */
283 You_feel("like a glutton!");
285 You("
\91å
\90H
\8a¿
\82Ì
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81I");
288 exercise(A_CON, FALSE);
290 if (Breathless || (!Strangled && !rn2(20))) {
291 /* choking by eating AoS doesn't involve stuffing yourself */
292 if (food && food->otyp == AMULET_OF_STRANGULATION) {
294 You("choke, but recover your composure.");
296 You("
\8eñ
\82ð
\8di
\82ß
\82ç
\82ê
\82½
\81D
\82µ
\82©
\82µ
\82È
\82ñ
\82Æ
\82à
\82È
\82©
\82Á
\82½
\81D");
300 You("stuff yourself and then vomit voluminously.");
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! */
306 killer.format = KILLED_BY_AN;
308 * Note all "killer"s below read "Choked on %s" on the
309 * high score list & tombstone. So plan accordingly.
313 You("choke over your %s.", foodword(food));
315 You("%s
\82ð
\8dA
\82É
\8bl
\82Ü
\82ç
\82¹
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D", foodword(food));
316 if (food->oclass == COIN_CLASS) {
318 Strcpy(killer.name, "very rich meal");
320 Strcpy(killer.name, "
\82Æ
\82Ä
\82à
\8d\82\89¿
\82È
\97¿
\97\9d");
322 killer.format = KILLED_BY;
323 Strcpy(killer.name, killer_xname(food));
327 You("choke over it.");
329 pline("
\8dA
\82É
\8bl
\82Ü
\82ç
\82¹
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
331 Strcpy(killer.name, "quick snack");
333 Strcpy(killer.name, "
\91\81\90H
\82¢");
338 pline("
\82 \82È
\82½
\82Í
\8e\80\82É
\82Ü
\82µ
\82½
\81D
\81D
\81D");
343 /* modify object wt. depending on time spent consuming it */
347 struct obj *piece = context.victual.piece;
349 impossible("recalc_wt without piece");
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);
359 /* called when eating interrupted by an event */
363 /* we only set a flag here - the actual reset process is done after
364 * the round is spent eating.
366 if (context.victual.eating && !context.victual.doreset) {
367 debugpline0("reset_eat...");
368 context.victual.doreset = TRUE;
373 /* base nutrition of a food-class object */
378 unsigned nut = (otmp->otyp == CORPSE) ? mons[otmp->corpsenm].cnutrit
379 : otmp->globby ? otmp->owt
380 : (unsigned) objects[otmp->otyp].oc_nutrition;
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)
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 */
399 STATIC_OVL struct obj *
403 if (otmp->quan > 1L) {
405 (void) splitobj(otmp, otmp->quan - 1L);
407 otmp = splitobj(otmp, 1L);
408 debugpline0("split object,");
412 costly_alteration(otmp, COST_BITE);
413 otmp->oeaten = obj_nutrition(otmp);
418 if (inv_cnt(FALSE) >= 52) {
419 sellobj_state(SELL_DONTSELL);
421 sellobj_state(SELL_NORMAL);
423 otmp->nomerge = 1; /* used to prevent merge */
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
440 if (obj == context.victual.piece) {
441 context.victual.piece = (struct obj *) 0;
442 context.victual.o_id = 0;
445 obj_stop_timers(obj);
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 */
452 food_substitution(old_obj, new_obj)
453 struct obj *old_obj, *new_obj;
455 if (old_obj == context.victual.piece) {
456 context.victual.piece = new_obj;
457 context.victual.o_id = new_obj->o_id;
459 if (old_obj == context.tin.tin) {
460 context.tin.tin = new_obj;
461 context.tin.o_id = new_obj->o_id;
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;
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.
487 /* called each move during eating process */
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? */
498 if (!context.victual.eating)
501 if (++context.victual.usedtime <= context.victual.reqtime) {
504 return 1; /* still busy */
515 struct obj *piece = context.victual.piece;
517 piece->in_use = TRUE;
518 occupation = 0; /* do this early, so newuhs() knows we're done */
526 You("finish eating %s.", food_xname(piece, TRUE));
528 You("%s
\82ð
\90H
\82×
\8fI
\82¦
\82½
\81D", food_xname(piece, TRUE));
530 if (piece->otyp == CORPSE || piece->globby)
531 cpostfx(piece->corpsenm);
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;
551 u.uconduct.unvegan++;
553 violated_vegetarian();
556 /* handle side-effects of mind flayer's tentacle attack */
558 eat_brains(magr, mdef, visflag, dmg_p)
559 struct monst *magr, *mdef;
561 int *dmg_p; /* for dishing out extra damage in lieu of Int loss */
563 struct permonst *pd = mdef->data;
564 boolean give_nutrit = FALSE;
565 int result = MM_HIT, xtra_dmg = rnd(10);
567 if (noncorporeal(pd)) {
570 pline("%s brain is unharmed.",
571 (mdef == &youmonst) ? "Your" : s_suffix(Monnam(mdef)));
573 pline("%s
\82Ì
\94]
\82Í
\96³
\8e\96\82¾
\82Á
\82½
\81D",
574 (mdef == &youmonst) ? "
\82 \82È
\82½" : Monnam(mdef));
576 return MM_MISS; /* side-effects can't occur */
577 } else if (magr == &youmonst) {
579 You("eat %s brain!", s_suffix(mon_nam(mdef)));
581 You("%s
\82Ì
\94]
\82ð
\90H
\82×
\82½
\81I", mon_nam(mdef));
582 } else if (mdef == &youmonst) {
584 Your("brain is eaten!");
586 Your("
\94]
\82Í
\90H
\82×
\82ç
\82ê
\82½
\81I");
587 } else { /* monster against monster */
588 if (visflag && canspotmon(mdef))
590 pline("%s brain is eaten!", s_suffix(Monnam(mdef)));
592 pline("%s
\82Ì
\94]
\82Í
\90H
\82×
\82ç
\82ê
\82½
\81I", Monnam(mdef));
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);
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))
607 pline("%s turns to stone!", Monnam(magr));
609 pline("%s
\82Í
\90Î
\82É
\82È
\82Á
\82½
\81I", Monnam(magr));
611 if (!DEADMONSTER(magr)) {
612 /* life-saved; don't continue eating the brains */
615 if (magr->mtame && !visflag)
616 /* parallels mhitm.c's brief_feeling */
618 You("have a sad thought for a moment, then it passes.");
620 You("
\94ß
\82µ
\82¢
\8dl
\82¦
\82É
\82¨
\82»
\82í
\82ê
\82½
\82ª
\81A
\82·
\82®
\82É
\89ß
\82¬
\82³
\82Á
\82½
\81D");
626 if (magr == &youmonst) {
628 * player mind flayer is eating something's brain
631 if (mindless(pd)) { /* (cannibalism not possible here) */
633 pline("%s doesn't notice.", Monnam(mdef));
635 pline("%s
\82Í
\8bC
\82Ã
\82¢
\82Ä
\82¢
\82È
\82¢
\81D", Monnam(mdef));
636 /* all done; no extra harm inflicted upon target */
638 } else if (is_rider(pd)) {
640 pline("Ingesting that is fatal.");
642 pline("
\8eæ
\82è
\8d\9e\82ñ
\82¾
\82ç
\82·
\82®
\82É
\8e\80\82ñ
\82Å
\82µ
\82Ü
\82Á
\82½
\81D");
644 Sprintf(killer.name, "unwisely ate the brain of %s", pd->mname);
645 killer.format = NO_KILLER_PREFIX;
647 Sprintf(killer.name, "
\8bð
\82©
\82É
\82à%s
\82Ì
\91Ì
\82ð
\90H
\82×
\82Ä", pd->mname);
648 killer.format = KILLED_BY;
651 /* life-saving needed to reach here */
652 exercise(A_WIS, FALSE);
653 *dmg_p += xtra_dmg; /* Rider takes extra damage */
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);
663 exercise(A_WIS, TRUE);
666 /* targetting another mind flayer or your own underlying species
668 (void) maybe_cannibal(monsndx(pd), TRUE);
670 } else if (mdef == &youmonst) {
672 * monster mind flayer is eating hero's brain
674 /* no such thing as mindless players */
675 if (ABASE(A_INT) <= ATTRMIN(A_INT)) {
677 static NEARDATA const char brainlessness[] = "brainlessness";
679 static NEARDATA const char brainlessness[] = "
\94]
\82ð
\8e¸
\82Á
\82Ä";
682 Strcpy(killer.name, brainlessness);
683 killer.format = KILLED_BY;
685 /* amulet of life saving has now been used up */
687 pline("Unfortunately your brain is still gone.");
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;
695 Your("last thought fades away.");
697 Your("
\8dÅ
\8cã
\82Ì
\8ev
\82¢
\82ª
\91\96\94n
\93\95\82Ì
\82æ
\82¤
\82É
\89¡
\82¬
\82Á
\82½
\81D");
699 Strcpy(killer.name, brainlessness);
700 killer.format = KILLED_BY;
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;
706 You_feel("like a scarecrow.");
708 You("
\82©
\82©
\82µ
\82Ì
\82æ
\82¤
\82È
\8bC
\8e\9d\82ª
\82µ
\82½
\81D");
710 give_nutrit = TRUE; /* in case a conflicted pet is doing this */
711 exercise(A_WIS, FALSE);
712 /* caller handles Int and memory loss */
716 * monster mind flayer is eating another monster's brain
719 if (visflag && canspotmon(mdef))
721 pline("%s doesn't notice.", Monnam(mdef));
723 pline("%s
\82Í
\8bC
\82Ã
\82¢
\82Ä
\82¢
\82È
\82¢
\81D", Monnam(mdef));
725 } else if (is_rider(pd)) {
727 if (DEADMONSTER(magr))
728 result = MM_AGR_DIED;
729 /* Rider takes extra damage regardless of whether attacker dies */
734 if (*dmg_p >= mdef->mhp && visflag && canspotmon(mdef))
736 pline("%s last thought fades away...",
737 s_suffix(Monnam(mdef)));
739 pline("%s
\82Ì
\8dÅ
\8cã
\82Ì
\8ev
\82¢
\82ª
\82æ
\82¬
\82é
\81D
\81D
\81D",
745 if (give_nutrit && magr->mtame && !magr->isminion) {
746 EDOG(magr)->hungrytime += rnd(60);
753 /* eating a corpse or egg of one's own species is usually naughty */
755 maybe_cannibal(pm, allowmsg)
759 static NEARDATA long ate_brains = 0L;
760 struct permonst *fptr = &mons[pm]; /* food type */
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)
767 ate_brains = moves; /* ate_anything, not just brains... */
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) */
775 || (Upolyd && same_race(youmonst.data, fptr))
776 || (u.ulycn >= LOW_PM && were_beastie(pm) == u.ulycn))) {
778 if (Upolyd && your_race(fptr))
780 You("have a bad feeling deep inside.");
782 You("
\8c\99\88«
\8a´
\82É
\82¨
\82»
\82í
\82ê
\82½
\81D");
784 You("cannibal! You will regret this!");
786 pline("
\8b¤
\8bò
\82¢
\82¾
\81I
\8cã
\89÷
\82·
\82é
\82¼
\81I");
788 HAggravate_monster |= FROMOUTSIDE;
789 change_luck(-rn1(4, 2)); /* -5..-2 */
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))) {
805 Sprintf(killer.name, "tasting %s meat", mons[pm].mname);
807 Sprintf(killer.name, "%s
\82Ì
\93÷
\82ð
\90H
\82×", mons[pm].mname);
808 killer.format = KILLED_BY;
810 You("turn to stone.");
812 You("
\90Î
\82É
\82È
\82Á
\82½
\81D");
814 if (context.victual.piece)
815 context.victual.eating = FALSE;
816 return; /* lifesaved */
827 /* cannibals are allowed to eat domestic animals without penalty */
828 if (!CANNIBAL_ALLOWED()) {
830 You_feel("that eating the %s was a bad idea.", mons[pm].mname);
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;
844 pline("Eating that is instantly fatal.");
846 pline("
\90H
\82×
\82½
\82ç
\82·
\82®
\82É
\8e\80\82ñ
\82Å
\82µ
\82Ü
\82Á
\82½
\81D");
848 Sprintf(killer.name, "unwisely ate the body of %s", mons[pm].mname);
849 killer.format = NO_KILLER_PREFIX;
851 Sprintf(killer.name, "
\8bð
\82©
\82É
\82à%s
\82Ì
\91Ì
\82ð
\90H
\82×
\82Ä", mons[pm].mname);
852 killer.format = KILLED_BY;
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;
867 if (!Slimed && !Unchanging && !slimeproof(youmonst.data)) {
869 You("don't feel very well.");
871 You("
\82·
\82²
\82
\8bC
\95ª
\82ª
\88«
\82¢
\81D");
872 make_slimed(10L, (char *) 0);
873 delayed_killer(SLIMED, KILLED_BY_AN, "");
877 if (acidic(&mons[pm]) && Stoned)
890 Sprintf(buf, "What a pity--you just ruined a future piece of %sart!",
891 ACURR(A_CHA) > 15 ? "fine " : "");
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È" : "");
898 Strcpy(buf, "You feel limber!");
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);
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.
913 /* intrinsic_possible() returns TRUE iff a monster can give an intrinsic. */
915 intrinsic_possible(type, ptr)
917 register struct permonst *ptr;
922 #define ifdebugresist(Msg) \
928 #define ifdebugresist(Msg) /*empty*/
932 res = (ptr->mconveys & MR_FIRE) != 0;
933 ifdebugresist("can get fire resistance");
936 res = (ptr->mconveys & MR_SLEEP) != 0;
937 ifdebugresist("can get sleep resistance");
940 res = (ptr->mconveys & MR_COLD) != 0;
941 ifdebugresist("can get cold resistance");
944 res = (ptr->mconveys & MR_DISINT) != 0;
945 ifdebugresist("can get disintegration resistance");
947 case SHOCK_RES: /* shock (electricity) resistance */
948 res = (ptr->mconveys & MR_ELEC) != 0;
949 ifdebugresist("can get shock resistance");
952 res = (ptr->mconveys & MR_POISON) != 0;
953 ifdebugresist("can get poison resistance");
956 res = can_teleport(ptr);
957 ifdebugresist("can get teleport");
959 case TELEPORT_CONTROL:
960 res = control_teleport(ptr);
961 ifdebugresist("can get teleport control");
964 res = telepathic(ptr);
965 ifdebugresist("can get telepathy");
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.
981 register struct permonst *ptr;
985 debugpline1("Attempting to give intrinsic %d", type);
986 /* some intrinsics are easier to get than others */
989 if ((ptr == &mons[PM_KILLER_BEE] || ptr == &mons[PM_SCORPION])
998 case TELEPORT_CONTROL:
1009 if (ptr->mlevel <= rn2(chance))
1010 return; /* failed die roll */
1014 debugpline0("Trying to give fire resistance");
1015 if (!(HFire_resistance & FROMOUTSIDE)) {
1017 You(Hallucination ? "be chillin'." : "feel a momentary chill.");
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;
1024 debugpline0("Trying to give sleep resistance");
1025 if (!(HSleep_resistance & FROMOUTSIDE)) {
1027 You_feel("wide awake.");
1029 You("
\82Ï
\82Á
\82¿
\82è
\96Ú
\82ª
\82³
\82ß
\82½
\81D");
1030 HSleep_resistance |= FROMOUTSIDE;
1034 debugpline0("Trying to give cold resistance");
1035 if (!(HCold_resistance & FROMOUTSIDE)) {
1037 You_feel("full of hot air.");
1039 You("
\94M
\95\97\82ð
\91S
\90g
\82É
\8a´
\82¶
\82½
\81D");
1040 HCold_resistance |= FROMOUTSIDE;
1044 debugpline0("Trying to give disintegration resistance");
1045 if (!(HDisint_resistance & FROMOUTSIDE)) {
1047 You_feel(Hallucination ? "totally together, man." : "very firm.");
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;
1053 case SHOCK_RES: /* shock (electricity) resistance */
1054 debugpline0("Trying to give shock resistance");
1055 if (!(HShock_resistance & FROMOUTSIDE)) {
1058 You_feel("grounded in reality.");
1060 You("
\8eÀ
\82Í
\83A
\81[
\83X
\82³
\82ê
\82Ä
\82¢
\82é
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
1063 Your("health currently feels amplified!");
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;
1070 debugpline0("Trying to give poison resistance");
1071 if (!(HPoison_resistance & FROMOUTSIDE)) {
1073 You_feel(Poison_resistance ? "especially healthy." : "healthy.");
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;
1080 debugpline0("Trying to give teleport");
1081 if (!(HTeleportation & FROMOUTSIDE)) {
1083 You_feel(Hallucination ? "diffuse." : "very jumpy.");
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;
1089 case TELEPORT_CONTROL:
1090 debugpline0("Trying to give teleport control");
1091 if (!(HTeleport_control & FROMOUTSIDE)) {
1093 You_feel(Hallucination ? "centered in your personal space."
1094 : "in control of yourself.");
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");
1099 HTeleport_control |= FROMOUTSIDE;
1103 debugpline0("Trying to give telepathy");
1104 if (!(HTelepat & FROMOUTSIDE)) {
1106 You_feel(Hallucination ? "in touch with the cosmos."
1107 : "a strange mental acuity.");
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");
1112 HTelepat |= FROMOUTSIDE;
1113 /* If blind, make sure monsters show up. */
1119 debugpline0("Tried to give an impossible intrinsic");
1124 /* called after completely consuming a corpse */
1130 int catch_lycanthropy = NON_PM;
1131 boolean check_intrinsics = FALSE;
1133 /* in case `afternmv' didn't get called for previously mimicking
1134 gold, clean up now to avoid `eatmbuf' memory leak */
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;
1145 if (u.uen > u.uenmax) {
1150 if (old_uen != u.uen) {
1152 You_feel("a mild buzz.");
1154 You("
\82·
\82±
\82µ
\82Ó
\82ç
\82Ó
\82ç
\82µ
\82½
\81D");
1162 case PM_HUMAN_WERERAT:
1163 catch_lycanthropy = PM_WERERAT;
1165 case PM_HUMAN_WEREJACKAL:
1166 catch_lycanthropy = PM_WEREJACKAL;
1168 case PM_HUMAN_WEREWOLF:
1169 catch_lycanthropy = PM_WEREWOLF;
1176 make_blinded(0L, !u.ucreamed);
1178 check_intrinsics = TRUE; /* might also convey poison resistance */
1182 set_itimeout(&HInvis, (long) rn1(100, 50));
1183 if (!Blind && !BInvis)
1184 self_invis_message();
1186 if (!(HInvis & INTRINSIC))
1188 You_feel("hidden!");
1190 Your("
\8ep
\82Í
\89B
\82³
\82ê
\82½
\81I");
1191 HInvis |= FROMOUTSIDE;
1192 HSee_invisible |= FROMOUTSIDE;
1196 case PM_YELLOW_LIGHT:
1198 make_stunned((HStun & TIMEOUT) + 30L, FALSE);
1201 make_stunned((HStun & TIMEOUT) + 30L, FALSE);
1203 case PM_GIANT_MIMIC:
1206 case PM_LARGE_MIMIC:
1209 case PM_SMALL_MIMIC:
1211 if (youmonst.data->mlet != S_MIMIC && !Unchanging) {
1214 u.uconduct.polyselfs++; /* you're changing form */
1216 You_cant("resist the temptation to mimic %s.",
1217 Hallucination ? "an orange" : "a pile of gold");
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");
1222 /* A pile of gold can't ride. */
1224 dismount_steed(DISMOUNT_FELL);
1227 multi_reason = "pretending to be a pile of gold";
1229 multi_reason = "
\8bà
\89Ý
\82Ì
\8eR
\82Ì
\90^
\8e\97\82ð
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
1233 ? "You suddenly dread being peeled and mimic %s again!"
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"
1237 : "You now prefer mimicking %s again.",
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;
1249 /* make gold symbol show up now */
1250 display_nhwindow(WIN_MAP, TRUE);
1253 case PM_QUANTUM_MECHANIC:
1255 Your("velocity suddenly seems very uncertain!");
1257 Your("
\91¬
\93x
\82ª
\93Ë
\91R
\81C
\95s
\8am
\92è
\82É
\82È
\82Á
\82½
\81I");
1258 if (HFast & INTRINSIC) {
1259 HFast &= ~INTRINSIC;
1261 You("seem slower.");
1263 You("
\92x
\82
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D");
1265 HFast |= FROMOUTSIDE;
1267 You("seem faster.");
1269 You("
\91¬
\82
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D");
1273 if ((HStun & TIMEOUT) > 2)
1274 make_stunned(2L, FALSE);
1275 if ((HConfusion & TIMEOUT) > 2)
1276 make_confused(2L, FALSE);
1279 case PM_DOPPELGANGER:
1280 case PM_SANDESTIN: /* moot--they don't leave corpses */
1283 You_feel("momentarily different."); /* same as poly trap */
1285 You_feel("
\88ê
\8fu
\88á
\82Á
\82½
\8a´
\82¶
\82ª
\82µ
\82½
\81D"); /* same as poly trap */
1289 You_feel("a change coming over you.");
1291 pline("
\95Ï
\89»
\82ª
\96K
\82ê
\82½
\81D");
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");
1301 case PM_MIND_FLAYER:
1302 case PM_MASTER_MIND_FLAYER:
1303 if (ABASE(A_INT) < ATTRMAX(A_INT)) {
1306 pline("Yum! That was real brain food!");
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 */
1314 pline("For some reason, that tasted bland.");
1316 pline("
\82Ç
\82¤
\82µ
\82½
\82í
\82¯
\82©
\81C
\92W
\94\92\82È
\96¡
\82¾
\81D");
1320 check_intrinsics = TRUE;
1324 /* possibly convey an intrinsic */
1325 if (check_intrinsics) {
1326 struct permonst *ptr = &mons[pm];
1327 boolean conveys_STR = is_giant(ptr);
1330 if (dmgtype(ptr, AD_STUN) || dmgtype(ptr, AD_HALU)
1331 || pm == PM_VIOLET_FUNGUS) {
1333 pline("Oh wow! Great stuff!");
1335 pline("
\83\8f\81[
\83H
\81I
\82±
\82è
\82á
\82·
\82²
\82¢
\81I");
1336 (void) make_hallucinated((HHallucination & TIMEOUT) + 200L, FALSE,
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.
1344 * Strength from giants is now treated like an intrinsic
1345 * rather than being given unconditionally.
1347 count = 0; /* number of possible intrinsics */
1348 tmp = 0; /* which one we will try to give */
1351 tmp = -1; /* use -1 as fake prop index for STR */
1352 debugpline1("\"Intrinsic\" strength, %d", tmp);
1354 for (i = 1; i <= LAST_PROP; i++) {
1355 if (!intrinsic_possible(i, ptr))
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) */
1363 debugpline2("Intrinsic %d replacing %d", i, tmp);
1367 /* if strength is the only candidate, give it 50% chance */
1368 if (conveys_STR && count == 1 && !rn2(2))
1370 /* if something was chosen, give it now (givit() might fail) */
1372 gainstr((struct obj *) 0, 0, TRUE);
1375 } /* check_intrinsics */
1377 if (catch_lycanthropy >= LOW_PM) {
1378 set_ulycn(catch_lycanthropy);
1379 retouch_equipment(2);
1385 violated_vegetarian()
1387 u.uconduct.unvegetarian++;
1388 if (Role_if(PM_MONK)) {
1390 You_feel("guilty.");
1392 pline("
\8dß
\82ð
\8a´
\82¶
\82½
\81D");
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 */
1404 struct obj *tin = context.tin.tin;
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;
1412 costly_alteration(tin, alter_type);
1418 tin_variety_txt(s, tinvariety)
1424 if (s && tinvariety) {
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)
1439 * This assumes that buf already contains the word "tin",
1440 * as is the case with caller xname().
1442 /*JP:
\81u
\8aÊ
\8bl
\81v
\82Í
\8cã
\82Å
\95t
\82¯
\82é */
1444 tin_details(obj, mnum, buf)
1452 int r = tin_variety(obj, TRUE);
1455 if (r == SPINACH_TIN)
1457 Strcat(buf, " of spinach");
1459 Strcat(buf, "
\83z
\83E
\83\8c\83\93\91\90\82Ì");
1460 else if (mnum == NON_PM)
1462 Strcpy(buf, "empty tin");
1464 Strcat(buf, "
\8bó
\82Á
\82Û
\82Ì");
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);
1473 Sprintf(eos(buf), " of %s ", tintxts[r].txt);
1475 Sprintf(eos(buf), "%s", tintxts[r].txt);
1477 Strcpy(eos(buf), " of ");
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);
1485 if (vegetarian(&mons[mnum]))
1487 Sprintf(eos(buf), "%s", mons[mnum].mname);
1489 Sprintf(eos(buf), "%s", mons[mnum].mname);
1492 Sprintf(eos(buf), "%s meat", mons[mnum].mname);
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);
1499 Strcpy(eos(buf), "
\82Ì");
1506 set_tin_variety(obj, forcetype)
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 */
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)
1525 } else if (forcetype >= 0 && forcetype < TTSZ - 1) {
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 */
1532 obj->spe = -(r + 1); /* offset by 1 to allow index 0 */
1536 tin_variety(obj, disp)
1538 boolean disp; /* we're just displaying so leave things alone */
1542 if (obj->spe == 1) {
1544 } else if (obj->cursed) {
1545 r = ROTTEN_TIN; /* always rotten if cursed */
1546 } else if (obj->spe < 0) {
1548 --r; /* get rid of the offset */
1552 if (!disp && r == HOMEMADE_TIN && !obj->blessed && !rn2(7))
1553 r = ROTTEN_TIN; /* some homemade tins go bad */
1555 if (r == ROTTEN_TIN && nonrotting_corpse(obj->corpsenm))
1556 r = HOMEMADE_TIN; /* lizards don't rot */
1566 struct obj *tin = context.tin.tin;
1568 r = tin_variety(tin, FALSE);
1569 if (tin->otrapped || (tin->cursed && r != HOMEMADE_TIN && !rn2(8))) {
1571 b_trapped("tin", 0);
1573 b_trapped("
\8aÊ", 0);
1574 tin = costly_tin(COST_DSTROY);
1578 pline1(mesg); /* "You succeed in opening the tin." */
1580 if (r != SPINACH_TIN) {
1581 mnum = tin->corpsenm;
1582 if (mnum == NON_PM) {
1584 pline("It turns out to be empty.");
1586 pline("
\8aÊ
\82Í
\8bó
\82Á
\82Û
\82¾
\82Á
\82½
\81D");
1587 tin->dknown = tin->known = 1;
1588 tin = costly_tin(COST_OPEN);
1592 which = 0; /* 0=>plural, 1=>as-is, 2=>"the" prefix */
1593 if ((mnum == PM_COCKATRICE || mnum == PM_CHICKATRICE)
1594 && (Stone_resistance || Hallucination)) {
1599 which = 1; /* suppress pluralization */
1600 } else if (Hallucination) {
1601 what = rndmonnam(NULL);
1603 what = mons[mnum].mname;
1604 if (the_unique_pm(&mons[mnum]))
1606 else if (type_is_pname(&mons[mnum]))
1610 what = makeplural(what);
1611 else if (which == 2)
1615 pline("It smells like %s.", what);
1617 pline("%s
\82Ì
\82æ
\82¤
\82È
\93õ
\82¢
\82ª
\82µ
\82½
\81D", what);
1619 if (yn("Eat it?") == 'n') {
1621 if (yn("
\90H
\82×
\82Ü
\82·
\82©
\81H") == 'n') {
1624 You("discard the open tin.");
1626 You("
\8aJ
\82¯
\82½
\8aÊ
\82ð
\8eÌ
\82Ä
\82½
\81D");
1628 tin->dknown = tin->known = 1;
1629 tin = costly_tin(COST_OPEN);
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;
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);
1645 You("%s%s
\82Ì
\8aÊ
\8bl
\82ð
\82½
\82¢
\82ç
\82°
\82½
\81D", tintxts[r].txt, mons[mnum].mname);
1649 eating_conducts(&mons[mnum]);
1651 tin->dknown = tin->known = 1;
1655 /* charge for one at pre-eating cost */
1656 tin = costly_tin(COST_OPEN);
1658 if (tintxts[r].nut < 0) /* rotten */
1659 make_vomiting((long) rn1(15, 10), FALSE);
1661 lesshungry(tintxts[r].nut);
1663 if (tintxts[r].greasy) {
1664 /* Assume !Glib, because you can't open tins when Glib. */
1665 incr_itimeout(&Glib, rnd(15));
1667 pline("Eating %s food made your %s very slippery.",
1668 tintxts[r].txt, makeplural(body_part(FINGER)));
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",
1675 } else { /* spinach... */
1678 pline("It contains some decaying%s%s substance.",
1679 Blind ? "" : " ", Blind ? "" : hcolor(NH_GREEN));
1681 pline("%s
\95\85\82Á
\82½
\95¨
\91Ì
\82ª
\93ü
\82Á
\82Ä
\82¢
\82é
\81D",
1682 Blind ? "" : hcolor(NH_GREEN));
1686 pline("It contains spinach.");
1688 pline("
\83z
\83E
\83\8c\83\93\91\90\82ª
\93ü
\82Á
\82Ä
\82¢
\82é
\81D");
1689 tin->dknown = tin->known = 1;
1693 if (yn("Eat it?") == 'n') {
1695 if (yn("
\90H
\82×
\82Ü
\82·
\82©
\81H") == 'n') {
1698 You("discard the open tin.");
1700 You("
\8aJ
\82¯
\82½
\8aÊ
\82ð
\8eÌ
\82Ä
\82½
\81D");
1701 tin = costly_tin(COST_OPEN);
1706 * Same order as with non-spinach above:
1707 * conduct update, side-effects, shop handling, and nutrition.
1709 u.uconduct.food++; /* don't need vegetarian checks for spinach */
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"));
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"));
1736 gainstr(tin, 0, FALSE);
1738 tin = costly_tin(COST_OPEN);
1740 lesshungry(tin->blessed
1743 ? (400 + rnd(200)) /* uncursed */
1744 : (200 + rnd(400))); /* cursed */
1752 context.tin.tin = (struct obj *) 0;
1753 context.tin.o_id = 0;
1756 /* called during each move whilst opening a tin */
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) {
1766 You("give up your attempt to open the tin.");
1768 You("
\8aÊ
\82ð
\8aJ
\82¯
\82é
\82Ì
\82ð
\82 \82«
\82ç
\82ß
\82½
\81D");
1771 if (context.tin.usedtime < context.tin.reqtime)
1772 return 1; /* still busy */
1775 consume_tin("You succeed in opening the tin.");
1777 consume_tin("
\8aÊ
\82ð
\8aJ
\82¯
\82é
\82Ì
\82É
\90¬
\8c÷
\82µ
\82½
\81D");
1781 /* called when starting to open a tin */
1786 const char *mesg = 0;
1789 if (metallivorous(youmonst.data)) {
1791 mesg = "You bite right into the metal tin...";
1793 mesg = "
\8bà
\91®
\82Ì
\8aÊ
\82ð
\8a\9a\82Ý
\82Í
\82¶
\82ß
\82½
\81D
\81D
\81D";
1795 } else if (cantwield(youmonst.data)) { /* nohands || verysmall */
1797 You("cannot handle the tin properly to open it.");
1799 You("
\8aÊ
\82ð
\82¤
\82Ü
\82
\8aJ
\82¯
\82ç
\82ê
\82È
\82¢
\81D");
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);
1810 mesg = "The tin opens like magic!";
1812 mesg = "
\8aÊ
\82Í
\96\82\96@
\82Ì
\82æ
\82¤
\82É
\8aJ
\82¢
\82½
\81I";
1815 pline_The("tin seems easy to open.");
1817 pline_The("
\8aÊ
\82Í
\8aÈ
\92P
\82É
\8aJ
\82¯
\82ç
\82ê
\82»
\82¤
\82¾
\81D");
1819 switch (uwep->otyp) {
1822 mesg = "You easily open the tin."; /* iff tmp==0 */
1824 mesg = "
\82 \82È
\82½
\82Í
\8aÈ
\92P
\82É
\8aÊ
\82ð
\8aJ
\82¯
\82½
\81D"; /* iff tmp==0 */
1826 tmp = rn2(uwep->cursed ? 3 : !uwep->blessed ? 2 : 1);
1846 pline("Using %s you try to open the tin.", yobjnam(uwep, (char *) 0));
1848 You("%s
\82ð
\8eg
\82Á
\82Ä
\8aÊ
\82ð
\8aJ
\82¯
\82æ
\82¤
\82Æ
\82µ
\82½
\81D", xname(uwep));
1852 pline("It is not so easy to open this tin.");
1854 pline("
\82±
\82Ì
\8aÊ
\82ð
\8aJ
\82¯
\82é
\82Ì
\82Í
\97e
\88Õ
\82È
\82±
\82Æ
\82Å
\82Í
\82È
\82¢
\81D");
1857 pline_The("tin slips from your %s.",
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);
1870 tmp = rn1(1 + 500 / ((int) (ACURR(A_DEX) + ACURRSTR)), 10);
1873 context.tin.tin = otmp;
1874 context.tin.o_id = otmp->o_id;
1876 consume_tin(mesg); /* begin immediately */
1878 context.tin.reqtime = tmp;
1879 context.tin.usedtime = 0;
1881 set_occupation(opentin, "opening the tin", 0);
1883 set_occupation(opentin, "
\8aÊ
\82ð
\8aJ
\82¯
\82é", 0);
1888 /* called when waking up after fainting */
1890 Hear_again(VOID_ARGS)
1892 /* Chance of deafness going away while fainted/sleeping/etc. */
1894 make_deaf(0L, FALSE);
1895 context.botl = TRUE;
1900 /* called on the "first bite" of rotten food */
1906 pline("Blecch! Rotten %s!", foodword(obj));
1908 pline("
\83Q
\83F
\81I
\95\85\82Á
\82½%s
\82¾
\81I", foodword(obj));
1912 You_feel("rather trippy.");
1914 You("
\82Ö
\82ë
\82Ö
\82ë
\82µ
\82½
\81D");
1917 You_feel("rather %s.", body_part(LIGHT_HEADED));
1919 You("%s
\81D", body_part(LIGHT_HEADED));
1920 make_confused(HConfusion + d(2, 4), FALSE);
1921 } else if (!rn2(4) && !Blind) {
1923 pline("Everything suddenly goes dark.");
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);
1930 Your1(vision_clears);
1931 } else if (!rn2(3)) {
1932 const char *what, *where;
1933 int duration = rnd(10);
1937 what = "goes", where = "dark";
1939 what = "
\82È
\82Á
\82½", where = "
\88Ã
\88Å
\82É";
1940 else if (Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz))
1942 what = "you lose control of", where = "yourself";
1944 what = "
\90§
\8cä
\82Å
\82«
\82È
\82
\82È
\82Á
\82½", where = "
\8e©
\95ª
\82ð";
1947 what = "you slap against the",
1949 what = "
\82É
\82Ô
\82Â
\82©
\82Á
\82½",
1951 where = (u.usteed) ? "saddle" : surface(u.ux, u.uy);
1953 where = (u.usteed) ? "
\88Æ" : surface(u.ux, u.uy);
1955 pline_The("world spins and %s %s.", what, where);
1957 pline("
\90¢
\8aE
\82ª
\89ñ
\93]
\82µ
\81C%s%s
\81D", where, what);
1958 incr_itimeout(&HDeaf, duration);
1959 context.botl = TRUE;
1962 multi_reason = "unconscious from rotten food";
1964 multi_reason = "
\95\85\82Á
\82½
\90H
\82×
\95¨
\82Å
\88Ó
\8e¯
\82ð
\8e¸
\82Á
\82Ä
\82¢
\82é
\8aÔ
\82É";
1966 nomovemsg = "You are conscious again.";
1968 nomovemsg = "
\82 \82È
\82½
\82Í
\82Ü
\82½
\90³
\8bC
\82Ã
\82¢
\82½
\81D";
1969 afternmv = Hear_again;
1975 /* called when a corpse is selected as food */
1980 int retcode = 0, tp = 0, mnum = otmp->corpsenm;
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;
1989 if (!vegan(&mons[mnum]))
1990 u.uconduct.unvegan++;
1991 if (!vegetarian(&mons[mnum]))
1992 violated_vegetarian();
1994 if (!nonrotting_corpse(mnum)) {
1995 long age = peek_at_iced_corpse_age(otmp);
1997 rotted = (monstermoves - age) / (10L + rn2(20));
2000 else if (otmp->blessed)
2004 if (mnum != PM_ACID_BLOB && !stoneable && !slimeable && rotted > 5L) {
2005 boolean cannibal = maybe_cannibal(mnum, FALSE);
2008 pline("Ulch - that %s was tainted%s!",
2009 (mons[mnum].mlet == S_FUNGUS) ? "fungoid vegetation"
2011 : vegetarian(&mons[mnum]) ? "protoplasm"
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" : "");
2018 if (Sick_resistance) {
2020 pline("It doesn't seem at all sickening, though...");
2022 pline("
\82µ
\82©
\82µ
\81C
\82¢
\82½
\82Á
\82Ä
\8c³
\8bC
\82¾
\81D
\81D
\81D");
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;
2031 make_sick(sick_time, corpse_xname(otmp, "rotted", CXN_NORMAL),
2032 TRUE, SICK_VOMITABLE);
2034 make_sick(sick_time, corpse_xname(otmp, "
\95\85\82Á
\82½", CXN_NORMAL),
2035 TRUE, SICK_VOMITABLE);
2039 pline("(It must have died too long ago to be safe to eat.)");
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)");
2048 } else if (acidic(&mons[mnum]) && !Acid_resistance) {
2051 You("have a very bad case of stomach acid."); /* not body_part() */
2053 pline("
\88Ý
\8e_
\82Ì
\92²
\8eq
\82ª
\82Æ
\82Ä
\82à
\88«
\82¢
\81D");
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);
2061 } else if (poisonous(&mons[mnum]) && rn2(5)) {
2064 pline("Ecch - that must have been poisonous!");
2066 pline("
\83E
\83Q
\83F
\81[
\81C
\97L
\93Å
\82¾
\82Á
\82½
\82É
\82¿
\82ª
\82¢
\82È
\82¢
\81I");
2067 if (!Poison_resistance) {
2070 losehp(rnd(15), !glob ? "poisonous corpse" : "poisonous glob",
2073 losehp(rnd(15), "
\93Å
\82Ì
\8e\80\91Ì
\82Å", KILLED_BY_AN);
2077 You("seem unaffected by the poison.");
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) {
2084 You_feel("%ssick.", (Sick) ? "very " : "");
2086 You("%s
\8bC
\95ª
\82ª
\88«
\82¢
\81D", (Sick) ? "
\82Æ
\82Ä
\82à" : "");
2088 losehp(rnd(8), !glob ? "cadaver" : "rotted glob", KILLED_BY_AN);
2090 losehp(rnd(8), "
\95\85\97\90\8e\80\91Ì
\82Å", KILLED_BY_AN);
2093 /* delay is weight dependent */
2094 context.victual.reqtime = 3 + ((!glob ? mons[mnum].cwt : otmp->owt) >> 6);
2096 if (!tp && !nonrotting_corpse(mnum) && (otmp->orotten || !rn2(7))) {
2097 if (rottenfood(otmp)) {
2098 otmp->orotten = TRUE;
2099 (void) touchfood(otmp);
2103 if (!mons[otmp->corpsenm].cnutrit) {
2104 /* no nutrition: rots away, no message if you passed out */
2107 pline_The("corpse rots away completely.");
2109 pline("
\8e\80\91Ì
\82Í
\8a®
\91S
\82É
\95\85\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D");
2118 consume_oeaten(otmp, 2); /* oeaten >>= 2 */
2119 } else if ((mnum == PM_COCKATRICE || mnum == PM_CHICKATRICE)
2120 && (Stone_resistance || Hallucination)) {
2122 pline("This tastes just like chicken!");
2124 pline("
\82±
\82ê
\82Í
\8c{
\93÷
\82Ì
\96¡
\82¾
\81I");
2125 } else if (mnum == PM_FLOATING_EYE && u.umonnum == PM_RAVEN) {
2127 You("peck the eyeball with delight.");
2129 You("
\96Ú
\8bÊ
\82ð
\82Â
\82ñ
\82Â
\82ñ
\82Â
\82Â
\82¢
\82½
\81D");
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))
2141 && ((rotted < 1) ? TRUE : !rn2(rotted+1)));
2142 const char *pmxnam = food_xname(otmp, FALSE);
2145 if (!strncmpi(pmxnam, "the ", 4))
2147 pline("%s%s %s %s%c",
2148 type_is_pname(&mons[mnum])
2149 ? "" : the_unique_pm(&mons[mnum]) ? "The " : "This ",
2151 Hallucination ? "is" : "tastes",
2152 /* tiger reference is to TV ads for "Frosted Flakes",
2153 breakfast cereal targeted at kids by "Tony the tiger" */
2155 ? (yummy ? ((u.umonnum == PM_TIGER) ? "gr-r-reat" : "gnarly")
2156 : palatable ? "copacetic" : "grody")
2157 : (yummy ? "delicious" : palatable ? "okay" : "terrible"),
2158 (yummy || !palatable) ? '!' : '.');
2160 pline("
\82±
\82Ì%s
\82Í%s%s",
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");
2175 /* called as you start to eat */
2180 const char *old_nomovemsg, *save_nomovemsg;
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;
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 */
2203 old_nomovemsg = nomovemsg;
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;
2215 nomovemsg = save_nomovemsg;
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);
2227 Sprintf(msgbuf, "eating %s", food_xname(otmp, TRUE));
2229 Sprintf(msgbuf, "%s
\82ð
\90H
\82×
\82é", food_xname(otmp, TRUE));
2230 set_occupation(eatfood, msgbuf, 0);
2234 * called on "first bite" of (non-corpse) food.
2235 * used for non-rotten non-tin non-corpse food
2241 switch (otmp->otyp) {
2243 if (u.uhunger <= 200)
2245 pline(Hallucination ? "Oh wow, like, superior, man!"
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"
2249 : "That food really hit the spot!");
2251 : "
\82±
\82Ì
\90H
\82×
\95¨
\82Í
\96{
\93\96\82É
\90\
\82µ
\95ª
\82È
\82¢
\81I");
2252 else if (u.uhunger <= 700)
2254 pline("That satiated your %s!", body_part(STOMACH));
2256 pline("
\96\9e\95 \82É
\82È
\82Á
\82½
\81I");
2259 if (carnivorous(youmonst.data) && !humanoid(youmonst.data))
2261 pline("That tripe ration was surprisingly good!");
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)))
2266 pline(Hallucination ? "Tastes great! Less filling!"
2268 pline(Hallucination ? "
\82¤
\82Ü
\82¢
\81I
\82à
\82Á
\82Æ
\82Ù
\82µ
\82
\82È
\82é
\82Ë
\81I"
2270 : "Mmm, tripe... not bad!");
2272 : "
\82ñ
\81[
\81C
\83\82\83c
\82©
\81D
\81D
\81D
\88«
\82
\82È
\82¢
\81I");
2275 pline("Yak - dog food!");
2277 pline("
\82¤
\82°
\81C
\83h
\83b
\83O
\83t
\81[
\83h
\82¾
\81I");
2278 more_experienced(1, 0);
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);
2287 if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC))) {
2289 pline("%s", "!#?&* elf kibble!");
2291 pline("%s", "
\81I
\81\94\81H
\81\95\81\96 \83G
\83\8b\83N
\82Ì
\90H
\82¢
\95¨
\81I");
2293 } else if (maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF))) {
2295 pline("A little goes a long way.");
2297 pline("
\8f
\82µ
\82Å
\8f\
\95ª
\82¾
\81D");
2303 case HUGE_CHUNK_OF_MEAT:
2306 case CLOVE_OF_GARLIC:
2307 if (is_undead(youmonst.data)) {
2308 make_vomiting((long) rn1(context.victual.reqtime, 5), FALSE);
2313 if (otmp->otyp == SLIME_MOLD && !otmp->cursed
2314 && otmp->spe == context.current_fruit) {
2316 pline("My, that was a %s %s!",
2317 Hallucination ? "primo" : "yummy",
2318 singular(otmp, xname));
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));
2324 } else if (otmp->otyp == APPLE && otmp->cursed && !Sleep_resistance) {
2325 ; /* skip core joke; feedback deferred til fpostfx() */
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) {
2333 pline("Delicious! Must be a Macintosh!");
2335 pline("
\82·
\82Î
\82ç
\82µ
\82¢
\81I
\83}
\83b
\83L
\83\93\83g
\83b
\83V
\83\85\82É
\88á
\82¢
\82È
\82¢
\81I");
2339 } else if (otmp->otyp == APPLE || otmp->otyp == PEAR) {
2340 if (!Hallucination) {
2341 pline("Core dumped.");
2343 /* This is based on an old Usenet joke, a fake a.out manual
2348 pline("%s -- core dumped.",
2350 ? "Segmentation fault"
2356 } else if (otmp->otyp == EGG && stale_egg(otmp)) {
2358 pline("Ugh. Rotten egg."); /* perhaps others like it */
2360 pline("
\83E
\83Q
\83F
\81[
\95\85\82Á
\82½
\97\91\82¾
\81D");
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);
2369 pline("This %s is %s", singular(otmp, xname),
2371 ? (Hallucination ? "grody!" : "terrible!")
2372 : (otmp->otyp == CRAM_RATION
2373 || otmp->otyp == K_RATION
2374 || otmp->otyp == C_RATION)
2376 : Hallucination ? "gnarly!" : "delicious!");
2378 pline("
\82±
\82Ì%s
\82Í%s", singular(otmp, xname),
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");
2388 break; /* default */
2392 /* increment a combat intrinsic with limits on its growth */
2394 bounded_increase(old, inc, typ)
2397 int absold, absinc, sgnold, sgninc;
2399 /* don't include any amount coming from worn rings (caller handles
2400 'protection' differently) */
2401 if (uright && uright->otyp == typ && typ != RIN_PROTECTION)
2403 if (uleft && uleft->otyp == typ && typ != RIN_PROTECTION)
2405 absold = abs(old), absinc = abs(inc);
2406 sgnold = sgn(old), sgninc = sgn(inc);
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;
2421 inc = 0; /* no further increase allowed via this method */
2423 /* put amount from worn rings back */
2424 if (uright && uright->otyp == typ && typ != RIN_PROTECTION)
2426 if (uleft && uleft->otyp == typ && typ != RIN_PROTECTION)
2432 accessory_has_effect(otmp)
2436 pline("Magic spreads through your body as you digest the %s.",
2437 (otmp->oclass == RING_CLASS) ? "ring" : "amulet");
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¯");
2448 int typ = otmp->otyp;
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) {
2457 return; /* died from sink fall */
2459 otmp->known = otmp->dknown = 1; /* by taste */
2460 if (!rn2(otmp->oclass == RING_CLASS ? 3 : 5)) {
2461 switch (otmp->otyp) {
2463 if (!objects[typ].oc_oprop)
2464 break; /* should never happen */
2466 if (!(u.uprops[objects[typ].oc_oprop].intrinsic & FROMOUTSIDE))
2467 accessory_has_effect(otmp);
2469 u.uprops[objects[typ].oc_oprop].intrinsic |= FROMOUTSIDE;
2472 case RIN_SEE_INVISIBLE:
2473 set_mimic_blocking();
2475 if (Invis && !oldprop && !ESee_invisible
2476 && !perceives(youmonst.data) && !Blind) {
2479 pline("Suddenly you can see yourself.");
2481 pline("
\93Ë
\91R
\8e©
\95ª
\8e©
\90g
\82ª
\8c©
\82¦
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D");
2485 case RIN_INVISIBILITY:
2486 if (!oldprop && !EInvis && !BInvis && !See_invisible
2490 Your("body takes on a %s transparency...",
2491 Hallucination ? "normal" : "strange");
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É");
2499 case RIN_PROTECTION_FROM_SHAPE_CHAN:
2502 case RIN_LEVITATION:
2503 /* undo the `.intrinsic |= FROMOUTSIDE' done above */
2504 u.uprops[LEVITATION].intrinsic = oldprop;
2507 incr_itimeout(&HLevitation, d(10, 20));
2511 } /* inner switch */
2512 break; /* default case of outer switch */
2515 accessory_has_effect(otmp);
2516 if (adjattrib(A_CHA, otmp->spe, -1))
2519 case RIN_GAIN_STRENGTH:
2520 accessory_has_effect(otmp);
2521 if (adjattrib(A_STR, otmp->spe, -1))
2524 case RIN_GAIN_CONSTITUTION:
2525 accessory_has_effect(otmp);
2526 if (adjattrib(A_CON, otmp->spe, -1))
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);
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);
2539 case RIN_PROTECTION:
2540 accessory_has_effect(otmp);
2541 HProtection |= FROMOUTSIDE;
2542 u.ublessed = bounded_increase(u.ublessed, otmp->spe,
2546 case RIN_FREE_ACTION:
2547 /* Give sleep resistance instead */
2548 if (!(HSleep_resistance & FROMOUTSIDE))
2549 accessory_has_effect(otmp);
2550 if (!Sleep_resistance)
2552 You_feel("wide awake.");
2554 You("
\82Ï
\82Á
\82¿
\82è
\96Ú
\82ª
\82³
\82ß
\82½
\81D");
2555 HSleep_resistance |= FROMOUTSIDE;
2557 case AMULET_OF_CHANGE:
2558 accessory_has_effect(otmp);
2562 You("are suddenly very %s!",
2563 flags.female ? "feminine" : "masculine");
2565 You("
\93Ë
\91R
\82Æ
\82Ä
\82à%s
\82Á
\82Û
\82
\82È
\82Á
\82½
\81I",
2566 flags.female ? "
\8f\97" : "
\92j");
2570 case AMULET_OF_UNCHANGING:
2571 /* un-change: it's a pun */
2572 if (!Unchanging && Upolyd) {
2573 accessory_has_effect(otmp);
2578 case AMULET_OF_STRANGULATION: /* bad idea! */
2579 /* no message--this gives no permanent effect */
2582 case AMULET_OF_RESTFUL_SLEEP: { /* another bad idea! */
2583 long newnap = (long) rnd(100), oldnap = (HSleepy & TIMEOUT);
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;
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.
2604 /* called after eating non-food */
2608 struct obj *otmp = context.victual.piece;
2610 /* lesshungry wants an occupation to handle choke messages correctly */
2612 set_occupation(eatfood, "eating non-food", 0);
2614 set_occupation(eatfood, "
\90H
\82×
\82é", 0);
2615 lesshungry(context.victual.nmod);
2617 context.victual.piece = (struct obj *) 0;
2618 context.victual.o_id = 0;
2619 context.victual.eating = 0;
2620 if (otmp->oclass == COIN_CLASS) {
2624 useupf(otmp, otmp->quan);
2625 vault_gd_watching(GD_EATGOLD);
2628 if (objects[otmp->otyp].oc_material == PAPER) {
2630 if (otmp->otyp == SCR_MAIL)
2633 pline("This junk mail is less than satisfying.");
2635 pline("
\82±
\82Ì
\83S
\83~
\83\81\81[
\83\8b\82Í
\96\9e\91«
\82É
\82Í
\82Ù
\82Ç
\89\93\82¢
\81D");
2638 if (otmp->otyp == SCR_SCARE_MONSTER)
2639 /* to eat scroll, hero is currently polymorphed into a monster */
2641 pline("Yuck%c", otmp->blessed ? '!' : '.');
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"))
2648 pline("Yum%c", otmp->blessed ? '!' : '.');
2650 pline("
\82¤
\82Ü
\82¢%s", otmp->blessed ? "
\81I" : "
\81D");
2653 pline("Needs salt...");
2655 pline("
\96¡
\82ª
\82¤
\82·
\82¢
\81D
\81D
\81D");
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) {
2662 } else if (otmp->otyp == LEASH && otmp->leashmon) {
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 */
2670 pline(Hallucination ? "Four out of five dentists agree."
2671 : "That was pure chewing satisfaction!");
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");
2676 exercise(A_WIS, TRUE);
2678 if (otmp->otyp == FLINT && !otmp->cursed) {
2679 /* chewable vitamin for kids based on "The Flintstones" TV cartoon */
2681 pline("Yabba-dabba delicious!");
2683 pline("
\83\84\83b
\83o
\83_
\83b
\83o
\82¤
\82Ü
\82¢
\81I");
2684 exercise(A_CON, TRUE);
2687 if (otmp == uwep && otmp->quan == 1L)
2689 if (otmp == uquiver && otmp->quan == 1L)
2691 if (otmp == uswapwep && otmp->quan == 1L)
2697 unpunish(); /* but no useup() */
2698 else if (carried(otmp))
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[] = {
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"
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Î"
2720 STATIC_OVL const char *
2724 if (otmp->oclass == FOOD_CLASS)
2729 if (otmp->oclass == GEM_CLASS && objects[otmp->otyp].oc_material == GLASS
2731 makeknown(otmp->otyp);
2732 return foodwords[objects[otmp->otyp].oc_material];
2735 /* called after consuming (non-corpse) food */
2740 switch (otmp->otyp) {
2741 case SPRIG_OF_WOLFSBANE:
2742 if (u.ulycn >= LOW_PM || is_were(youmonst.data))
2747 || !attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_BLND))
2748 make_blinded((long) u.ucreamed, TRUE);
2750 case FORTUNE_COOKIE:
2751 outrumor(bcsign(otmp), BY_COOKIE);
2753 u.uconduct.literate++;
2755 case LUMP_OF_ROYAL_JELLY:
2756 /* This stuff seems to be VERY healthy! */
2757 gainstr(otmp, 1, TRUE);
2759 u.mh += otmp->cursed ? -rnd(20) : rnd(20);
2760 if (u.mh > u.mhmax) {
2764 } else if (u.mh <= 0) {
2768 u.uhp += otmp->cursed ? -rnd(20) : rnd(20);
2769 if (u.uhp > u.uhpmax) {
2773 } else if (u.uhp <= 0) {
2774 killer.format = KILLED_BY_AN;
2776 Strcpy(killer.name, "rotten lump of royal jelly");
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Å");
2788 if (flesh_petrifies(&mons[otmp->corpsenm])) {
2789 if (!Stone_resistance
2790 && !(poly_when_stoned(youmonst.data)
2791 && polymon(PM_STONE_GOLEM))) {
2794 Sprintf(killer.name, "%s egg",
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);
2801 /* note: no "tastes like chicken" message for eggs */
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);
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)
2817 verbalize("Heigh-ho, ho-hum, I think I'll skip work today.");
2819 verbalize("
\83n
\83C
\83z
\81[
\81C
\83n
\83C
\83z
\81[
\81C
\8d¡
\93ú
\82Í
\8bx
\82Ý
\81D");
2820 else if (Deaf || !flags.acoustics)
2822 You("fall asleep.");
2824 You("
\96°
\82è
\82É
\97\8e\82¿
\82½
\81D");
2827 You_hear("sinister laughter as you fall asleep...");
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);
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 *));
2847 const char *odesc = OBJ_DESCR(objects[otmp->otyp]);
2849 if (odesc && (otmp->oclass == SPBOOK_CLASS)) {
2850 if (!strcmp(odesc, "leather"))
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.
2863 edibility_prompts(otmp)
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.
2871 char buf[BUFSZ], foodsmell[BUFSZ],
2872 it_or_they[QBUFSZ], eat_it_anyway[QBUFSZ];
2874 char buf[BUFSZ], foodsmell[BUFSZ],
2875 eat_it_anyway[QBUFSZ];
2877 boolean cadaver = (otmp->otyp == CORPSE || otmp->globby),
2878 stoneorslime = FALSE;
2879 int material = objects[otmp->otyp].oc_material, mnum = otmp->corpsenm;
2883 Strcpy(foodsmell, Tobjnam(otmp, "smell"));
2885 Strcpy(foodsmell, xname(otmp));
2888 Strcpy(it_or_they, (otmp->quan == 1L) ? "it" : "they");
2891 Sprintf(eat_it_anyway, "Eat %s anyway?",
2892 (otmp->quan == 1L) ? "it" : "one");
2894 Strcpy(eat_it_anyway, "
\82»
\82ê
\82Å
\82à
\90H
\82×
\82é
\81H");
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));
2902 if (mnum == PM_GREEN_SLIME || otmp->otyp == GLOB_OF_GREEN_SLIME)
2903 stoneorslime = (!Unchanging && !slimeproof(youmonst.data));
2905 if (cadaver && !nonrotting_corpse(mnum)) {
2906 long age = peek_at_iced_corpse_age(otmp);
2908 /* worst case rather than random
2909 in this calculation to force prompt */
2910 rotted = (monstermoves - age) / (10L + 0 /* was rn2(20) */);
2913 else if (otmp->blessed)
2919 * These problems with food should be checked in
2920 * order from most detrimental to least detrimental.
2922 if (cadaver && mnum != PM_ACID_BLOB && rotted > 5L && !Sick_resistance) {
2925 Sprintf(buf, "%s like %s could be tainted! %s", foodsmell, it_or_they,
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);
2931 if (yn_function(buf, ynchars, 'n') == 'n')
2938 Sprintf(buf, "%s like %s could be something very dangerous! %s",
2939 foodsmell, it_or_they, eat_it_anyway);
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);
2944 if (yn_function(buf, ynchars, 'n') == 'n')
2949 if (otmp->orotten || (cadaver && rotted > 3L)) {
2952 Sprintf(buf, "%s like %s could be rotten! %s", foodsmell, it_or_they,
2955 Sprintf(buf, "%s
\82Í
\95\85\82Á
\82½
\82æ
\82¤
\82È
\82É
\82¨
\82¢
\82ª
\82·
\82é
\81I%s", foodsmell,
2958 if (yn_function(buf, ynchars, 'n') == 'n')
2963 if (cadaver && poisonous(&mons[mnum]) && !Poison_resistance) {
2966 Sprintf(buf, "%s like %s might be poisonous! %s", foodsmell,
2967 it_or_they, eat_it_anyway);
2969 Sprintf(buf, "%s
\82Í
\93Å
\82ð
\82à
\82Á
\82Ä
\82¢
\82»
\82¤
\82È
\82É
\82¨
\82¢
\82ª
\82·
\82é
\81I%s", foodsmell,
2972 if (yn_function(buf, ynchars, 'n') == 'n')
2977 if (otmp->otyp == APPLE && otmp->cursed && !Sleep_resistance) {
2978 /* causes sleep, for long enough to be dangerous */
2980 Sprintf(buf, "%s like %s might have been poisoned. %s", foodsmell,
2981 it_or_they, eat_it_anyway);
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,
2986 return (yn_function(buf, ynchars, 'n') == 'n') ? 1 : 2;
2988 if (cadaver && !vegetarian(&mons[mnum]) && !u.uconduct.unvegetarian
2989 && Role_if(PM_MONK)) {
2991 Sprintf(buf, "%s unhealthy. %s", foodsmell, eat_it_anyway);
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')
2999 if (cadaver && acidic(&mons[mnum]) && !Acid_resistance) {
3001 Sprintf(buf, "%s rather acidic. %s", foodsmell, eat_it_anyway);
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')
3009 if (Upolyd && u.umonnum == PM_RUST_MONSTER && is_metallic(otmp)
3010 && otmp->oerodeproof) {
3012 Sprintf(buf, "%s disgusting to you right now. %s", foodsmell,
3015 Sprintf(buf, "%s
\82Í
\8bC
\95ª
\82ª
\88«
\82
\82È
\82é
\82É
\82¨
\82¢
\82ª
\82·
\82é
\81D%s", foodsmell,
3018 if (yn_function(buf, ynchars, 'n') == 'n')
3025 * Breaks conduct, but otherwise safe.
3027 if (!u.uconduct.unvegan
3028 && ((material == LEATHER || material == BONE
3029 || material == DRAGON_HIDE || material == WAX)
3030 || (cadaver && !vegan(&mons[mnum])))) {
3032 Sprintf(buf, "%s foul and unfamiliar to you. %s", foodsmell,
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,
3038 if (yn_function(buf, ynchars, 'n') == 'n')
3043 if (!u.uconduct.unvegetarian
3044 && ((material == LEATHER || material == BONE
3045 || material == DRAGON_HIDE)
3046 || (cadaver && !vegetarian(&mons[mnum])))) {
3048 Sprintf(buf, "%s unfamiliar to you. %s", foodsmell, eat_it_anyway);
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')
3057 if (cadaver && mnum != PM_ACID_BLOB && rotted > 5L && Sick_resistance) {
3058 /* Tainted meat with Sick_resistance */
3060 Sprintf(buf, "%s like %s could be tainted! %s",
3061 foodsmell, it_or_they, eat_it_anyway);
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);
3066 if (yn_function(buf, ynchars, 'n') == 'n')
3079 int basenutrit; /* nutrition of full item */
3080 boolean dont_start = FALSE, nodelicious = FALSE;
3084 pline("If you can't breathe air, how can you consume solids?");
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");
3089 if (!(otmp = floorfood("eat", 0)))
3091 if (check_capacity((char *) 0))
3095 int res = edibility_prompts(otmp);
3100 "%s stops tingling and your sense of smell returns to normal.",
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",
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....
3117 if (!is_edible(otmp)) {
3119 You("cannot eat that!");
3121 You("
\82»
\82ê
\82ð
\90H
\82×
\82ç
\82ê
\82È
\82¢
\81I");
3123 } else if ((otmp->owornmask & (W_ARMOR | W_TOOL | W_AMUL | W_SADDLE))
3125 /* let them eat rings */
3127 You_cant("eat %s you're wearing.", something);
3129 You("
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é
\8aÔ
\82Í
\90H
\82×
\82ê
\82È
\82¢
\81D");
3131 } else if (!(carried(otmp) ? retouch_object(&otmp, FALSE)
3132 : touch_artifact(otmp, &youmonst))) {
3133 return 1; /* got blasted so use a turn */
3135 if (is_metallic(otmp) && u.umonnum == PM_RUST_MONSTER
3136 && otmp->oerodeproof) {
3137 otmp->rknown = TRUE;
3138 if (otmp->quan > 1L) {
3140 (void) splitobj(otmp, otmp->quan - 1L);
3142 otmp = splitobj(otmp, 1L);
3145 pline("Ulch - that %s was rustproofed!", xname(otmp));
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);
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.
3156 if (welded(otmp) || (otmp->cursed && (otmp->owornmask & W_RING))) {
3157 otmp->bknown = 1; /* for ring; welded() does this for weapon */
3159 You("spit out %s.", the(xname(otmp)));
3161 You("%s
\82ð
\93f
\82«
\8fo
\82µ
\82½
\81D", xname(otmp));
3164 You("spit %s out onto the %s.", the(xname(otmp)),
3165 surface(u.ux, u.uy));
3167 You("%s
\82ð%s
\82É
\93f
\82«
\8fo
\82µ
\82½
\81D", the(xname(otmp)),
3168 surface(u.ux, u.uy));
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);
3181 /* KMH -- Slow digestion is... indigestible */
3182 if (otmp->otyp == RIN_SLOW_DIGESTION) {
3184 pline("This ring is indigestible!");
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)
3193 if (otmp->oclass != FOOD_CLASS) {
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)
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 */
3212 basenutrit = objects[otmp->otyp].oc_nutrition;
3214 if (otmp->otyp == SCR_MAIL) {
3219 context.victual.nmod = basenutrit;
3220 context.victual.eating = TRUE; /* needed for lesshungry() */
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++;
3232 (void) rottenfood(otmp);
3234 } else if (objects[otmp->otyp].oc_material == PAPER)
3237 if (otmp->oclass == WEAPON_CLASS && otmp->opoisoned) {
3239 pline("Ecch - that must have been poisonous!");
3241 pline("
\83E
\83Q
\83F
\81[
\81C
\97L
\93Å
\82¾
\82Á
\82½
\82É
\88á
\82¢
\82È
\82¢
\81I");
3242 if (!Poison_resistance) {
3245 losehp(rnd(15), xname(otmp), KILLED_BY_AN);
3249 Sprintf(jbuf, "%s
\82Å", xname(otmp));
3250 losehp(rnd(15), jbuf, KILLED_BY_AN);
3255 You("seem unaffected by the poison.");
3257 You("
\93Å
\82Ì
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82¢
\82æ
\82¤
\82¾
\81D");
3258 } else if (!nodelicious) {
3260 pline("%s%s is delicious!",
3262 && otmp->oartifact < ART_ORB_OF_DETECTION)
3265 (otmp->oclass == COIN_CLASS)
3267 : singular(otmp, xname));
3269 pline("
\82±
\82Ì%s
\82Í
\8e|
\82¢
\81I",
3270 otmp->oclass == COIN_CLASS
3272 : singular(otmp, xname));
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.
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;
3292 You("resume your meal.");
3294 You("
\90H
\8e\96\82ð
\8dÄ
\8aJ
\82µ
\82½
\81D");
3295 start_eating(context.victual.piece);
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) {
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;
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.
3321 if (otmp->otyp == CORPSE || otmp->globby) {
3322 int tmp = eatcorpse(otmp);
3326 context.victual.piece = (struct obj *) 0;
3327 context.victual.o_id = 0;
3331 /* if not used up, eatcorpse sets up reqtime and may modify oeaten */
3333 /* No checks for WAX, LEATHER, BONE, DRAGON_HIDE. These are
3334 * all handled in the != FOOD_CLASS case, above.
3336 switch (objects[otmp->otyp].oc_material) {
3338 u.uconduct.unvegan++;
3339 if (otmp->otyp != EGG) {
3340 violated_vegetarian();
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++;
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;
3362 consume_oeaten(otmp, 1); /* oeaten >>= 1 */
3367 /* re-calc the nutrition */
3368 basenutrit = (int) obj_nutrition(otmp);
3371 "before rounddiv: victual.reqtime == %d, oeaten == %d, basenutrit == %d",
3372 context.victual.reqtime, otmp->oeaten, basenutrit);
3374 context.victual.reqtime = (basenutrit == 0) ? 0
3375 : rounddiv(context.victual.reqtime * (long) otmp->oeaten, basenutrit);
3377 debugpline1("after rounddiv: victual.reqtime == %d",
3378 context.victual.reqtime);
3380 * calculate the modulo value (nutrit. units per round eating)
3381 * note: this isn't exact - you actually lose a little nutrition due
3383 * TODO: add in a "remainder" value to be given at the end of the meal.
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);
3392 context.victual.nmod = context.victual.reqtime % otmp->oeaten;
3393 context.victual.canchoke = (u.uhs == SATIATED);
3407 if (!carrying(TIN)) {
3409 You("have no tin to open.");
3411 You("
\8aÊ
\82ð
\8e\9d\82Á
\82Ä
\82¢
\82È
\82¢
\81D");
3416 if (obj->cursed && obj->bknown) {
3420 if (ynq(safe_qbuf(qbuf, "Really wield ", "?",
3421 obj, doname, thesimpleoname, "that")) != 'y')
3423 if (ynq(safe_qbuf(qbuf, "
\96{
\93\96\82É", "
\82ð
\91\95\94õ
\82·
\82é
\81H",
3424 obj, doname, thesimpleoname, "
\82»
\82ê")) != 'y')
3428 if (!wield_tool(obj, "use"))
3433 otmp = getobj(comestibles, "open");
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.
3447 if (context.victual.canchoke && u.uhunger >= 2000) {
3448 choke(context.victual.piece);
3451 if (context.victual.doreset) {
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)) {
3463 consume_oeaten(context.victual.piece, -1); /* -= 1 */
3465 force_save_hs = FALSE;
3470 /* as time goes by - called by moveloop(every move) & domove(melee attack) */
3474 if (u.uinvulnerable)
3475 return; /* you don't feel hungrier */
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))
3486 u.uhunger--; /* ordinary food consumption */
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)))
3493 if (near_capacity() > SLT_ENCUMBER)
3495 } else { /* even turns */
3498 /* Conflict uses up food too */
3499 if (HConflict || (EConflict & (~W_ARTI)))
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 */
3505 if (uleft && (uleft->spe || !objects[uleft->otyp].oc_charged))
3513 if (uright && (uright->spe || !objects[uright->otyp].oc_charged))
3527 /* called after vomiting and after performing feats of magic */
3536 /* called after eating (and after drinking fruit juice) */
3541 /* See comments in newuhs() for discussion on force_save_hs */
3542 boolean iseating = (occupation == eatfood) || force_save_hs;
3544 debugpline1("lesshungry(%d)", num);
3546 if (u.uhunger >= 2000) {
3547 if (!iseating || context.victual.canchoke) {
3549 choke(context.victual.piece);
3552 choke(occupation == opentin ? context.tin.tin
3553 : (struct obj *) 0);
3554 /* no reset_eat() */
3557 /* Have lesshungry() report when you're nearly full so all eating
3558 * warns when you're about to choke.
3560 if (u.uhunger >= 1500) {
3561 if (!context.victual.eating
3562 || (context.victual.eating && !context.victual.fullwarn)) {
3564 pline("You're having a hard time getting all of it down.");
3566 pline("
\91S
\82Ä
\82ð
\88ù
\82Ý
\82±
\82Þ
\82É
\82Í
\8e\9e\8aÔ
\82ª
\82©
\82©
\82é
\81D");
3568 nomovemsg = "You're finally finished.";
3570 nomovemsg = "
\82â
\82Á
\82Æ
\90H
\82×
\8fI
\82¦
\82½
\81D";
3571 if (!context.victual.eating) {
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 */
3579 if (yn_function("Continue eating?", ynchars, 'n')
3581 if (yn_function("
\90H
\82×
\91±
\82¯
\82Ü
\82·
\82©
\81H", ynchars, 'n')
3584 nomovemsg = (char *) 0;
3598 (void) Hear_again();
3599 if (u.uhs > FAINTING)
3609 return (boolean) (u.uhs == FAINTED);
3612 /* call when a faint must be prematurely terminated */
3616 if (afternmv == unfaint)
3618 unmul("You revive.");
3620 unmul("
\82 \82È
\82½
\82Í
\8bC
\82ª
\82Â
\82¢
\82½
\81D");
3623 /* compute and comment on your (new?) hunger status */
3629 static unsigned save_hs;
3630 static boolean saved_hs = FALSE;
3635 : (h > 150) ? NOT_HUNGRY
3636 : (h > 50) ? HUNGRY : (h > 0) ? WEAK : FAINTING;
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.
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.
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.
3660 if (occupation == eatfood || force_save_hs) {
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);
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;
3684 /* stop what you're doing, then faint */
3687 You("faint from lack of food.");
3689 You("
\95 \82ª
\8c¸
\82Á
\82Ä
\93|
\82ê
\82½
\81D");
3690 incr_itimeout(&HDeaf, duration);
3691 context.botl = TRUE;
3694 multi_reason = "fainted from lack of food";
3696 multi_reason = "
\8bó
\95 \82Å
\91²
\93|
\82µ
\82Ä
\82¢
\82é
\8aÔ
\82É";
3698 nomovemsg = "You regain consciousness.";
3700 nomovemsg = "
\82 \82È
\82½
\82Í
\90³
\8bC
\82Ã
\82¢
\82½
\81D";
3705 selftouch("Falling, you");
3707 selftouch("
\97\8e\82¿
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í");
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))) {
3718 You("die from starvation.");
3720 You("
\89ì
\8e\80\82µ
\82½
\81D");
3721 killer.format = KILLED_BY;
3723 Strcpy(killer.name, "starvation");
3725 Strcpy(killer.name, "
\90H
\97¿
\95s
\91«
\82Å
\89ì
\8e\80\82µ
\82½");
3727 /* if we return, we lifesaved, and that calls newuhs */
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 */
3752 if (Hallucination) {
3754 You((!incr) ? "now have a lesser case of the munchies."
3755 : "are getting the munchies.");
3758 You("
\83n
\83\89\83w
\83\8a\82ª
\8c¸
\82Á
\82½
\81D");
3760 pline("
\83n
\83\89\83w
\83\8a\83w
\83\8a\83n
\83\89\81D");
3765 You((!incr) ? "only feel hungry now."
3767 You((!incr) ? "
\92P
\82É
\95 \83y
\83R
\8fó
\91Ô
\82É
\82È
\82Á
\82½
\81D"
3772 ? "
\8bó
\95 \8a´
\82ð
\8a´
\82¶
\82½
\81D"
3774 : "are beginning to feel hungry.");
3776 : "
\8bó
\95 \8a´
\82ð
\82¨
\82Ú
\82¦
\82Í
\82¶
\82ß
\82½
\81D");
3777 if (incr && occupation
3778 && (occupation != eatfood && occupation != opentin))
3780 context.travel = context.travel1 = context.mv = context.run = 0;
3785 pline((!incr) ? "You still have the munchies."
3787 pline((!incr) ? "
\83n
\83\89\83w
\83\8a\82ª
\8c¸
\82ç
\82È
\82¢
\81D"
3789 : "The munchies are interfering with your motor capabilities.");
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)))
3795 pline("%s needs food, badly!",
3797 pline("%s
\82É
\82Í
\8e\8a\8b}
\90H
\97¿
\82ª
\95K
\97v
\82¾
\81I",
3798 (Role_if(PM_WIZARD) || Role_if(PM_VALKYRIE))
3803 : "
\83G
\83\8b\83t");
3809 ? "
\90\8a\8eã
\8fó
\91Ô
\82É
\82È
\82Á
\82½
\81D"
3811 : (u.uhunger < 45) ? "feel weak."
3813 : (u.uhunger < 45) ? "
\90\8a\8eã
\82µ
\82Ä
\82«
\82½
\81D"
3815 : "are beginning to feel weak.");
3817 : "
\8eã
\82
\82È
\82Á
\82Ä
\82«
\82½
\82æ
\82¤
\82É
\8a´
\82¶
\82½
\81D");
3818 if (incr && occupation
3819 && (occupation != eatfood && occupation != opentin))
3821 context.travel = context.travel1 = context.mv = context.run = 0;
3827 if ((Upolyd ? u.mh : u.uhp) < 1) {
3829 You("die from hunger and exhaustion.");
3831 You("
\8bó
\95 \82Æ
\90\8a\8eã
\82Å
\8e\80\82ñ
\82¾
\81D");
3832 killer.format = KILLED_BY;
3834 Strcpy(killer.name, "exhaustion");
3836 Strcpy(killer.name, "
\8bó
\95 \82Æ
\90\8a\8eã
\82Å
\8e\80\82ñ
\82¾");
3843 /* Returns an object representing food.
3844 * Object may be either on floor or in inventory.
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
3853 floorfood(verb, corpsecheck)
3855 int corpsecheck; /* 0, no check, 1, corpses, 2, tinnable corpses */
3857 register struct obj *otmp;
3860 boolean feeding = !strcmp(verb, "eat"), /* corpsecheck==0 */
3861 offering = !strcmp(verb, "sacrifice"); /* corpsecheck==1 */
3864 const char *jverb = trans_verb(verb)->jp;
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))))
3875 if (feeding && metallivorous(youmonst.data)) {
3877 struct trap *ttmp = t_at(u.ux, u.uy);
3879 if (ttmp && ttmp->tseen && ttmp->ttyp == BEAR_TRAP) {
3880 boolean u_in_beartrap = (u.utrap && u.utraptype == TT_BEARTRAP);
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... */
3886 Sprintf(qbuf, "There is a bear trap here (%s); eat it?",
3887 u_in_beartrap ? "holding you" : "armed");
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");
3892 if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
3896 return mksobj(BEARTRAP, TRUE, FALSE);
3897 } else if (c == 'q') {
3898 return (struct obj *) 0;
3902 if (youmonst.data != &mons[PM_RUST_MONSTER]
3903 && (gold = g_at(u.ux, u.uy)) != 0) {
3905 if (gold->quan == 1L)
3906 Sprintf(qbuf, "There is 1 gold piece here; eat it?");
3908 Sprintf(qbuf, "There are %ld gold pieces here; eat them?",
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);
3913 if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
3915 } else if (c == 'q') {
3916 return (struct obj *) 0;
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) {
3924 ? (otmp->otyp == CORPSE
3925 && (corpsecheck == 1 || tinnable(otmp)))
3926 : feeding ? (otmp->oclass != COIN_CLASS && is_edible(otmp))
3927 : otmp->oclass == FOOD_CLASS) {
3929 boolean one = (otmp->quan == 1L);
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;
3941 /* "There is <an object> here; <verb> it?" or
3942 "There are <N objects> here; <verb> one?" */
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");
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©");
3954 if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y')
3957 return (struct obj *) 0;
3962 /* We cannot use ALL_CLASSES since that causes getobj() to skip its
3963 * "ugly checks" and we need to check for inedible items.
3965 otmp = getobj(feeding ? allobj : offering ? offerfodder : comestibles,
3967 if (corpsecheck && otmp && !(offering && otmp->oclass == AMULET_CLASS))
3968 if (otmp->otyp != CORPSE || (corpsecheck == 2 && !tinnable(otmp))) {
3970 You_cant("%s that!", verb);
3972 You_cant("
\82»
\82ê
\82ð%s
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81I", jverb);
3973 return (struct obj *) 0;
3978 /* Side effects of vomiting */
3979 /* added nomul (MRS) - it makes sense, you're too busy being sick! */
3981 vomit() /* A good idea from David Neves */
3983 if (cantvomit(youmonst.data)) {
3984 /* doesn't cure food poisoning; message assumes that we aren't
3985 dealing with some esoteric body_part() */
3987 Your("jaw gapes convulsively.");
3989 Your("
\82 \82²
\82Í
\94
\8dì
\93I
\82É
\91å
\82«
\82
\8aJ
\82¢
\82½
\81D");
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)
3998 Your("%s heaves convulsively!", body_part(STOMACH));
4000 Your("%s
\82Í
\8c\83\82µ
\82¢
\93f
\82«
\8bC
\82ð
\82à
\82æ
\82¨
\82µ
\82½
\81I", body_part(STOMACH));
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 */
4009 multi_reason = "vomiting";
4011 multi_reason = "
\9aq
\93f
\82µ
\82Ä
\82¢
\82é
\8dÅ
\92\86\82É";
4012 nomovemsg = You_can_move_again;
4017 eaten_stat(base, obj)
4021 long uneaten_amt, full_amount;
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) {
4028 "partly eaten food (%ld) more nutritious than untouched food (%ld)",
4029 uneaten_amt, full_amount);
4030 uneaten_amt = full_amount;
4033 base = (int) (full_amount ? (long) base * uneaten_amt / full_amount : 0L);
4034 return (base < 1) ? 1 : base;
4037 /* reduce obj's oeaten field, making sure it never hits or passes 0 */
4039 consume_oeaten(obj, amt)
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.
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.
4070 /* bit shift to divide the remaining amount of food */
4071 obj->oeaten >>= amt;
4073 /* simple decrement; value is negative so we actually add it */
4074 if ((int) obj->oeaten > -amt)
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 */
4088 /* called when eatfood occupation has been interrupted,
4089 or in the case of theft, is about to be interrupted */
4091 maybe_finished_meal(stopping)
4094 /* in case consume_oeaten() has decided that the food is all gone */
4095 if (occupation == eatfood
4096 && context.victual.usedtime >= context.victual.reqtime) {
4098 occupation = 0; /* for do_reset_eat */
4099 (void) eatfood(); /* calls done_eating() to use up
4100 context.victual.piece */
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. :-] */
4118 if (occupation != opentin)
4120 otin = context.tin.tin;
4121 /* make sure hero still has access to tin */
4123 && (!obj_here(otin, u.ux, u.uy) || !can_reach_floor(TRUE)))
4125 /* unknown tin is assumed to be helpful */
4128 /* known tin is helpful if it will stop life-threatening problem */
4129 mndx = otin->corpsenm;
4131 /* note: not used; hunger code bypasses stop_occupation() when eating */
4133 return (boolean) (mndx != NON_PM || otin->spe == 1);
4134 /* flesh from lizards and acidic critters stops petrification */
4136 return (boolean) (mndx >= LOW_PM
4137 && (mndx == PM_LIZARD || acidic(&mons[mndx])));
4138 /* no tins can cure these (yet?) */