Source:NetHack 3.0.0/eat.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to eat.c from the source code of NetHack 3.0.0.

Warning! This is the source code from an old release. For newer releases, see Source code

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

1.    /*	SCCS Id: @(#)eat.c	3.0	88/10/22
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include	"hack.h"
6.    
7.    char corpsename[60];
8.    
9.    /* hunger texts used on bottom line (each 8 chars long) */
10.   #define	SATIATED	0
11.   #define NOT_HUNGRY	1
12.   #define	HUNGRY		2
13.   #define	WEAK		3
14.   #define	FAINTING	4
15.   #define FAINTED		5
16.   #define STARVED		6
17.   
18.   const char *hu_stat[] = {
19.   	"Satiated",
20.   	"        ",
21.   	"Hungry  ",
22.   	"Weak    ",
23.   	"Fainting",
24.   	"Fainted ",
25.   	"Starved "
26.   };
27.   
28.   static const char comestibles[] = { FOOD_SYM, 0 };
29.   
30.   void
31.   init_uhunger(){
32.   	u.uhunger = 900;
33.   	u.uhs = NOT_HUNGRY;
34.   }
35.   
36.   const struct { char *txt; int nut; } tintxts[] = {
37.   	"deep fried",	60,
38.   	"pickled",	40,
39.   	"soup made from", 20,
40.   	"pureed", 500,
41.   	"rotten", -50,
42.   	"",	0
43.   };
44.   #define	TTSZ	SIZE(tintxts)
45.   
46.   static struct {
47.   	struct obj *tin;
48.   	int usedtime, reqtime;
49.   } tin;
50.   
51.   static int
52.   Meatdone() {
53.   	u.usym =
54.   #ifdef POLYSELF
55.   		u.mtimedone ? uasmon->mlet :
56.   #endif
57.   		S_HUMAN;
58.   	prme();
59.   	return 0;
60.   }
61.   
62.   static int
63.   corpsefx(pm)
64.   register int pm;
65.   {
66.   	register int tmp = 0, tp = 0;
67.   
68.   	if ((pl_character[0]=='E') ? is_elf(&mons[pm]) : is_human(&mons[pm])) {
69.   		You("cannibal!  You will be sorry for this!");
70.   		Aggravate_monster |= INTRINSIC;
71.   	}
72.   
73.   	switch(pm) {
74.   	    case PM_WRAITH:
75.   		pluslvl();
76.   		break;
77.   #ifdef POLYSELF
78.   	    case PM_WERERAT:
79.   		u.ulycn = PM_RATWERE;
80.   		break;
81.   	    case PM_WEREJACKAL:
82.   		u.ulycn = PM_JACKALWERE;
83.   		break;
84.   	    case PM_WEREWOLF:
85.   		u.ulycn = PM_WOLFWERE;
86.   		break;
87.   #endif
88.   	    case PM_NURSE:
89.   		u.uhp = u.uhpmax;
90.   		flags.botl = 1;
91.   		break;
92.   	    case PM_LITTLE_DOG:
93.   	    case PM_DOG:
94.   	    case PM_LARGE_DOG:
95.   	    case PM_KITTEN:
96.   	    case PM_HOUSECAT:
97.   	    case PM_LARGE_CAT:
98.   		Aggravate_monster |= INTRINSIC;
99.   		break;
100.  	    case PM_STALKER:
101.  		if(!Invis) {
102.  			HInvis = 50+rn2(100);
103.  			if(!See_invisible)
104.  				newsym(u.ux, u.uy);
105.  		} else {
106.  			if (!HInvis) You("feel hidden!");
107.  			HInvis |= INTRINSIC;
108.  			HSee_invisible |= INTRINSIC;
109.  		}
110.  		/* fall into next case */
111.  	    case PM_YELLOW_LIGHT:
112.  		/* fall into next case */
113.  	    case PM_GIANT_BAT:
114.  		make_stunned(HStun + 30,FALSE);
115.  		/* fall into next case */
116.  	    case PM_BAT:
117.  		make_stunned(HStun + 30,FALSE);
118.  		break;
119.  	    case PM_COCKATRICE:
120.  #ifdef MEDUSA
121.  	    case PM_MEDUSA:
122.  #endif
123.  #ifdef POLYSELF
124.  		if(!resists_ston(uasmon)) {
125.  #endif
126.  			killer = (char *) alloc(40);
127.  			You("turn to stone.");
128.  			Sprintf(killer, "%s meat",
129.  				      mons[pm].mname);
130.  			done("stoned");
131.  #ifdef POLYSELF
132.  		}
133.  #endif
134.  		break;
135.  	    case PM_GIANT_MIMIC:
136.  		tmp += 10;
137.  		/* fall into next case */
138.  	    case PM_LARGE_MIMIC:
139.  		tmp += 20;
140.  		/* fall into next case */
141.  	    case PM_SMALL_MIMIC:
142.  		tmp += 20;
143.  		if(u.usym == S_HUMAN) {
144.  		    You("cannot resist the temptation to mimic a treasure chest.");
145.  		    tp++;
146.  		    nomul(tmp);
147.  		    afternmv = Meatdone;
148.  		    nomovemsg = "You now again prefer mimicking a human.";
149.  		    u.usym = GOLD_SYM;
150.  		    prme();
151.  		}
152.  		break;
153.  	    case PM_FLOATING_EYE:
154.  		if (!(HTelepat & INTRINSIC)) {
155.  			HTelepat |= INTRINSIC;
156.  			You("feel a %s mental acuity.",
157.  			Hallucination ? "normal" : "strange");
158.  		}
159.  		break;
160.  	    case PM_QUANTUM_MECHANIC:
161.  		Your("velocity suddenly seems very uncertain!");
162.  		if (Fast & INTRINSIC) {
163.  			Fast &= ~INTRINSIC;
164.  			You("seem slower.");
165.  		} else {
166.  			Fast |= INTRINSIC;
167.  			You("seem faster.");
168.  		}
169.  		break;
170.  #ifdef POLYSELF
171.  	    case PM_CHAMELEON:
172.  		You("feel a change coming over you.");
173.  		polyself();
174.  		break;
175.  #endif
176.  	    default: {
177.  		register struct permonst *ptr = &mons[pm];
178.  		if(dmgtype(ptr, AD_STUN) || ptr==&mons[PM_VIOLET_FUNGUS]) {
179.  		    pline ("Oh wow!  Great stuff!");
180.  		    make_hallucinated(Hallucination + 200,FALSE);
181.  		}
182.  		if(dmgtype(ptr, AD_ACID)) {
183.  		  if(Stoned) {
184.  			pline("What a pity - you just destroyed a future piece of art!");
185.  			tp++;
186.  			Stoned = 0;
187.  		  }
188.  		}
189.  		if(is_giant(ptr)) gainstr((struct obj *)0, 0);
190.  
191.  		if(can_teleport(ptr) && ptr->mlevel > rn2(10)) {
192.  		    if (!(HTeleportation & INTRINSIC)) {
193.  			You("feel very jumpy.");
194.  			HTeleportation |= INTRINSIC;
195.  		    }
196.  		} else if(control_teleport(ptr) && ptr->mlevel > rn2(20)) {
197.  		    if (!(HTeleport_control & INTRINSIC)) {
198.  			You("feel in control of yourself.");
199.  			HTeleport_control |= INTRINSIC;
200.  		    }
201.  		} else if(resists_fire(ptr) && ptr->mlevel > rn2(20)) {
202.  		    if (!(HFire_resistance & INTRINSIC)) {
203.  			You("feel a momentary chill.");
204.  			HFire_resistance |= INTRINSIC;
205.  		    }
206.  		} else if(resists_cold(ptr) && ptr->mlevel > rn2(20)) {
207.  		    if (!(HCold_resistance & INTRINSIC)) {
208.  			You("feel full of hot air.");
209.  			HCold_resistance |= INTRINSIC;
210.  		    }
211.  		} else if((ptr->mflags1 & M1_POIS_RES) && ptr->mlevel>rn2(20)) {
212.  		/* Monsters with only M1_POIS are poison resistant themselves,
213.  		 * but do not confer resistance when eaten
214.  		 */
215.  		    if (!(HPoison_resistance & INTRINSIC)) {
216.  			You("feel healthy.");
217.  			HPoison_resistance |= INTRINSIC;
218.  		    }
219.  		} else if(resists_elec(ptr) && ptr->mlevel > rn2(20)) {
220.  		    if (!(HShock_resistance & INTRINSIC)) {
221.  			Your("health currently feels amplified!");
222.  			HShock_resistance |= INTRINSIC;
223.  		    }
224.  		} else if((ptr->mflags1 & M1_SLEE_RES) && ptr->mlevel > rn2(20)) {
225.  		/* Undead monsters never sleep,
226.  		 * but also do not confer resistance when eaten
227.  		 */
228.  		    if (!(HSleep_resistance & INTRINSIC)) {
229.  			You("feel wide awake.");
230.  			HSleep_resistance |= INTRINSIC;
231.  		    }
232.  		} else if(resists_disint(ptr) && ptr->mlevel > rn2(20)) {
233.  		    if (!(HDisint_resistance & INTRINSIC)) {
234.  			You("feel very firm.");
235.  			HDisint_resistance |= INTRINSIC;
236.  		    }
237.  		}
238.  	    }
239.  	    break;
240.  	}
241.  	return(tp);
242.  }
243.  
244.  static int
245.  opentin(){
246.  	register int r;
247.  
248.  	if(!carried(tin.tin))		/* perhaps it was stolen? */
249.  		return(0);		/* %% probably we should use tinoid */
250.  	if(tin.usedtime++ >= 50) {
251.  		You("give up your attempt to open the tin.");
252.  		return(0);
253.  	}
254.  	if(tin.usedtime < tin.reqtime)
255.  		return(1);		/* still busy */
256.  	if(tin.tin->cursed && !rn2(8)) {
257.  		b_trapped("tin");
258.  		useup(tin.tin);
259.  		return(0);
260.  	}
261.  	You("succeed in opening the tin.");
262.  	if(!tin.tin->spe) {
263.  	    if(tin.tin->corpsenm == -1) {
264.  		pline("It turns out to be empty.");
265.  		tin.tin->dknown = tin.tin->known = TRUE;
266.  		useup(tin.tin);
267.  		return(0);
268.  	    }
269.  	    r = tin.tin->cursed ? 4 : rn2(TTSZ-1); /* Always rotten if cursed */
270.  	    pline("It smells like %s.", makeplural(
271.  		  Hallucination ? rndmonnam() : mons[tin.tin->corpsenm].mname));
272.  	    pline("Eat it? ");
273.  	    if (yn() == 'n') {
274.  		if (!Hallucination) tin.tin->dknown = tin.tin->known = TRUE;
275.  		useup(tin.tin);
276.  		return 0;
277.  	    }
278.  	    You("consume %s %s.", tintxts[r].txt,
279.  		  mons[tin.tin->corpsenm].mname);
280.  	    tin.tin->dknown = tin.tin->known = TRUE;
281.  	    (void) corpsefx(tin.tin->corpsenm);
282.  	    /* check for vomiting added by GAN 01/16/87 */
283.  	    if(tintxts[r].nut < 0) {
284.  		You("vomit.");
285.  		vomit();
286.  		morehungry(-tintxts[r].nut);
287.  	    } else lesshungry(tintxts[r].nut);
288.  	    if(r == 0) {			/* Deep Fried */
289.  		Glib = rnd(15);
290.  		pline("Eating deep fried food made your %s very slippery.",
291.  			makeplural(body_part(FINGER)));
292.  	    }
293.  	} else {
294.  	    if (tin.tin->cursed)
295.  		pline("It contains some decaying %s substance.",
296.  			Hallucination ? hcolor() : green);
297.  	    else
298.  		pline("It contains spinach - this makes you feel like %s!",
299.  			Hallucination ? "Swee'pea" : "Popeye");
300.  
301.  	    lesshungry(600);
302.  	    gainstr(tin.tin, 0);
303.  	}
304.  	tin.tin->dknown = tin.tin->known = TRUE;
305.  	useup(tin.tin);
306.  	return(0);
307.  }
308.  
309.  int
310.  Hear_again()
311.  {
312.  	flags.soundok = 1;
313.  	return 0;
314.  }
315.  
316.  static void
317.  rottenfood() {
318.  
319.  	pline("Blecch!  Rotten food!");
320.  	if(!rn2(4)) {
321.  		if (Hallucination) You("feel rather trippy.");
322.  		else
323.  			You("feel rather %s.",
324.  				body_part(LIGHT_HEADED));
325.  		make_confused(HConfusion + d(2,4),FALSE);
326.  	} else if(!rn2(4) && !Blind) {
327.  		pline("Everything suddenly goes dark.");
328.  		make_blinded((long)d(2,10),FALSE);
329.  	} else if(!rn2(3)) {
330.  		if(Blind)
331.  		  pline("The world spins and you slap against the floor.");
332.  		else
333.  		  pline("The world spins and goes dark.");
334.  		flags.soundok = 0;
335.  		nomul(-rnd(10));
336.  		nomovemsg = "You are conscious again.";
337.  		afternmv = Hear_again;
338.  	}
339.  }
340.  
341.  static void
342.  eatcorpse(otmp) register struct obj *otmp; {
343.  	register char *cname = mons[otmp->corpsenm].mname;
344.  	register int tp, rotted;
345.  
346.  	tp = 0;
347.  #ifdef LINT	/* problem if more than 320K moves before try to eat */
348.  	rotted = 0;
349.  #else
350.  	rotted = (moves - otmp->age)/((long)(10 + rn2(20)));	/* how decomposed? */
351.  #endif
352.  
353.  	if(otmp->cursed) rotted += 2;
354.  	else if (otmp->blessed) rotted -= 2;
355.  
356.  	if(otmp->corpsenm != PM_ACID_BLOB && (rotted > 5)) {
357.  		tp++;
358.  		pline("Ulch - that %s was tainted!",
359.  		      mons[otmp->corpsenm].mlet != S_FUNGUS ?
360.  				"meat" : "fungoid vegetation");
361.  #ifdef POLYSELF
362.  		if (u.usym == S_FUNGUS)
363.  			pline("It doesn't seem at all sickening, though...");
364.  		else {
365.  #endif
366.  			make_sick(10L + rn2(10),FALSE);
367.  			Sprintf(corpsename, "rotted %s corpse", cname);
368.  			u.usick_cause = corpsename;
369.  			flags.botl = 1;
370.  #ifdef POLYSELF
371.  		}
372.  #endif
373.  	} else if(poisonous(&mons[otmp->corpsenm]) && rn2(5)){
374.  		pline("Ecch - that must have been poisonous!");
375.  		if(!Poison_resistance) {
376.  			losestr(rnd(4));
377.  			losehp(rnd(15), "poisonous corpse");
378.  		} else	You("seem unaffected by the poison.");
379.  		(void) corpsefx(otmp->corpsenm);
380.  		tp++;
381.  	/* now any corpse left too long will make you mildly ill */
382.  	} else if(((rotted > 5) || ((rotted > 3) && rn2(5)))
383.  #ifdef POLYSELF
384.  		&& u.usym != S_FUNGUS
385.  #endif
386.  							){
387.  		tp++;
388.  		You("feel%s sick.", (Sick) ? " very" : "");
389.  		losehp(rnd(8), "cadaver");
390.  	} else	tp = corpsefx(otmp->corpsenm);
391.  	if(!tp && !rn2(7)) {
392.  
393.  	    rottenfood();
394.  	    lesshungry((int)mons[otmp->corpsenm].cnutrit >> 2);
395.  	} else {
396.  #ifdef POLYSELF
397.  	    pline("That %s corpse %s!", cname,
398.  		carnivorous(uasmon) ? "was delicious" : "tasted terrible");
399.  #else
400.  	    pline("That %s corpse tasted terrible!", cname);
401.  #endif
402.  	    lesshungry((int)mons[otmp->corpsenm].cnutrit);
403.  	}
404.  
405.  	/* delay is weight dependant */
406.  	multi = -(3 + (mons[otmp->corpsenm].cwt >> 2));
407.  }
408.  
409.  /* Created by GAN 01/28/87
410.   * Amended by AKP 09/22/87: if not hard, don't choke, just vomit.
411.   * Amended by 3.  06/12/89: if not hard, sometimes choke anyway, to keep risk.
412.   *
413.   * Note that if you have enough food, you can always stop being Sick!
414.   * choke() returns if you don't choke, kills you if you do.
415.   */
416.  /*ARGSUSED*/
417.  static void
418.  choke(food)
419.  register struct objclass *food;
420.  {
421.  	/* only happens if you were satiated */
422.  	if(u.uhs != SATIATED) return;
423.  
424.  	if (pl_character[0] == 'K' && u.ualigntyp == U_LAWFUL)
425.  		u.ualign--;	/* gluttony is unchivalrous */
426.  
427.  #ifndef HARD
428.  	if (rn2(20)) {
429.  		You("stuff yourself and then vomit voluminously.");
430.  		morehungry(1000);	/* you just got *very* sick! */
431.  		vomit();
432.  	} else {
433.  #endif
434.  		if(food)	killer = food->oc_name;
435.  		else		killer = "exuberant appetite";
436.  		You("choke over your food.");
437.  		You("die...");
438.  		done("choked");
439.  #ifndef HARD
440.  	}
441.  #endif
442.  }
443.  
444.  int
445.  doeat() {
446.  	register struct obj *otmp;
447.  	register struct objclass *ftmp;
448.  	register int tmp;
449.  
450.  	if (!(otmp = floorfood("eat", 0))) return 0;
451.  
452.  	if(otmp->otyp == TIN) {
453.  		if (otmp->blessed) {
454.  			pline("The tin opens like magic!");
455.  			tmp = 1;
456.  		} else if(uwep) {
457.  			switch(uwep->otyp) {
458.  			case TIN_OPENER:
459.  				tmp = 1;
460.  				break;
461.  			case DAGGER:
462.  #ifdef WORM
463.  			case CRYSKNIFE:
464.  #endif
465.  				tmp = 3;
466.  				break;
467.  			case PICK_AXE:
468.  			case AXE:
469.  				tmp = 6;
470.  				break;
471.  			default:
472.  				goto no_opener;
473.  			}
474.  			pline("Using your %s you try to open the tin.",
475.  				aobjnam(uwep, NULL));
476.  		} else {
477.  		no_opener:
478.  			pline("It is not so easy to open this tin.");
479.  			if(Glib) {
480.  				pline("The tin slips out of your hands.");
481.  				if(otmp->quan > 1) {
482.  					register struct obj *obj;
483.  					obj = splitobj(otmp, 1);
484.  					if(otmp == uwep) setuwep(obj);
485.  				}
486.  				dropx(otmp);
487.  				return(1);
488.  			}
489.  			tmp = 10 + rn2(1 + 500/((int)(ACURR(A_DEX) + ACURR(A_STR))));
490.  		}
491.  		tin.reqtime = tmp;
492.  		tin.usedtime = 0;
493.  		tin.tin = otmp;
494.  		set_occupation(opentin, "opening the tin", 0);
495.  		return(1);
496.  	}
497.  
498.  	ftmp = &objects[otmp->otyp];
499.  	multi = -ftmp->oc_delay;
500.  	if(otmp->otyp == CORPSE) eatcorpse(otmp);
501.  	else {
502.  	    if (otmp->otyp != FORTUNE_COOKIE &&
503.  		otmp->otyp != DEAD_LIZARD &&
504.  		(otmp->cursed ||
505.  		 ((moves - otmp->age) > otmp->blessed ? 50 : 30)) &&
506.  		  !rn2(7)) {
507.  
508.  		rottenfood();
509.  		lesshungry(ftmp->nutrition >> 2);
510.  	    } else {
511.  		if(u.uhunger >= 1500) choke(ftmp);
512.  
513.  		switch(otmp->otyp){
514.  		case FOOD_RATION:
515.  			if(u.uhunger <= 200)
516.  			    if (Hallucination)
517.  				pline("Oh wow, like, superior, man!");
518.  			    else
519.  				pline("That food really hit the spot!");
520.  			else if(u.uhunger <= 700)
521.  				pline("That satiated your stomach!");
522.  	/* Have lesshungry() report when you are nearly full so all eating
523.  	 * warns when you are about to choke.
524.  	 */
525.  			lesshungry(ftmp->nutrition);
526.  			if(multi < 0) nomovemsg = "You finished your meal.";
527.  			break;
528.  		case TRIPE_RATION:
529.  #ifdef POLYSELF
530.  			if (carnivorous(uasmon))
531.  			    pline("That tripe ration was surprisingly good!");
532.  			else {
533.  #endif
534.  			    pline("Yak - dog food!");
535.  			    more_experienced(1,0);
536.  			    flags.botl = 1;
537.  #ifdef POLYSELF
538.  			}
539.  #endif
540.  			if(rn2(2)
541.  #ifdef POLYSELF
542.  				&& u.usym == S_HUMAN
543.  #endif
544.  							){
545.  				You("vomit.");
546.  				morehungry(20);
547.  				vomit();
548.  			} else	lesshungry(ftmp->nutrition);
549.  			break;
550.  #ifdef POLYSELF
551.  		case CLOVE_OF_GARLIC:
552.  			if (is_undead(uasmon)) {
553.  				You("cannot stand eating it.  You vomit.");
554.  				vomit();
555.  				break;
556.  			}
557.  			/* Fall through otherwise */
558.  #endif
559.  		default:
560.  			if (otmp->otyp==SLIME_MOLD && !otmp->cursed &&
561.  				otmp->spe == current_fruit)
562.  			    pline(!Hallucination ?
563.  				    "Mmm!  Your favorite!" :
564.  				    "Yum!  Your fave fruit!");
565.  			else {
566.  			    int oldquan = otmp->quan;
567.  			    otmp->quan = 1;
568.  			    pline("That %s was %s!", xname(otmp),
569.  			      otmp->cursed ?
570.  				(Hallucination ? "grody" : "terrible"):
571.  			      Hallucination ? "gnarly" : (
572.  #ifdef TOLKIEN
573.  			       otmp->otyp==CRAM_RATION ? "bland":
574.  #endif
575.  			       "delicious"));
576.  			    otmp->quan = oldquan;
577.  			}
578.  			lesshungry(ftmp->nutrition);
579.  
580.  			switch(otmp->otyp) {
581.  #ifdef POLYSELF
582.  			    case CLOVE_OF_GARLIC:
583.  				if (u.ulycn != -1) {
584.  					You("feel purified.");
585.  					if(uasmon == &mons[u.ulycn] &&
586.  					  !Polymorph_control)
587.  						rehumanize();
588.  					u.ulycn = -1;
589.  				}
590.  				break;
591.  #endif
592.  			    case DEAD_LIZARD:
593.  				/* Relief from cockatrices -dgk */
594.  				if (Stoned) {
595.  					Stoned = 0;
596.  					You("feel limber!");
597.  				}
598.  				if (HStun > 2)  make_stunned(2L,FALSE);
599.  				if (HConfusion > 2)  make_confused(2L,FALSE);
600.  				break;
601.  			    case CARROT:
602.  				make_blinded(0L,TRUE);
603.  				break;
604.  			    case FORTUNE_COOKIE:
605.  				outrumor(bcsign(otmp), TRUE);
606.  				break;
607.  			    case LUMP_OF_ROYAL_JELLY:
608.  				/* This stuff seems to be VERY healthy! */
609.  				gainstr(otmp, 1);
610.  				u.uhp += (otmp->cursed) ? -rnd(20) : rnd(20);
611.  				if(u.uhp > u.uhpmax) {
612.  					if(!rn2(17)) u.uhpmax++;
613.  					u.uhp = u.uhpmax;
614.  				} else if(u.uhp <= 0) {
615.  					killer = "rotten jelly lump";
616.  					done("died");
617.  				}
618.  				if(!otmp->cursed) heal_legs();
619.  				break;
620.  			    case EGG:
621.  				if(otmp->corpsenm == PM_COCKATRICE) {
622.  #ifdef POLYSELF
623.  				    if(!resists_ston(uasmon)) {
624.  #endif
625.  					if (!Stoned) Stoned = 5;
626.  					killer = "cockatrice egg";
627.  #ifdef POLYSELF
628.  				    }
629.  #endif
630.  				}
631.  				break;
632.  			    default:	break;
633.  			}
634.  			break;
635.  		}
636.  	    }
637.  	}
638.  	
639.  
640.  	if(multi < 0 && !nomovemsg){
641.  #ifdef LINT	/* JAR		static char msgbuf[BUFSZ]; */
642.  		char msgbuf[BUFSZ];
643.  #else
644.  		static char msgbuf[BUFSZ];
645.  #endif
646.  		/* note: ftmp->oc_name usually works, the exception being
647.  		 * for fruits.  If fruits are changed to take more time to
648.  		 * eat, this has to be modified.
649.  		 */
650.  		if (otmp->otyp != CORPSE)
651.  			Sprintf(msgbuf, "You finish eating the %s.",
652.  						ftmp->oc_name);
653.  		else
654.  			Sprintf(msgbuf, "You finish eating the %s corpse.",
655.  						mons[otmp->corpsenm].mname);
656.  		nomovemsg = msgbuf;
657.  	}
658.  	useup(otmp);
659.  	return(1);
660.  }
661.  
662.  /* called in main.c */
663.  void
664.  gethungry(){
665.  	--u.uhunger;
666.  	if(moves % 2) {
667.  		if(HRegeneration) u.uhunger--;
668.  		if(Hunger) u.uhunger--;
669.  		/* a3:  if(Hunger & LEFT_RING) u.uhunger--;
670.  			if(Hunger & RIGHT_RING) u.uhunger--;
671.  		   etc. */
672.  	}
673.  	if(moves % 20 == 0) {			/* jimt@asgb */
674.  		/* +0 rings don't do anything, so don't affect hunger */
675.  		if(uleft && uleft->otyp && (!objects[uleft->otyp].oc_charged
676.  			|| uleft->spe)) u.uhunger--;
677.  		if(uright && uright->otyp && (!objects[uright->otyp].oc_charged
678.  			|| uright->spe)) u.uhunger--;
679.  		if(uamul) u.uhunger--;
680.  		if(u.uhave_amulet) u.uhunger--;
681.  	}
682.  	newuhs(TRUE);
683.  }
684.  
685.  /* called after vomiting and after performing feats of magic */
686.  void
687.  morehungry(num)
688.  register int num;
689.  {
690.  	u.uhunger -= num;
691.  	newuhs(TRUE);
692.  }
693.  
694.  /* called after eating something (and after drinking fruit juice) */
695.  void
696.  lesshungry(num)
697.  register int num;
698.  {
699.  	u.uhunger += num;
700.  	if(u.uhunger >= 2000) choke((struct objclass *) 0);
701.  	else {
702.  	    /* Have lesshungry() report when you're nearly full so all eating
703.  	     * warns when you're about to choke.
704.  	     */
705.  	    if (u.uhunger >= 1500) {
706.  		pline("You're having a hard time getting all of it down.");
707.  		multi -= 2;
708.  		nomovemsg = "You're finally finished.";
709.  	    }
710.  	}
711.  	newuhs(FALSE);
712.  }
713.  
714.  static int
715.  unfaint() {
716.  	(void) Hear_again();
717.  	u.uhs = FAINTING;
718.  	flags.botl = 1;
719.  	return 0;
720.  }
721.  
722.  void
723.  newuhs(incr) boolean incr; {
724.  	register int newhs, h = u.uhunger;
725.  
726.  	newhs = (h > 1000) ? SATIATED :
727.  		(h > 150) ? NOT_HUNGRY :
728.  		(h > 50) ? HUNGRY :
729.  		(h > 0) ? WEAK : FAINTING;
730.  
731.  	if(newhs == FAINTING) {
732.  		if(u.uhs == FAINTED) newhs = FAINTED;
733.  		if(u.uhs <= WEAK || rn2(20-u.uhunger/10) >= 19) {
734.  			if(u.uhs != FAINTED && multi >= 0 /* %% */) {
735.  				You("faint from lack of food.");
736.  				flags.soundok = 0;
737.  				nomul(-10+(u.uhunger/10));
738.  				nomovemsg = "You regain consciousness.";
739.  				afternmv = unfaint;
740.  				newhs = FAINTED;
741.  			}
742.  		} else
743.  		if(u.uhunger < -(int)(200 + 20*ACURR(A_CON))) {
744.  			u.uhs = STARVED;
745.  			flags.botl = 1;
746.  			bot();
747.  			You("die from starvation.");
748.  			done("starved");
749.  		}
750.  	}
751.  
752.  	if(newhs != u.uhs) {
753.  		if(newhs >= WEAK && u.uhs < WEAK)
754.  			losestr(1);	/* this may kill you -- see below */
755.  		else if(newhs < WEAK && u.uhs >= WEAK)
756.  			losestr(-1);
757.  		switch(newhs){
758.  		case HUNGRY:
759.  			if (Hallucination) {
760.  			    pline((!incr) ?
761.  				"You now have a lesser case of the munchies." :
762.  				"You are getting the munchies.");
763.  			} else
764.  			    You((!incr) ? "only feel hungry now." :
765.  				  (u.uhunger < 145) ? "feel hungry." :
766.  				   "are beginning to feel hungry.");
767.  			break;
768.  		case WEAK:
769.  			if (Hallucination)
770.  			    pline((!incr) ?
771.  				  "You still have the munchies." :
772.  				  "The munchies are starting to interfere with your motor capabilities.");
773.  			else
774.  			    You((!incr) ? "feel weak now." :
775.  				  (u.uhunger < 45) ? "feel weak." :
776.  				   "are beginning to feel weak.");
777.  			break;
778.  		}
779.  		u.uhs = newhs;
780.  		flags.botl = 1;
781.  		if(u.uhp < 1) {
782.  			You("die from hunger and exhaustion.");
783.  			killer = "exhaustion";
784.  			done("starved");
785.  		}
786.  	}
787.  }
788.  
789.  struct obj *
790.  floorfood(verb,corpseonly)
791.  char *verb;
792.  int corpseonly;
793.  {
794.  	register struct obj *otmp;
795.  
796.  	/* Is there some food (probably a heavy corpse) here on the ground? */
797.  	if(!Levitation && !u.uswallow) {
798.  	if(levl[u.ux][u.uy].omask)
799.  	    for(otmp = fobj; otmp; otmp = otmp->nobj) {
800.  		if(otmp->ox == u.ux && otmp->oy == u.uy &&
801.  		   (otmp->otyp==CORPSE ||
802.  		   (!corpseonly && otmp->olet == FOOD_SYM))) {
803.  			pline("There %s %s here; %s %s? ",
804.  				(otmp->quan == 1) ? "is" : "are",
805.  				doname(otmp), verb,
806.  				(otmp->quan == 1) ? "it" : "one");
807.  			if(yn() == 'y') {
808.  				if(otmp->quan != 1)
809.  					(void) splitobj(otmp, 1);
810.  				freeobj(otmp);
811.  				otmp = addinv(otmp);
812.  				addtobill(otmp, TRUE);
813.  				if(Invisible) newsym(u.ux, u.uy);
814.  				return otmp;
815.  			}
816.  		}
817.  	    }
818.  	}
819.  	return getobj(comestibles, verb);
820.  }
821.  
822.  /* Side effects of vomiting */
823.  /* TO DO: regurgitate swallowed monsters when poly'd */
824.  void
825.  vomit() { /* A good idea from David Neves */
826.  	make_sick(0L,TRUE);
827.  }