Source:NetHack 1.4f/eat.c

From NetHackWiki
Jump to: navigation, search

Below is the full text to eat.c from the source code of NetHack 1.4f. To link to a particular line, write [[NetHack 1.4f/eat.c#line123]], for example.

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

Screenshots and source code from Hack are used under the CWI license.

1.    /*	SCCS Id: @(#)eat.c	1.4	87/08/08
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* eat.c - version 1.0.3 */
4.    
5.    #include	"hack.h"
6.    #ifdef KAA
7.    char POISONOUS[] = "ADKSVabhks&";
8.    #else
9.    char POISONOUS[] = "ADKSVabhks";
10.   #endif
11.   extern char *nomovemsg;
12.   extern int (*afternmv)();
13.   extern int (*occupation)();
14.   extern char *occtxt;
15.   extern struct obj *splitobj(), *addinv();
16.   
17.   /* hunger texts used on bottom line (each 8 chars long) */
18.   #define	SATIATED	0
19.   #define NOT_HUNGRY	1
20.   #define	HUNGRY		2
21.   #define	WEAK		3
22.   #define	FAINTING	4
23.   #define FAINTED		5
24.   #define STARVED		6
25.   
26.   char *hu_stat[] = {
27.   	"Satiated",
28.   	"        ",
29.   	"Hungry  ",
30.   	"Weak    ",
31.   	"Fainting",
32.   	"Fainted ",
33.   	"Starved "
34.   };
35.   
36.   init_uhunger(){
37.   	u.uhunger = 900;
38.   	u.uhs = NOT_HUNGRY;
39.   }
40.   
41.   struct { char *txt; int nut; } tintxts[] = {
42.   	"It contains salmon - not bad!",	60,
43.   	"It contains first quality peaches - what a surprise!",	40,
44.   	"It contains apple juice - perhaps not what you hoped for.", 20,
45.   	"It contains some nondescript substance, tasting awfully.", 500,
46.   	"It contains rotten meat. You vomit.", -50,
47.   	"It turns out to be empty.",	0
48.   };
49.   #define	TTSZ	SIZE(tintxts)
50.   
51.   static struct {
52.   	struct obj *tin;
53.   	int usedtime, reqtime;
54.   } tin;
55.   
56.   opentin(){
57.   	register int r;
58.   
59.   	if(!carried(tin.tin))		/* perhaps it was stolen? */
60.   		return(0);		/* %% probably we should use tinoid */
61.   	if(tin.usedtime++ >= 50) {
62.   		pline("You give up your attempt to open the tin.");
63.   		return(0);
64.   	}
65.   	if(tin.usedtime < tin.reqtime)
66.   		return(1);		/* still busy */
67.   
68.   	pline("You succeed in opening the tin.");
69.   	useup(tin.tin);
70.   	r = rn2(2*TTSZ);
71.   	if(r < TTSZ) {
72.   	    pline(tintxts[r].txt);
73.   	    lesshungry(tintxts[r].nut);
74.   	    /* check for vomiting added by GAN 01/16/87 */
75.   	    if(tintxts[r].nut < 0 && Sick) {
76.   		Sick = 0;
77.   		pline("What a relief!");
78.   	    }
79.   	    if(r == 0) {			/* Salmon */
80.   		Glib = rnd(15);
81.   		pline("Eating salmon made your fingers very slippery.");
82.   	    }
83.   	} else {
84.   	    pline("It contains spinach - this makes you feel like %s!",
85.   		Hallucination ? "Swee'pea" : "Popeye");
86.   
87.   	    lesshungry(600);
88.   	    gainstr(0);
89.   	}
90.   	return(0);
91.   }
92.   
93.   Meatdone(){
94.   	u.usym = '@';
95.   	prme();
96.   }
97.   
98.   doeat(){
99.   	register struct obj *otmp;
100.  	register struct objclass *ftmp;
101.  	register tmp;
102.  
103.  	/* Is there some food (probably a heavy corpse) here on the ground? */
104.  	if(!Levitation)
105.  	for(otmp = fobj; otmp; otmp = otmp->nobj) {
106.  		if(otmp->ox == u.ux && otmp->oy == u.uy &&
107.  		   otmp->olet == FOOD_SYM) {
108.  			pline("There %s %s here; eat %s? [ny] ",
109.  				(otmp->quan == 1) ? "is" : "are",
110.  				doname(otmp),
111.  				(otmp->quan == 1) ? "it" : "one");
112.  			if(readchar() == 'y') {
113.  				if(otmp->quan != 1)
114.  					(void) splitobj(otmp, 1);
115.  				freeobj(otmp);
116.  				otmp = addinv(otmp);
117.  				addtobill(otmp);
118.  				if(Invisible) newsym(u.ux, u.uy);
119.  				goto gotit;
120.  			}
121.  		}
122.  	}
123.  	otmp = getobj("%", "eat");
124.  	if(!otmp) return(0);
125.  gotit:
126.  	if(otmp->otyp == TIN) {
127.  		if(uwep) {
128.  			switch(uwep->otyp) {
129.  			case CAN_OPENER:
130.  				tmp = 1;
131.  				break;
132.  			case DAGGER:
133.  			case CRYSKNIFE:
134.  				tmp = 3;
135.  				break;
136.  			case PICK_AXE:
137.  			case AXE:
138.  				tmp = 6;
139.  				break;
140.  			default:
141.  				goto no_opener;
142.  			}
143.  			pline("Using your %s you try to open the tin.",
144.  				aobjnam(uwep, (char *) 0));
145.  		} else {
146.  		no_opener:
147.  			pline("It is not so easy to open this tin.");
148.  			if(Glib) {
149.  				pline("The tin slips out of your hands.");
150.  				if(otmp->quan > 1) {
151.  					register struct obj *obj;
152.  					extern struct obj *splitobj();
153.  
154.  					obj = splitobj(otmp, 1);
155.  					if(otmp == uwep) setuwep(obj);
156.  				}
157.  				dropx(otmp);
158.  				return(1);
159.  			}
160.  			tmp = 10 + rn2(1 + 500/((int)(u.ulevel + u.ustr)));
161.  		}
162.  		tin.reqtime = tmp;
163.  		tin.usedtime = 0;
164.  		tin.tin = otmp;
165.  #ifdef DGK
166.  		set_occupation(opentin, "opening the tin", 0);
167.  #else
168.  		occupation = opentin;
169.  		occtxt = "opening the tin";
170.  #endif
171.  		return(1);
172.  	}
173.  	ftmp = &objects[otmp->otyp];
174.  	multi = -ftmp->oc_delay;
175.  	if(otmp->otyp >= CORPSE && eatcorpse(otmp)) goto eatx;
176.  #ifdef DGKMOD
177.  	if(!rn2(7) && otmp->otyp != FORTUNE_COOKIE && otmp->otyp != DEAD_LIZARD) {
178.  #else
179.  	if(!rn2(7) && otmp->otyp != FORTUNE_COOKIE) {
180.  #endif
181.  #ifdef KAA
182.  		if (otmp->otyp == DEAD_VIOLET_FUNGUS)
183.  			pline("Seems rather stale though...");
184.  		else
185.  #endif
186.  		pline("Blecch!  Rotten food!");
187.  		if(!rn2(4)) {
188.  			if (Hallucination) pline("You feel rather trippy.");
189.  			else
190.  				pline("You feel rather light headed.");
191.  			HConfusion += d(2,4);
192.  		} else if(!rn2(4) && !Blind) {
193.  			pline("Everything suddenly goes dark.");
194.  			Blind = d(2,10);
195.  			seeoff(0);
196.  		} else if(!rn2(3)) {
197.  			if(Blind)
198.  			  pline("The world spins and you slap against the floor.");
199.  			else
200.  			  pline("The world spins and goes dark.");
201.  			nomul(-rnd(10));
202.  			nomovemsg = "You are conscious again.";
203.  		}
204.  		lesshungry(ftmp->nutrition / 4);
205.  	} else {
206.  		if(u.uhunger >= 1500) choke(ftmp);
207.  
208.  		switch(otmp->otyp){
209.  		case FOOD_RATION:
210.  			if(u.uhunger <= 200)
211.  			    if (Hallucination)
212.  				pline("Oh wow, like superior man!");
213.  			    else
214.  				pline("That food really hit the spot!");
215.  			else if(u.uhunger <= 700)
216.  				pline("That satiated your stomach!");
217.  #ifdef DGKMOD
218.  	/* Have lesshungry() report when you're nearly full so all eating
219.  	 * warns when you're about to choke.
220.  	 */
221.  			lesshungry(ftmp->nutrition);
222.  #else
223.  			else {
224.  	pline("You're having a hard time getting all that food down.");
225.  				multi -= 2;
226.  			}
227.  			lesshungry(ftmp->nutrition);
228.  			if(multi < 0) nomovemsg = "You finished your meal.";
229.  #endif /* DGKMOD /**/
230.  			break;
231.  		case TRIPE_RATION:
232.  			if (u.usym != '@')
233.  			    pline("That tripe ration was surprisingly good!");
234.  			else {
235.  			    pline("Yak - dog food!");
236.  			    more_experienced(1,0);
237.  			    flags.botl = 1;
238.  			}
239.  			if(rn2(2) && u.usym == '@'){
240.  				pline("You vomit.");
241.  				morehungry(20);
242.  				if(Sick) {
243.  					Sick = 0;	/* David Neves */
244.  					pline("What a relief!");
245.  				}
246.  			} else	lesshungry(ftmp->nutrition);
247.  			break;
248.  		default:
249.  			if(u.usym == '@' && otmp->otyp >= CORPSE) {
250.  #ifdef KAA
251.  			    if(otmp->otyp != DEAD_VIOLET_FUNGUS)
252.  #endif
253.  			    pline("That %s tasted terrible!",ftmp->oc_name);
254.  			} else
255.  			pline("That %s was delicious!",ftmp->oc_name);
256.  			lesshungry(ftmp->nutrition);
257.  #ifdef DGKMOD
258.  			/* Relief from cockatrices -dgk */
259.  			if (otmp->otyp == DEAD_LIZARD) {
260.  				if (Stoned) {
261.  					Stoned = 0;
262.  					pline("You feel more limber!");
263.  				}
264.  				if (HConfusion > 2)
265.  					HConfusion = 2;
266.  			}
267.  #else
268.  			if(otmp->otyp == DEAD_LIZARD && (HConfusion > 2))
269.  				HConfusion = 2;
270.  #endif /* DGKMOD /**/
271.  			else
272.  #ifdef QUEST
273.  			if(otmp->otyp == CARROT && !Blind){
274.  				u.uhorizon++;
275.  				setsee();
276.  				pline("Your vision improves.");
277.  			} else
278.  #endif
279.  #ifdef KAA
280.  			if(otmp->otyp == CARROT && Blind) Blind=1;
281.  			else
282.  #endif
283.  			if(otmp->otyp == FORTUNE_COOKIE) {
284.  			  if(Blind) {
285.  			    pline("This cookie has a scrap of paper inside!");
286.  			    pline("What a pity, that you cannot read it!");
287.  			  } else
288.  			    outrumor();
289.  			} else
290.  			if(otmp->otyp == LUMP_OF_ROYAL_JELLY) {
291.  				/* This stuff seems to be VERY healthy! */
292.  				gainstr(1);
293.  				u.uhp += rnd(20);
294.  				if(u.uhp > u.uhpmax) {
295.  					if(!rn2(17)) u.uhpmax++;
296.  					u.uhp = u.uhpmax;
297.  				}
298.  				heal_legs();
299.  			}
300.  			break;
301.  		}
302.  	}
303.  eatx:
304.  	if(multi<0 && !nomovemsg){
305.  		static char msgbuf[BUFSZ];
306.  		(void) sprintf(msgbuf, "You finished eating the %s.",
307.  				ftmp->oc_name);
308.  		nomovemsg = msgbuf;
309.  	}
310.  	useup(otmp);
311.  	return(1);
312.  }
313.  
314.  /* called in main.c */
315.  gethungry(){
316.  	--u.uhunger;
317.  	if(moves % 2) {
318.  		if(HRegeneration) u.uhunger--;
319.  		if(Hunger) u.uhunger--;
320.  		/* a3:  if(Hunger & LEFT_RING) u.uhunger--;
321.  			if(Hunger & RIGHT_RING) u.uhunger--;
322.  		   etc. */
323.  	}
324.  	if(moves % 20 == 0) {			/* jimt@asgb */
325.  		if(uleft) u.uhunger--;
326.  		if(uright) u.uhunger--;
327.  	}
328.  	newuhs(TRUE);
329.  }
330.  
331.  /* called after vomiting and after performing feats of magic */
332.  morehungry(num) register num; {
333.  	u.uhunger -= num;
334.  	newuhs(TRUE);
335.  }
336.  
337.  /* called after eating something (and after drinking fruit juice) */
338.  lesshungry(num) register num; {
339.  	u.uhunger += num;
340.  	if(u.uhunger >= 2000) choke(FALSE);
341.  #ifdef DGKMOD
342.  	else {
343.  	    /* Have lesshungry() report when you're nearly full so all eating
344.  	     * warns when you're about to choke.
345.  	     */
346.  	    if (u.uhunger >= 1500) {
347.  		pline("You're having a hard time getting all of it down.");
348.  		multi -= 2;
349.  		nomovemsg = "You're finally finished.";
350.  	    }
351.  	}
352.  #endif /* DGKMOD /**/
353.  	newuhs(FALSE);
354.  }
355.  
356.  unfaint(){
357.  	u.uhs = FAINTING;
358.  	flags.botl = 1;
359.  }
360.  
361.  newuhs(incr) boolean incr; {
362.  	register int newhs, h = u.uhunger;
363.  
364.  	newhs = (h > 1000) ? SATIATED :
365.  		(h > 150) ? NOT_HUNGRY :
366.  		(h > 50) ? HUNGRY :
367.  		(h > 0) ? WEAK : FAINTING;
368.  
369.  	if(newhs == FAINTING) {
370.  		if(u.uhs == FAINTED) newhs = FAINTED;
371.  		if(u.uhs <= WEAK || rn2(20-u.uhunger/10) >= 19) {
372.  			if(u.uhs != FAINTED && multi >= 0 /* %% */) {
373.  				pline("You faint from lack of food.");
374.  				nomul(-10+(u.uhunger/10));
375.  				nomovemsg = "You regain consciousness.";
376.  				afternmv = unfaint;
377.  				newhs = FAINTED;
378.  			}
379.  		} else
380.  		if(u.uhunger < -(int)(200 + 25*u.ulevel)) {
381.  			u.uhs = STARVED;
382.  			flags.botl = 1;
383.  			bot();
384.  			pline("You die from starvation.");
385.  			done("starved");
386.  		}
387.  	}
388.  
389.  	if(newhs != u.uhs) {
390.  		if(newhs >= WEAK && u.uhs < WEAK)
391.  			losestr(1);	/* this may kill you -- see below */
392.  		else
393.  		if(newhs < WEAK && u.uhs >= WEAK && u.ustr < u.ustrmax)
394.  			losestr(-1);
395.  		switch(newhs){
396.  		case HUNGRY:
397.  			if (Hallucination) {
398.  			    pline((!incr) ?
399.  				"You now have a lesser case of the munchies." :
400.  				"You are getting the munchies.");
401.  			} else
402.  			    pline((!incr) ? "You only feel hungry now." :
403.  				  (u.uhunger < 145) ? "You feel hungry." :
404.  				   "You are beginning to feel hungry.");
405.  			break;
406.  		case WEAK:
407.  			if (Hallucination)
408.  			    pline((!incr) ?
409.  				  "You still have the munchies." :
410.  				  "The munchies are starting to interfere with your motor capabilities.");
411.  			else
412.  			    pline((!incr) ? "You feel weak now." :
413.  				  (u.uhunger < 45) ? "You feel weak." :
414.  				   "You are beginning to feel weak.");
415.  			break;
416.  		}
417.  		u.uhs = newhs;
418.  		flags.botl = 1;
419.  		if(u.uhp < 1) {
420.  			pline("You die from hunger and exhaustion.");
421.  			killer = "exhaustion";
422.  			done("starved");
423.  		}
424.  	}
425.  }
426.  
427.  #define	CORPSE_I_TO_C(otyp)	(char) ((otyp >= DEAD_ACID_BLOB)\
428.  		     ?  'a' + (otyp - DEAD_ACID_BLOB)\
429.  		     :	'@' + (otyp - DEAD_HUMAN))
430.  poisonous(otmp)
431.  register struct obj *otmp;
432.  {
433.  #ifdef KAA
434.  	if(otmp->otyp == DEAD_DEMON) return(1);
435.  #endif
436.  	return(index(POISONOUS, CORPSE_I_TO_C(otmp->otyp)) != 0);
437.  }
438.  
439.  /* returns 1 if some text was printed */
440.  eatcorpse(otmp) register struct obj *otmp; {
441.  #ifdef KAA
442.  register char let;
443.  #else
444.  register char let = CORPSE_I_TO_C(otmp->otyp);
445.  #endif
446.  register tp = 0;
447.  #ifdef KAA
448.  	if(otmp->otyp == DEAD_DEMON) let='&';
449.  	else if (otmp->otyp == DEAD_GIANT) let='9';
450.  	else let = CORPSE_I_TO_C(otmp->otyp);
451.  #endif
452.  	if(let != 'a' && moves > otmp->age + 50 + rn2(100)) {
453.  		tp++;
454.  		pline("Ulch -- that meat was tainted!");
455.  		pline("You get very sick.");
456.  		Sick = 10 + rn2(10);
457.  		u.usick_cause = objects[otmp->otyp].oc_name;
458.  	} else if(index(POISONOUS, let) && rn2(5)){
459.  		tp++;
460.  		pline("Ecch -- that must have been poisonous!");
461.  		if(!Poison_resistance){
462.  			losestr(rnd(4));
463.  			losehp(rnd(15), "poisonous corpse");
464.  		} else
465.  			pline("You don't seem affected by the poison.");
466.  	} else if(index("ELNOPQRUuxz", let) && rn2(5)){
467.  		tp++;
468.  		pline("You feel sick.");
469.  		losehp(rnd(8), "cadaver");
470.  	}
471.  	switch(let) {
472.  	case 'L':
473.  	case 'N':
474.  	case 't':
475.  #ifdef KAA
476.  	case 'Q':
477.  #endif
478.  		HTeleportation |= INTRINSIC;
479.  		break;
480.  	case 'W':
481.  		pluslvl();
482.  		break;
483.  	case 'n':
484.  		u.uhp = u.uhpmax;
485.  		flags.botl = 1;
486.  		/* fall into next case */
487.  	case '@':
488.  		pline("You cannibal! You will be sorry for this!");
489.  		/* not tp++; */
490.  		/* fall into next case */
491.  	case 'd':
492.  		Aggravate_monster |= INTRINSIC;
493.  		break;
494.  	case 'I':
495.  		if(!Invis) {
496.  			HInvis = 50+rn2(100);
497.  			if(!See_invisible)
498.  				newsym(u.ux, u.uy);
499.  		} else {
500.  			HInvis |= INTRINSIC;
501.  			HSee_invisible |= INTRINSIC;
502.  		}
503.  		/* fall into next case */
504.  	case 'y':
505.  #ifdef QUEST
506.  		u.uhorizon++;
507.  #endif
508.  		/* fall into next case */
509.  	case 'B':
510.  		HConfusion += 50;
511.  		break;
512.  	case 'D':
513.  		HFire_resistance |= INTRINSIC;
514.  		break;
515.  	case 'E':
516.  		HTelepat |= INTRINSIC;
517.  		break;
518.  	case 'F':
519.  	case 'Y':
520.  		HCold_resistance |= INTRINSIC;
521.  		break;
522.  #ifdef KAA
523.  	case '9':
524.  		gainstr(1);
525.  		break;
526.  #endif
527.  	case 'k':
528.  	case 's':
529.  		HPoison_resistance |= INTRINSIC;
530.  		break;
531.  	case 'c':
532.  		if (u.usym != 'c') {
533.  
534.  			pline("You turn to stone.");
535.  			killer = "dead cockatrice";
536.  			done("died");
537.  		}
538.  		break;
539.  	case 'a':
540.  	  if(Stoned) {
541.  	      pline("What a pity - you just destroyed a future piece of art!");
542.  	      tp++;
543.  	      Stoned = 0;
544.  	  }
545.  	  break;
546.  #ifdef KAA
547.  	case 'v':
548.  		pline ("Oh wow!  Great stuff!");
549.  		Hallucination += 200;
550.  		setsee();
551.  		break;
552.  #endif
553.  	case 'M':
554.  		if(u.usym == '@') {
555.  		    pline("You cannot resist the temptation to mimic a treasure chest.");
556.  		    tp++;
557.  		    nomul(-30);
558.  		    afternmv = Meatdone;
559.  		    nomovemsg = "You now again prefer mimicking a human.";
560.  		    u.usym = GOLD_SYM;
561.  		    prme();
562.  		}
563.  		break;
564.  	}
565.  	return(tp);
566.  }
567.  
568.  /* added by GAN 01/28/87 */
569.  choke(food)
570.  register struct objclass *food;
571.  {
572.  	/* only happens if you were satiated */
573.  	if(u.uhs != SATIATED) return;
574.  
575.  	if(food)	killer = food->oc_name;
576.  	else		killer = "exuberant appetite";
577.  	pline("You choke over your food.");
578.  	pline("You die...");
579.  	done("choked");
580.  }