xref: /netbsd-src/games/hack/hack.eat.c (revision 9c07d7ddd1bd0410b30ea4f01b9b1a362df1f573)
1*9c07d7ddSmrg /*	$NetBSD: hack.eat.c,v 1.13 2019/02/04 03:33:15 mrg Exp $	*/
23ea4a95cSchristos 
302ded532Smycroft /*
41c7f94e5Sjsm  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
51c7f94e5Sjsm  * Amsterdam
61c7f94e5Sjsm  * All rights reserved.
71c7f94e5Sjsm  *
81c7f94e5Sjsm  * Redistribution and use in source and binary forms, with or without
91c7f94e5Sjsm  * modification, are permitted provided that the following conditions are
101c7f94e5Sjsm  * met:
111c7f94e5Sjsm  *
121c7f94e5Sjsm  * - Redistributions of source code must retain the above copyright notice,
131c7f94e5Sjsm  * this list of conditions and the following disclaimer.
141c7f94e5Sjsm  *
151c7f94e5Sjsm  * - Redistributions in binary form must reproduce the above copyright
161c7f94e5Sjsm  * notice, this list of conditions and the following disclaimer in the
171c7f94e5Sjsm  * documentation and/or other materials provided with the distribution.
181c7f94e5Sjsm  *
191c7f94e5Sjsm  * - Neither the name of the Stichting Centrum voor Wiskunde en
201c7f94e5Sjsm  * Informatica, nor the names of its contributors may be used to endorse or
211c7f94e5Sjsm  * promote products derived from this software without specific prior
221c7f94e5Sjsm  * written permission.
231c7f94e5Sjsm  *
241c7f94e5Sjsm  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
251c7f94e5Sjsm  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
261c7f94e5Sjsm  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
271c7f94e5Sjsm  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
281c7f94e5Sjsm  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
291c7f94e5Sjsm  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
301c7f94e5Sjsm  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
311c7f94e5Sjsm  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
321c7f94e5Sjsm  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
331c7f94e5Sjsm  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
341c7f94e5Sjsm  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
351c7f94e5Sjsm  */
361c7f94e5Sjsm 
371c7f94e5Sjsm /*
381c7f94e5Sjsm  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
391c7f94e5Sjsm  * All rights reserved.
401c7f94e5Sjsm  *
411c7f94e5Sjsm  * Redistribution and use in source and binary forms, with or without
421c7f94e5Sjsm  * modification, are permitted provided that the following conditions
431c7f94e5Sjsm  * are met:
441c7f94e5Sjsm  * 1. Redistributions of source code must retain the above copyright
451c7f94e5Sjsm  *    notice, this list of conditions and the following disclaimer.
461c7f94e5Sjsm  * 2. Redistributions in binary form must reproduce the above copyright
471c7f94e5Sjsm  *    notice, this list of conditions and the following disclaimer in the
481c7f94e5Sjsm  *    documentation and/or other materials provided with the distribution.
491c7f94e5Sjsm  * 3. The name of the author may not be used to endorse or promote products
501c7f94e5Sjsm  *    derived from this software without specific prior written permission.
511c7f94e5Sjsm  *
521c7f94e5Sjsm  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
531c7f94e5Sjsm  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
541c7f94e5Sjsm  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
551c7f94e5Sjsm  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
561c7f94e5Sjsm  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
571c7f94e5Sjsm  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
581c7f94e5Sjsm  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
591c7f94e5Sjsm  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
601c7f94e5Sjsm  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
611c7f94e5Sjsm  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6202ded532Smycroft  */
6302ded532Smycroft 
643ea4a95cSchristos #include <sys/cdefs.h>
6502ded532Smycroft #ifndef lint
66*9c07d7ddSmrg __RCSID("$NetBSD: hack.eat.c,v 1.13 2019/02/04 03:33:15 mrg Exp $");
6702ded532Smycroft #endif				/* not lint */
6861f28255Scgd 
6961f28255Scgd #include "hack.h"
703ea4a95cSchristos #include "extern.h"
719b92b189Sdholland static char POISONOUS[] = "ADKSVabhks";
7261f28255Scgd 
7361f28255Scgd /* hunger texts used on bottom line (each 8 chars long) */
7461f28255Scgd #define	SATIATED	0
7561f28255Scgd #define NOT_HUNGRY	1
7661f28255Scgd #define	HUNGRY		2
7761f28255Scgd #define	WEAK		3
7861f28255Scgd #define	FAINTING	4
7961f28255Scgd #define FAINTED		5
8061f28255Scgd #define STARVED		6
8161f28255Scgd 
82ab8b6343Sjsm const char           *const hu_stat[] = {
8361f28255Scgd 	"Satiated",
8461f28255Scgd 	"        ",
8561f28255Scgd 	"Hungry  ",
8661f28255Scgd 	"Weak    ",
8761f28255Scgd 	"Fainting",
8861f28255Scgd 	"Fainted ",
8961f28255Scgd 	"Starved "
9061f28255Scgd };
9161f28255Scgd 
929b92b189Sdholland static int opentin(void);
939b92b189Sdholland static int Meatdone(void);
949b92b189Sdholland static int unfaint(void);
959b92b189Sdholland static void newuhs(boolean);
969b92b189Sdholland static int eatcorpse(struct obj *);
979b92b189Sdholland 
983ea4a95cSchristos void
init_uhunger(void)991fa8a9a6Sdholland init_uhunger(void)
1003ea4a95cSchristos {
10161f28255Scgd 	u.uhunger = 900;
10261f28255Scgd 	u.uhs = NOT_HUNGRY;
10361f28255Scgd }
10461f28255Scgd 
10561f28255Scgd #define	TTSZ	SIZE(tintxts)
1069b92b189Sdholland static const struct {
107ab8b6343Sjsm 	const char           *txt;
1083ea4a95cSchristos 	int             nut;
1093ea4a95cSchristos }               tintxts[] = {
1103ea4a95cSchristos 	{ "It contains first quality peaches - what a surprise!", 40 },
1113ea4a95cSchristos 	{ "It contains salmon - not bad!", 60 },
1123ea4a95cSchristos 	{ "It contains apple juice - perhaps not what you hoped for.", 20 },
1133ea4a95cSchristos 	{ "It contains some nondescript substance, tasting awfully.", 500 },
1143ea4a95cSchristos 	{ "It contains rotten meat. You vomit.", -50 },
1153ea4a95cSchristos 	{ "It turns out to be empty.", 0 }
11661f28255Scgd };
11761f28255Scgd 
11861f28255Scgd static struct {
11961f28255Scgd 	struct obj     *tin;
12061f28255Scgd 	int             usedtime, reqtime;
12161f28255Scgd }               tin;
12261f28255Scgd 
1239b92b189Sdholland static int
opentin(void)1241fa8a9a6Sdholland opentin(void)
1253ea4a95cSchristos {
1263ea4a95cSchristos 	int             r;
12761f28255Scgd 
12861f28255Scgd 	if (!carried(tin.tin))	/* perhaps it was stolen? */
12961f28255Scgd 		return (0);	/* %% probably we should use tinoid */
13061f28255Scgd 	if (tin.usedtime++ >= 50) {
13161f28255Scgd 		pline("You give up your attempt to open the tin.");
13261f28255Scgd 		return (0);
13361f28255Scgd 	}
13461f28255Scgd 	if (tin.usedtime < tin.reqtime)
13561f28255Scgd 		return (1);	/* still busy */
13661f28255Scgd 
13761f28255Scgd 	pline("You succeed in opening the tin.");
13861f28255Scgd 	useup(tin.tin);
13961f28255Scgd 	r = rn2(2 * TTSZ);
14061f28255Scgd 	if (r < TTSZ) {
14157c13365Sjoerg 		pline("%s", tintxts[r].txt);
14261f28255Scgd 		lesshungry(tintxts[r].nut);
1433ea4a95cSchristos 		if (r == 1) {	/* SALMON */
14461f28255Scgd 			Glib = rnd(15);
14561f28255Scgd 			pline("Eating salmon made your fingers very slippery.");
14661f28255Scgd 		}
14761f28255Scgd 	} else {
14861f28255Scgd 		pline("It contains spinach - this makes you feel like Popeye!");
14961f28255Scgd 		lesshungry(600);
15061f28255Scgd 		if (u.ustr < 118)
15161f28255Scgd 			u.ustr += rnd(((u.ustr < 17) ? 19 : 118) - u.ustr);
1523ea4a95cSchristos 		if (u.ustr > u.ustrmax)
1533ea4a95cSchristos 			u.ustrmax = u.ustr;
15461f28255Scgd 		flags.botl = 1;
15561f28255Scgd 	}
15661f28255Scgd 	return (0);
15761f28255Scgd }
15861f28255Scgd 
1599b92b189Sdholland static int
Meatdone(void)1601fa8a9a6Sdholland Meatdone(void)
1613ea4a95cSchristos {
16261f28255Scgd 	u.usym = '@';
16361f28255Scgd 	prme();
1643ea4a95cSchristos 	return 0;
16561f28255Scgd }
16661f28255Scgd 
1673ea4a95cSchristos int
doeat(void)1681fa8a9a6Sdholland doeat(void)
1693ea4a95cSchristos {
1703ea4a95cSchristos 	struct obj     *otmp;
1713ea4a95cSchristos 	struct objclass *ftmp;
1723ea4a95cSchristos 	int tmp;
17361f28255Scgd 
17461f28255Scgd 	/* Is there some food (probably a heavy corpse) here on the ground? */
17561f28255Scgd 	if (!Levitation)
17661f28255Scgd 		for (otmp = fobj; otmp; otmp = otmp->nobj) {
17761f28255Scgd 			if (otmp->ox == u.ux && otmp->oy == u.uy &&
17861f28255Scgd 			    otmp->olet == FOOD_SYM) {
17961f28255Scgd 				pline("There %s %s here; eat %s? [ny] ",
18061f28255Scgd 				      (otmp->quan == 1) ? "is" : "are",
18161f28255Scgd 				      doname(otmp),
18261f28255Scgd 				      (otmp->quan == 1) ? "it" : "one");
18361f28255Scgd 				if (readchar() == 'y') {
18461f28255Scgd 					if (otmp->quan != 1)
18561f28255Scgd 						(void) splitobj(otmp, 1);
18661f28255Scgd 					freeobj(otmp);
18761f28255Scgd 					otmp = addinv(otmp);
18861f28255Scgd 					addtobill(otmp);
18961f28255Scgd 					goto gotit;
19061f28255Scgd 				}
19161f28255Scgd 			}
19261f28255Scgd 		}
19361f28255Scgd 	otmp = getobj("%", "eat");
1943ea4a95cSchristos 	if (!otmp)
1953ea4a95cSchristos 		return (0);
19661f28255Scgd gotit:
19761f28255Scgd 	if (otmp->otyp == TIN) {
19861f28255Scgd 		if (uwep) {
19961f28255Scgd 			switch (uwep->otyp) {
20061f28255Scgd 			case CAN_OPENER:
20161f28255Scgd 				tmp = 1;
20261f28255Scgd 				break;
20361f28255Scgd 			case DAGGER:
20461f28255Scgd 			case CRYSKNIFE:
20561f28255Scgd 				tmp = 3;
20661f28255Scgd 				break;
20761f28255Scgd 			case PICK_AXE:
20861f28255Scgd 			case AXE:
20961f28255Scgd 				tmp = 6;
21061f28255Scgd 				break;
21161f28255Scgd 			default:
21261f28255Scgd 				goto no_opener;
21361f28255Scgd 			}
21461f28255Scgd 			pline("Using your %s you try to open the tin.",
2152c0ecb1aSdholland 			      aobjnam(uwep, NULL));
21661f28255Scgd 		} else {
21761f28255Scgd 	no_opener:
21861f28255Scgd 			pline("It is not so easy to open this tin.");
21961f28255Scgd 			if (Glib) {
22061f28255Scgd 				pline("The tin slips out of your hands.");
22161f28255Scgd 				if (otmp->quan > 1) {
2223ea4a95cSchristos 					struct obj     *obj;
22361f28255Scgd 
22461f28255Scgd 					obj = splitobj(otmp, 1);
2253ea4a95cSchristos 					if (otmp == uwep)
2263ea4a95cSchristos 						setuwep(obj);
22761f28255Scgd 				}
22861f28255Scgd 				dropx(otmp);
22961f28255Scgd 				return (1);
23061f28255Scgd 			}
23161f28255Scgd 			tmp = 10 + rn2(1 + 500 / ((int) (u.ulevel + u.ustr)));
23261f28255Scgd 		}
23361f28255Scgd 		tin.reqtime = tmp;
23461f28255Scgd 		tin.usedtime = 0;
23561f28255Scgd 		tin.tin = otmp;
23661f28255Scgd 		occupation = opentin;
23761f28255Scgd 		occtxt = "opening the tin";
23861f28255Scgd 		return (1);
23961f28255Scgd 	}
24061f28255Scgd 	ftmp = &objects[otmp->otyp];
24161f28255Scgd 	multi = -ftmp->oc_delay;
2423ea4a95cSchristos 	if (otmp->otyp >= CORPSE && eatcorpse(otmp))
2433ea4a95cSchristos 		goto eatx;
24461f28255Scgd 	if (!rn2(7) && otmp->otyp != FORTUNE_COOKIE) {
24561f28255Scgd 		pline("Blecch!  Rotten food!");
24661f28255Scgd 		if (!rn2(4)) {
24761f28255Scgd 			pline("You feel rather light headed.");
24861f28255Scgd 			Confusion += d(2, 4);
24961f28255Scgd 		} else if (!rn2(4) && !Blind) {
25061f28255Scgd 			pline("Everything suddenly goes dark.");
25161f28255Scgd 			Blind = d(2, 10);
25261f28255Scgd 			seeoff(0);
25361f28255Scgd 		} else if (!rn2(3)) {
25461f28255Scgd 			if (Blind)
25561f28255Scgd 				pline("The world spins and you slap against the floor.");
25661f28255Scgd 			else
25761f28255Scgd 				pline("The world spins and goes dark.");
25861f28255Scgd 			nomul(-rnd(10));
25961f28255Scgd 			nomovemsg = "You are conscious again.";
26061f28255Scgd 		}
26161f28255Scgd 		lesshungry(ftmp->nutrition / 4);
26261f28255Scgd 	} else {
26361f28255Scgd 		if (u.uhunger >= 1500) {
26461f28255Scgd 			pline("You choke over your food.");
26561f28255Scgd 			pline("You die...");
26661f28255Scgd 			killer = ftmp->oc_name;
26761f28255Scgd 			done("choked");
26861f28255Scgd 		}
26961f28255Scgd 		switch (otmp->otyp) {
27061f28255Scgd 		case FOOD_RATION:
27161f28255Scgd 			if (u.uhunger <= 200)
27261f28255Scgd 				pline("That food really hit the spot!");
27361f28255Scgd 			else if (u.uhunger <= 700)
27461f28255Scgd 				pline("That satiated your stomach!");
27561f28255Scgd 			else {
27661f28255Scgd 				pline("You're having a hard time getting all that food down.");
27761f28255Scgd 				multi -= 2;
27861f28255Scgd 			}
27961f28255Scgd 			lesshungry(ftmp->nutrition);
2803ea4a95cSchristos 			if (multi < 0)
2813ea4a95cSchristos 				nomovemsg = "You finished your meal.";
28261f28255Scgd 			break;
28361f28255Scgd 		case TRIPE_RATION:
28461f28255Scgd 			pline("Yak - dog food!");
28561f28255Scgd 			more_experienced(1, 0);
28661f28255Scgd 			flags.botl = 1;
28761f28255Scgd 			if (rn2(2)) {
28861f28255Scgd 				pline("You vomit.");
28961f28255Scgd 				morehungry(20);
29061f28255Scgd 				if (Sick) {
29161f28255Scgd 					Sick = 0;	/* David Neves */
29261f28255Scgd 					pline("What a relief!");
29361f28255Scgd 				}
2943ea4a95cSchristos 			} else
2953ea4a95cSchristos 				lesshungry(ftmp->nutrition);
29661f28255Scgd 			break;
29761f28255Scgd 		default:
29861f28255Scgd 			if (otmp->otyp >= CORPSE)
29961f28255Scgd 				pline("That %s tasted terrible!", ftmp->oc_name);
30061f28255Scgd 			else
30161f28255Scgd 				pline("That %s was delicious!", ftmp->oc_name);
30261f28255Scgd 			lesshungry(ftmp->nutrition);
30361f28255Scgd 			if (otmp->otyp == DEAD_LIZARD && (Confusion > 2))
30461f28255Scgd 				Confusion = 2;
30561f28255Scgd 			else
30661f28255Scgd #ifdef QUEST
30761f28255Scgd 			if (otmp->otyp == CARROT && !Blind) {
30861f28255Scgd 				u.uhorizon++;
30961f28255Scgd 				setsee();
31061f28255Scgd 				pline("Your vision improves.");
31161f28255Scgd 			} else
3123ea4a95cSchristos #endif	/* QUEST */
31361f28255Scgd 			if (otmp->otyp == FORTUNE_COOKIE) {
31461f28255Scgd 				if (Blind) {
31561f28255Scgd 					pline("This cookie has a scrap of paper inside!");
31661f28255Scgd 					pline("What a pity, that you cannot read it!");
31761f28255Scgd 				} else
31861f28255Scgd 					outrumor();
3193ea4a95cSchristos 			} else if (otmp->otyp == LUMP_OF_ROYAL_JELLY) {
32061f28255Scgd 				/* This stuff seems to be VERY healthy! */
3213ea4a95cSchristos 				if (u.ustrmax < 118)
3223ea4a95cSchristos 					u.ustrmax++;
3233ea4a95cSchristos 				if (u.ustr < u.ustrmax)
3243ea4a95cSchristos 					u.ustr++;
32561f28255Scgd 				u.uhp += rnd(20);
32661f28255Scgd 				if (u.uhp > u.uhpmax) {
3273ea4a95cSchristos 					if (!rn2(17))
3283ea4a95cSchristos 						u.uhpmax++;
32961f28255Scgd 					u.uhp = u.uhpmax;
33061f28255Scgd 				}
33161f28255Scgd 				heal_legs();
33261f28255Scgd 			}
33361f28255Scgd 			break;
33461f28255Scgd 		}
33561f28255Scgd 	}
33661f28255Scgd eatx:
33761f28255Scgd 	if (multi < 0 && !nomovemsg) {
33861f28255Scgd 		static char     msgbuf[BUFSZ];
339907fca1bSdholland 		(void) snprintf(msgbuf, sizeof(msgbuf),
340907fca1bSdholland 			       "You finished eating the %s.",
34161f28255Scgd 			       ftmp->oc_name);
34261f28255Scgd 		nomovemsg = msgbuf;
34361f28255Scgd 	}
34461f28255Scgd 	useup(otmp);
34561f28255Scgd 	return (1);
34661f28255Scgd }
34761f28255Scgd 
34861f28255Scgd /* called in hack.main.c */
3493ea4a95cSchristos void
gethungry(void)3501fa8a9a6Sdholland gethungry(void)
3513ea4a95cSchristos {
35261f28255Scgd 	--u.uhunger;
35361f28255Scgd 	if (moves % 2) {
3543ea4a95cSchristos 		if (Regeneration)
3553ea4a95cSchristos 			u.uhunger--;
3563ea4a95cSchristos 		if (Hunger)
3573ea4a95cSchristos 			u.uhunger--;
3583ea4a95cSchristos 		/*
3593ea4a95cSchristos 		 * a3:  if(Hunger & LEFT_RING) u.uhunger--; if(Hunger &
3603ea4a95cSchristos 		 * RIGHT_RING) u.uhunger--; etc.
3613ea4a95cSchristos 		 */
36261f28255Scgd 	}
36361f28255Scgd 	if (moves % 20 == 0) {	/* jimt@asgb */
3643ea4a95cSchristos 		if (uleft)
3653ea4a95cSchristos 			u.uhunger--;
3663ea4a95cSchristos 		if (uright)
3673ea4a95cSchristos 			u.uhunger--;
36861f28255Scgd 	}
36961f28255Scgd 	newuhs(TRUE);
37061f28255Scgd }
37161f28255Scgd 
37261f28255Scgd /* called after vomiting and after performing feats of magic */
3733ea4a95cSchristos void
morehungry(int num)3741fa8a9a6Sdholland morehungry(int num)
3753ea4a95cSchristos {
37661f28255Scgd 	u.uhunger -= num;
37761f28255Scgd 	newuhs(TRUE);
37861f28255Scgd }
37961f28255Scgd 
38061f28255Scgd /* called after eating something (and after drinking fruit juice) */
3813ea4a95cSchristos void
lesshungry(int num)3821fa8a9a6Sdholland lesshungry(int num)
3833ea4a95cSchristos {
38461f28255Scgd 	u.uhunger += num;
38561f28255Scgd 	newuhs(FALSE);
38661f28255Scgd }
38761f28255Scgd 
3889b92b189Sdholland static int
unfaint(void)3891fa8a9a6Sdholland unfaint(void)
3903ea4a95cSchristos {
39161f28255Scgd 	u.uhs = FAINTING;
39261f28255Scgd 	flags.botl = 1;
3933ea4a95cSchristos 	return 0;
39461f28255Scgd }
39561f28255Scgd 
3969b92b189Sdholland static void
newuhs(boolean incr)3971fa8a9a6Sdholland newuhs(boolean incr)
3983ea4a95cSchristos {
3993ea4a95cSchristos 	int             newhs, h = u.uhunger;
40061f28255Scgd 
40161f28255Scgd 	newhs = (h > 1000) ? SATIATED :
40261f28255Scgd 		(h > 150) ? NOT_HUNGRY :
40361f28255Scgd 		(h > 50) ? HUNGRY :
40461f28255Scgd 		(h > 0) ? WEAK : FAINTING;
40561f28255Scgd 
40661f28255Scgd 	if (newhs == FAINTING) {
40761f28255Scgd 		if (u.uhs == FAINTED)
40861f28255Scgd 			newhs = FAINTED;
40961f28255Scgd 		if (u.uhs <= WEAK || rn2(20 - u.uhunger / 10) >= 19) {
41061f28255Scgd 			if (u.uhs != FAINTED && multi >= 0 /* %% */ ) {
41161f28255Scgd 				pline("You faint from lack of food.");
41261f28255Scgd 				nomul(-10 + (u.uhunger / 10));
41361f28255Scgd 				nomovemsg = "You regain consciousness.";
41461f28255Scgd 				afternmv = unfaint;
41561f28255Scgd 				newhs = FAINTED;
41661f28255Scgd 			}
4173ea4a95cSchristos 		} else if (u.uhunger < -(int) (200 + 25 * u.ulevel)) {
41861f28255Scgd 			u.uhs = STARVED;
41961f28255Scgd 			flags.botl = 1;
42061f28255Scgd 			bot();
42161f28255Scgd 			pline("You die from starvation.");
42261f28255Scgd 			done("starved");
42361f28255Scgd 		}
42461f28255Scgd 	}
42561f28255Scgd 	if (newhs != u.uhs) {
42661f28255Scgd 		if (newhs >= WEAK && u.uhs < WEAK)
42761f28255Scgd 			losestr(1);	/* this may kill you -- see below */
4283ea4a95cSchristos 		else if (newhs < WEAK && u.uhs >= WEAK && u.ustr < u.ustrmax)
42961f28255Scgd 			losestr(-1);
43061f28255Scgd 		switch (newhs) {
43161f28255Scgd 		case HUNGRY:
43261f28255Scgd 			pline((!incr) ? "You only feel hungry now." :
43361f28255Scgd 			      (u.uhunger < 145) ? "You feel hungry." :
43461f28255Scgd 			      "You are beginning to feel hungry.");
43561f28255Scgd 			break;
43661f28255Scgd 		case WEAK:
43761f28255Scgd 			pline((!incr) ? "You feel weak now." :
43861f28255Scgd 			      (u.uhunger < 45) ? "You feel weak." :
43961f28255Scgd 			      "You are beginning to feel weak.");
44061f28255Scgd 			break;
44161f28255Scgd 		}
44261f28255Scgd 		u.uhs = newhs;
44361f28255Scgd 		flags.botl = 1;
44461f28255Scgd 		if (u.uhp < 1) {
44561f28255Scgd 			pline("You die from hunger and exhaustion.");
44661f28255Scgd 			killer = "exhaustion";
44761f28255Scgd 			done("starved");
44861f28255Scgd 		}
44961f28255Scgd 	}
45061f28255Scgd }
45161f28255Scgd 
45261f28255Scgd #define	CORPSE_I_TO_C(otyp)	(char) ((otyp >= DEAD_ACID_BLOB)\
45361f28255Scgd 		     ?  'a' + (otyp - DEAD_ACID_BLOB)\
45461f28255Scgd 		     :	'@' + (otyp - DEAD_HUMAN))
4553ea4a95cSchristos int
poisonous(struct obj * otmp)4561fa8a9a6Sdholland poisonous(struct obj *otmp)
45761f28255Scgd {
4583ea4a95cSchristos 	return (strchr(POISONOUS, CORPSE_I_TO_C(otmp->otyp)) != 0);
45961f28255Scgd }
46061f28255Scgd 
46161f28255Scgd /* returns 1 if some text was printed */
4629b92b189Sdholland static int
eatcorpse(struct obj * otmp)4631fa8a9a6Sdholland eatcorpse(struct obj *otmp)
4643ea4a95cSchristos {
4653ea4a95cSchristos 	char            let = CORPSE_I_TO_C(otmp->otyp);
4663ea4a95cSchristos 	int             tp = 0;
46761f28255Scgd 	if (let != 'a' && moves > otmp->age + 50 + rn2(100)) {
46861f28255Scgd 		tp++;
46961f28255Scgd 		pline("Ulch -- that meat was tainted!");
47061f28255Scgd 		pline("You get very sick.");
47161f28255Scgd 		Sick = 10 + rn2(10);
47261f28255Scgd 		u.usick_cause = objects[otmp->otyp].oc_name;
4733ea4a95cSchristos 	} else if (strchr(POISONOUS, let) && rn2(5)) {
47461f28255Scgd 		tp++;
47561f28255Scgd 		pline("Ecch -- that must have been poisonous!");
47661f28255Scgd 		if (!Poison_resistance) {
47761f28255Scgd 			losestr(rnd(4));
47861f28255Scgd 			losehp(rnd(15), "poisonous corpse");
47961f28255Scgd 		} else
48061f28255Scgd 			pline("You don't seem affected by the poison.");
4813ea4a95cSchristos 	} else if (strchr("ELNOPQRUuxz", let) && rn2(5)) {
48261f28255Scgd 		tp++;
48361f28255Scgd 		pline("You feel sick.");
48461f28255Scgd 		losehp(rnd(8), "cadaver");
48561f28255Scgd 	}
48661f28255Scgd 	switch (let) {
48761f28255Scgd 	case 'L':
48861f28255Scgd 	case 'N':
48961f28255Scgd 	case 't':
49061f28255Scgd 		Teleportation |= INTRINSIC;
49161f28255Scgd 		break;
49261f28255Scgd 	case 'W':
49361f28255Scgd 		pluslvl();
49461f28255Scgd 		break;
49561f28255Scgd 	case 'n':
49661f28255Scgd 		u.uhp = u.uhpmax;
49761f28255Scgd 		flags.botl = 1;
498d5b021c7Sdholland 		/* FALLTHROUGH */
49961f28255Scgd 	case '@':
50061f28255Scgd 		pline("You cannibal! You will be sorry for this!");
50161f28255Scgd 		/* not tp++; */
502d5b021c7Sdholland 		/* FALLTHROUGH */
50361f28255Scgd 	case 'd':
50461f28255Scgd 		Aggravate_monster |= INTRINSIC;
50561f28255Scgd 		break;
50661f28255Scgd 	case 'I':
50761f28255Scgd 		if (!Invis) {
50861f28255Scgd 			Invis = 50 + rn2(100);
50961f28255Scgd 			if (!See_invisible)
51061f28255Scgd 				newsym(u.ux, u.uy);
51161f28255Scgd 		} else {
51261f28255Scgd 			Invis |= INTRINSIC;
51361f28255Scgd 			See_invisible |= INTRINSIC;
51461f28255Scgd 		}
515d5b021c7Sdholland 		/* FALLTHROUGH */
51661f28255Scgd 	case 'y':
51761f28255Scgd #ifdef QUEST
51861f28255Scgd 		u.uhorizon++;
5193ea4a95cSchristos #endif	/* QUEST */
520d5b021c7Sdholland 		/* FALLTHROUGH */
52161f28255Scgd 	case 'B':
52261f28255Scgd 		Confusion = 50;
52361f28255Scgd 		break;
52461f28255Scgd 	case 'D':
52561f28255Scgd 		Fire_resistance |= INTRINSIC;
52661f28255Scgd 		break;
52761f28255Scgd 	case 'E':
52861f28255Scgd 		Telepat |= INTRINSIC;
52961f28255Scgd 		break;
53061f28255Scgd 	case 'F':
53161f28255Scgd 	case 'Y':
53261f28255Scgd 		Cold_resistance |= INTRINSIC;
53361f28255Scgd 		break;
53461f28255Scgd 	case 'k':
53561f28255Scgd 	case 's':
53661f28255Scgd 		Poison_resistance |= INTRINSIC;
53761f28255Scgd 		break;
53861f28255Scgd 	case 'c':
53961f28255Scgd 		pline("You turn to stone.");
54061f28255Scgd 		killer = "dead cockatrice";
54161f28255Scgd 		done("died");
542*9c07d7ddSmrg 		break;
54361f28255Scgd 	case 'a':
54461f28255Scgd 		if (Stoned) {
54561f28255Scgd 			pline("What a pity - you just destroyed a future piece of art!");
54661f28255Scgd 			tp++;
54761f28255Scgd 			Stoned = 0;
54861f28255Scgd 		}
54961f28255Scgd 		break;
55061f28255Scgd 	case 'M':
55161f28255Scgd 		pline("You cannot resist the temptation to mimic a treasure chest.");
55261f28255Scgd 		tp++;
55361f28255Scgd 		nomul(-30);
55461f28255Scgd 		afternmv = Meatdone;
55561f28255Scgd 		nomovemsg = "You now again prefer mimicking a human.";
55661f28255Scgd 		u.usym = '$';
55761f28255Scgd 		prme();
55861f28255Scgd 		break;
55961f28255Scgd 	}
56061f28255Scgd 	return (tp);
56161f28255Scgd }
562