-/* 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 $ */
+/* NetHack 3.6 eat.c $NHDT-Date: 1574900825 2019/11/28 00:27:05 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.206 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
/* JNetHack Copyright */
/* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
-/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019 */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020 */
/* JNetHack may be freely redistributed. See license for details. */
#include "hack.h"
STATIC_DCL void FDECL(consume_tin, (const char *));
STATIC_DCL void FDECL(start_tin, (struct obj *));
STATIC_DCL int FDECL(eatcorpse, (struct obj *));
-STATIC_DCL void FDECL(start_eating, (struct obj *));
+STATIC_DCL void FDECL(start_eating, (struct obj *, BOOLEAN_P));
STATIC_DCL void FDECL(fprefx, (struct obj *));
STATIC_DCL void FDECL(fpostfx, (struct obj *));
STATIC_DCL int NDECL(bite);
STATIC_OVL boolean force_save_hs = FALSE;
/* see hunger states in hack.h - texts used on bottom line */
-#if 0 /*JP*/
+#if 0 /*JP:T*/
const char *hu_stat[] = { "Satiated", " ", "Hungry ", "Weak ",
"Fainting", "Fainted ", "Starved " };
#else
int nut; /* nutrition */
Bitfield(fodder, 1); /* stocked by health food shops */
Bitfield(greasy, 1); /* causes slippery fingers */
-#if 0 /*JP*/
+#if 0 /*JP:T*/
} tintxts[] = { { "rotten", -50, 0, 0 }, /* ROTTEN_TIN = 0 */
{ "homemade", 50, 1, 0 }, /* HOMEMADE_TIN = 1 */
{ "soup made from", 20, 1, 0 },
if (noncorporeal(pd)) {
if (visflag)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s brain is unharmed.",
(mdef == &youmonst) ? "Your" : s_suffix(Monnam(mdef)));
#else
pline("Ingesting that is fatal.");
*/
pline("\8eæ\82è\8d\9e\82ñ\82¾\82ç\82·\82®\82É\8e\80\82ñ\82Å\82µ\82Ü\82Á\82½\81D");
-#if 0 /*JP*/
+#if 0 /*JP:T*/
Sprintf(killer.name, "unwisely ate the brain of %s", pd->mname);
killer.format = NO_KILLER_PREFIX;
#else
*dmg_p += xtra_dmg;
give_nutrit = TRUE;
if (*dmg_p >= mdef->mhp && visflag && canspotmon(mdef))
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("%s last thought fades away...",
s_suffix(Monnam(mdef)));
#else
pline("Eating that is instantly fatal.");
*/
pline("\90H\82×\82½\82ç\82·\82®\82É\8e\80\82ñ\82Å\82µ\82Ü\82Á\82½\81D");
-#if 0 /*JP*/
+#if 0 /*JP:T*/
Sprintf(killer.name, "unwisely ate the body of %s", mons[pm].mname);
killer.format = NO_KILLER_PREFIX;
#else
char buf[BUFSZ];
if (Hallucination)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
Sprintf(buf, "What a pity--you just ruined a future piece of %sart!",
ACURR(A_CHA) > 15 ? "fine " : "");
#else
/*JP
You_feel("grounded in reality.");
*/
- You("\8eÀ\82Í\83A\81[\83X\82³\82ê\82Ä\82¢\82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
+ You("\8eÀ\82Í\83A\81[\83X\82³\82ê\82Ä\82¢\82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
else
/*JP
Your("health currently feels amplified!");
*/
- pline("\8c\92\8dN\82ª\91\9d\95\9d\82³\82ê\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81I");
+ pline("\8c\92\8dN\82ª\91\9d\95\9d\82³\82ê\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81I");
HShock_resistance |= FROMOUTSIDE;
}
break;
case TELEPORT_CONTROL:
debugpline0("Trying to give teleport control");
if (!(HTeleport_control & FROMOUTSIDE)) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
You_feel(Hallucination ? "centered in your personal space."
: "in control of yourself.");
#else
case TELEPAT:
debugpline0("Trying to give telepathy");
if (!(HTelepat & FROMOUTSIDE)) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
You_feel(Hallucination ? "in touch with the cosmos."
: "a strange mental acuity.");
#else
char buf[BUFSZ];
u.uconduct.polyselfs++; /* you're changing form */
-#if 0 /*JP*/
+#if 0 /*JP:T*/
You_cant("resist the temptation to mimic %s.",
Hallucination ? "an orange" : "a pile of gold");
#else
case PM_DOPPELGANGER:
case PM_SANDESTIN: /* moot--they don't leave corpses */
if (Unchanging) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
You_feel("momentarily different."); /* same as poly trap */
#else
You_feel("\88ê\8fu\88á\82Á\82½\8a´\82¶\82ª\82µ\82½\81D"); /* same as poly trap */
if (tintxts[r].greasy) {
/* Assume !Glib, because you can't open tins when Glib. */
- incr_itimeout(&Glib, rnd(15));
+ make_glib(rn1(11, 5)); /* 5..15 */
#if 0 /*JP*/
pline("Eating %s food made your %s very slippery.",
- tintxts[r].txt, makeplural(body_part(FINGER)));
+ tintxts[r].txt, fingers_or_gloves(TRUE));
#else
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",
- body_part(FINGER));
+ fingers_or_gloves(TRUE));
#endif
}
} else { /* spinach... */
if (tin->cursed) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("It contains some decaying%s%s substance.",
Blind ? "" : " ", Blind ? "" : hcolor(NH_GREEN));
#else
*/
u.uconduct.food++; /* don't need vegetarian checks for spinach */
if (!tin->cursed)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("This makes you feel like %s!",
/* "Swee'pea" is a character from the Popeye cartoons */
Hallucination ? "Swee'pea"
gainstr(tin, 0, FALSE);
tin = costly_tin(COST_OPEN);
-
- lesshungry(tin->blessed
- ? 600 /* blessed */
- : !tin->cursed
- ? (400 + rnd(200)) /* uncursed */
- : (200 + rnd(400))); /* cursed */
+ lesshungry(tin->blessed ? 600 /* blessed */
+ : !tin->cursed ? (400 + rnd(200)) /* uncursed */
+ : (200 + rnd(400))); /* cursed */
}
-use_up_tin:
+ use_up_tin:
if (carried(tin))
useup(tin);
else
} else if (uwep) {
switch (uwep->otyp) {
case TIN_OPENER:
-#if 0 /*JP*/
+#if 0 /*JP:T*/
mesg = "You easily open the tin."; /* iff tmp==0 */
#else
mesg = "\82 \82È\82½\82Í\8aÈ\92P\82É\8aÊ\82ð\8aJ\82¯\82½\81D"; /* iff tmp==0 */
*/
You("%s\82ð\8eg\82Á\82Ä\8aÊ\82ð\8aJ\82¯\82æ\82¤\82Æ\82µ\82½\81D", xname(uwep));
} else {
- no_opener:
+ no_opener:
/*JP
pline("It is not so easy to open this tin.");
*/
pline("\82±\82Ì\8aÊ\82ð\8aJ\82¯\82é\82Ì\82Í\97e\88Õ\82È\82±\82Æ\82Å\82Í\82È\82¢\81D");
if (Glib) {
/*JP
- pline_The("tin slips from your %s.",
+ pline_The("tin slips from your %s.", fingers_or_gloves(FALSE));
*/
- pline("\8aÊ\82Í\82 \82È\82½\82Ì%s\82©\82ç\8a\8a\82è\97\8e\82¿\82½\81D",
- makeplural(body_part(FINGER)));
+ pline_The("\8aÊ\82Í\82 \82È\82½\82Ì%s\82©\82ç\8a\8a\82è\97\8e\82¿\82½\81D", fingers_or_gloves(FALSE));
if (otmp->quan > 1L) {
otmp = splitobj(otmp, 1L);
}
#if 0 /*JP:T*/
losehp(rnd(15), !glob ? "acidic corpse" : "acidic glob",
KILLED_BY_AN); /* acid damage */
-#else /* \93ú\96{\8cê\82Å\82Í\8bæ\95Ê\82µ\82È\82¢ */
+#else
+ /* \93ú\96{\8cê\82Å\82Í\8bæ\95Ê\82µ\82È\82¢ */
losehp(rnd(15), "\8e_\82Ì\8e\80\91Ì\82Å", KILLED_BY_AN);
#endif
} else if (poisonous(&mons[mnum]) && rn2(5)) {
pline("\83E\83Q\83F\81[\81C\97L\93Å\82¾\82Á\82½\82É\82¿\82ª\82¢\82È\82¢\81I");
if (!Poison_resistance) {
losestr(rnd(4));
-#if 0 /*JP*/
+#if 0 /*JP:T*/
losehp(rnd(15), !glob ? "poisonous corpse" : "poisonous glob",
KILLED_BY_AN);
#else
/* called as you start to eat */
STATIC_OVL void
-start_eating(otmp)
+start_eating(otmp, already_partly_eaten)
struct obj *otmp;
+boolean already_partly_eaten;
{
const char *old_nomovemsg, *save_nomovemsg;
if (++context.victual.usedtime >= context.victual.reqtime) {
/* print "finish eating" message if they just resumed -dlc */
- done_eating(context.victual.reqtime > 1 ? TRUE : FALSE);
+ done_eating((context.victual.reqtime > 1
+ || already_partly_eaten) ? TRUE : FALSE);
return;
}
}
/*
- * called on "first bite" of (non-corpse) food.
- * used for non-rotten non-tin non-corpse food
+ * Called on "first bite" of (non-corpse) food, after touchfood() has
+ * marked it 'partly eaten'. Used for non-rotten non-tin non-corpse food.
+ * Messages should use present tense since multi-turn food won't be
+ * finishing at the time they're issued.
*/
STATIC_OVL void
fprefx(otmp)
struct obj *otmp;
{
switch (otmp->otyp) {
- case FOOD_RATION:
+ case FOOD_RATION: /* nutrition 800 */
+ /* 200+800 remains below 1000+1, the satiation threshold */
if (u.uhunger <= 200)
+#if 0 /*JP:T*/
+ pline("%s!", Hallucination ? "Oh wow, like, superior, man"
+ : "This food really hits the spot");
+#else
+ pline("%s\81I", 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¾"
+ : "\82±\82Ì\90H\82×\95¨\82Í\96{\93\96\82É\90\\82µ\95ª\82È\82¢");
+#endif
+
+ /* 700-1+800 remains below 1500, the choking threshold which
+ triggers "you're having a hard time getting it down" feedback */
+ else if (u.uhunger < 700)
/*JP
- pline(Hallucination ? "Oh wow, like, superior, man!"
-*/
- 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"
-/*JP
- : "That food really hit the spot!");
-*/
- : "\82±\82Ì\90H\82×\95¨\82Í\96{\93\96\82É\90\\82µ\95ª\82È\82¢\81I");
- else if (u.uhunger <= 700)
-/*JP
- pline("That satiated your %s!", body_part(STOMACH));
+ pline("This satiates your %s!", body_part(STOMACH));
*/
pline("\96\9e\95 \82É\82È\82Á\82½\81I");
+ /* [satiation message may be inaccurate if eating gets interrupted] */
break;
case TRIPE_RATION:
- if (carnivorous(youmonst.data) && !humanoid(youmonst.data))
+ if (carnivorous(youmonst.data) && !humanoid(youmonst.data)) {
/*JP
- pline("That tripe ration was surprisingly good!");
+ pline("This tripe ration is surprisingly good!");
*/
pline("\82±\82Ì\83\82\83c\93÷\82Í\82¨\82Ç\82ë\82\82Ù\82Ç\8e|\82¢\81I");
- else if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC)))
+ } else if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC))) {
/*JP
pline(Hallucination ? "Tastes great! Less filling!"
*/
: "Mmm, tripe... not bad!");
*/
: "\82ñ\81[\81C\83\82\83c\82©\81D\81D\81D\88«\82\82È\82¢\81I");
- else {
+ } else {
/*JP
pline("Yak - dog food!");
*/
default:
if (otmp->otyp == SLIME_MOLD && !otmp->cursed
&& otmp->spe == context.current_fruit) {
-#if 0 /*JP*/
- pline("My, that was a %s %s!",
+#if 0 /*JP:T*/
+ pline("My, this is a %s %s!",
Hallucination ? "primo" : "yummy",
singular(otmp, xname));
#else
if (!Hallucination) {
pline("Core dumped.");
} else {
- /* This is based on an old Usenet joke, a fake a.out manual
- * page
- */
+ /* based on an old Usenet joke, a fake a.out manual page */
int x = rnd(100);
pline("%s -- core dumped.",
}
#endif
} else if (otmp->otyp == EGG && stale_egg(otmp)) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline("Ugh. Rotten egg."); /* perhaps others like it */
#else
pline("\83E\83Q\83F\81[\95\85\82Á\82½\97\91\82¾\81D");
will be abused more times before illness completes */
make_vomiting((Vomiting & TIMEOUT) + (long) d(10, 4), TRUE);
} else {
- give_feedback:
-#if 0 /*JP*/
+ give_feedback:
+#if 0 /*JP:T*/
pline("This %s is %s", singular(otmp, xname),
otmp->cursed
? (Hallucination ? "grody!" : "terrible!")
if (!oldprop && !EInvis && !BInvis && !See_invisible
&& !Blind) {
newsym(u.ux, u.uy);
-#if 0 /*JP*/
+#if 0 /*JP:T*/
Your("body takes on a %s transparency...",
Hallucination ? "normal" : "strange");
#else
accessory_has_effect(otmp);
makeknown(typ);
change_sex();
-#if 0 /*JP*/
+#if 0 /*JP:T*/
You("are suddenly very %s!",
flags.female ? "feminine" : "masculine");
#else
/* KMH -- idea by "Tommy the Terrorist" */
if (otmp->otyp == TRIDENT && !otmp->cursed) {
/* sugarless chewing gum which used to be heavily advertised on TV */
-#if 0 /*JP*/
+#if 0 /*JP:T*/
pline(Hallucination ? "Four out of five dentists agree."
: "That was pure chewing satisfaction!");
#else
/* NOTE: the order of these words exactly corresponds to the
order of oc_material values #define'd in objclass.h. */
static const char *foodwords[] = {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
"meal", "liquid", "wax", "food", "meat", "paper",
"cloth", "leather", "wood", "bone", "scale", "metal",
"metal", "metal", "silver", "gold", "platinum", "mithril",
{
struct obj *otmp;
int basenutrit; /* nutrition of full item */
- boolean dont_start = FALSE, nodelicious = FALSE;
+ boolean dont_start = FALSE, nodelicious = FALSE,
+ already_partly_eaten;
if (Strangled) {
/*JP
* against the possibility just in case.
*/
if (welded(otmp) || (otmp->cursed && (otmp->owornmask & W_RING))) {
- otmp->bknown = 1; /* for ring; welded() does this for weapon */
+ set_bknown(otmp, 1); /* for ring; welded() does this for weapon */
/*JP
You("spit out %s.", the(xname(otmp)));
*/
You("%s\82ð\93f\82«\8fo\82µ\82½\81D", xname(otmp));
} else {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
You("spit %s out onto the %s.", the(xname(otmp)),
surface(u.ux, u.uy));
#else
? foodword(otmp)
: singular(otmp, xname));
#else
- pline("\82±\82Ì%s\82Í\8e|\82¢\81I",
- otmp->oclass == COIN_CLASS
+ pline("%s%s\82Í\8e|\82¢\81I",
+ (obj_is_pname(otmp)
+ && otmp->oartifact < ART_ORB_OF_DETECTION)
+ ? ""
+ : "\82±\82Ì",
+ (otmp->oclass == COIN_CLASS)
? foodword(otmp)
: singular(otmp, xname));
#endif
context.victual.piece = touchfood(otmp);
if (context.victual.piece)
context.victual.o_id = context.victual.piece->o_id;
-/*JP
- You("resume your meal.");
-*/
- You("\90H\8e\96\82ð\8dÄ\8aJ\82µ\82½\81D");
- start_eating(context.victual.piece);
+#if 0 /*JP:T*/
+ You("resume %syour meal.",
+ (context.victual.usedtime + 1 >= context.victual.reqtime)
+ ? "the last bite of " : "");
+#else
+ You("\90H\8e\96%s\82ð\8dÄ\8aJ\82µ\82½\81D",
+ (context.victual.usedtime + 1 >= context.victual.reqtime)
+ ? "\82Ì\8dÅ\8cã\82Ì\88ê\8cû" : "");
+#endif
+ start_eating(context.victual.piece, FALSE);
return 1;
}
/* KMH, conduct */
u.uconduct.food++;
+ already_partly_eaten = otmp->oeaten ? TRUE : FALSE;
context.victual.o_id = 0;
context.victual.piece = otmp = touchfood(otmp);
if (context.victual.piece)
dont_start = TRUE;
}
consume_oeaten(otmp, 1); /* oeaten >>= 1 */
- } else
+ } else if (!already_partly_eaten) {
fprefx(otmp);
+ } else {
+#if 0 /*JP:T*/
+ You("%s %s.",
+ (context.victual.reqtime == 1) ? "eat" : "begin eating",
+ doname(otmp));
+#else
+ You("%s\82ð\90H\82×%s\82½\81D",
+ doname(otmp),
+ (context.victual.reqtime == 1) ? "" : "\82Í\82¶\82ß");
+#endif
+ }
}
/* re-calc the nutrition */
context.victual.canchoke = (u.uhs == SATIATED);
if (!dont_start)
- start_eating(otmp);
+ start_eating(otmp, already_partly_eaten);
return 1;
}
if (obj->cursed && obj->bknown) {
char qbuf[QBUFSZ];
-#if 0 /*JP*/
+#if 0 /*JP:T*/
if (ynq(safe_qbuf(qbuf, "Really wield ", "?",
obj, doname, thesimpleoname, "that")) != 'y')
#else
/* Have lesshungry() report when you're nearly full so all eating
* warns when you're about to choke.
*/
- if (u.uhunger >= 1500) {
- if (!context.victual.eating
- || (context.victual.eating && !context.victual.fullwarn)) {
+ if (u.uhunger >= 1500
+ && (!context.victual.eating
+ || (context.victual.eating && !context.victual.fullwarn))) {
/*JP
- pline("You're having a hard time getting all of it down.");
+ pline("You're having a hard time getting all of it down.");
*/
- pline("\91S\82Ä\82ð\88ù\82Ý\82±\82Þ\82É\82Í\8e\9e\8aÔ\82ª\82©\82©\82é\81D");
+ pline("\91S\82Ä\82ð\88ù\82Ý\82±\82Þ\82É\82Í\8e\9e\8aÔ\82ª\82©\82©\82é\81D");
/*JP
- nomovemsg = "You're finally finished.";
+ nomovemsg = "You're finally finished.";
*/
- nomovemsg = "\82â\82Á\82Æ\90H\82×\8fI\82¦\82½\81D";
- if (!context.victual.eating) {
- multi = -2;
- } else {
- context.victual.fullwarn = TRUE;
- if (context.victual.canchoke
- && context.victual.reqtime > 1) {
- /* a one-gulp food will not survive a stop */
-/*JP
- if (yn_function("Continue eating?", ynchars, 'n')
-*/
- if (yn_function("\90H\82×\91±\82¯\82Ü\82·\82©\81H", ynchars, 'n')
- != 'y') {
- reset_eat();
- nomovemsg = (char *) 0;
- }
+ nomovemsg = "\82â\82Á\82Æ\90H\82×\8fI\82¦\82½\81D";
+ if (!context.victual.eating) {
+ multi = -2;
+ } else {
+ context.victual.fullwarn = TRUE;
+ if (context.victual.canchoke && context.victual.reqtime > 1) {
+ /* a one-gulp food will not survive a stop */
+/*JP
+ if (!paranoid_query(ParanoidEating, "Continue eating?")) {
+*/
+ if (!paranoid_query(ParanoidEating, "\90H\82×\91±\82¯\82Ü\82·\82©\81H")) {
+ reset_eat();
+ nomovemsg = (char *) 0;
}
}
}
if (youmonst.data != &mons[PM_RUST_MONSTER]
&& (gold = g_at(u.ux, u.uy)) != 0) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
if (gold->quan == 1L)
Sprintf(qbuf, "There is 1 gold piece here; eat it?");
else
}
}
-skipfloor:
+ skipfloor:
/* We cannot use ALL_CLASSES since that causes getobj() to skip its
* "ugly checks" and we need to check for inedible items.
*/
if (multi >= -2) {
nomul(-2);
/*JP
- multi_reason = "vomiting";
+ multi_reason = "vomiting";
*/
- multi_reason = "\9aq\93f\82µ\82Ä\82¢\82é\8dÅ\92\86\82É";
+ multi_reason = "\9aq\93f\82µ\82Ä\82¢\82é\8dÅ\92\86\82É";
nomovemsg = You_can_move_again;
}
}