Source:NetHack 2.3e/eat.c

From NetHackWiki
Revision as of 03:14, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 2.3e/eat.c moved to Source:NetHack 2.3e/eat.c: Robot: moved page)
Jump to navigation Jump to search

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