Fandom

Wikihack

Source:NetHack 3.2.0/eat.c

2,034pages on
this wiki
Add New Page
Talk0

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

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

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.
1.    /*	SCCS Id: @(#)eat.c	3.2	96/03/06	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    /* #define DEBUG	/* uncomment to enable new eat code debugging */
7.    
8.    #ifdef DEBUG
9.    # ifdef WIZARD
10.   #define debugpline	if (wizard) pline
11.   # else
12.   #define debugpline	pline
13.   # endif
14.   #endif
15.   
16.   STATIC_PTR int NDECL(eatmdone);
17.   STATIC_PTR int NDECL(eatfood);
18.   STATIC_PTR int NDECL(opentin);
19.   STATIC_PTR int NDECL(unfaint);
20.   
21.   #ifdef OVLB
22.   static void FDECL(choke, (struct obj *));
23.   static void NDECL(recalc_wt);
24.   static struct obj *FDECL(touchfood, (struct obj *));
25.   static void NDECL(do_reset_eat);
26.   static void FDECL(done_eating, (BOOLEAN_P));
27.   static void FDECL(cprefx, (int));
28.   static int FDECL(intrinsic_possible, (int,struct permonst *));
29.   static void FDECL(givit, (int,struct permonst *));
30.   static void FDECL(cpostfx, (int));
31.   static void FDECL(start_tin, (struct obj *));
32.   static int FDECL(eatcorpse, (struct obj *));
33.   static void FDECL(start_eating, (struct obj *));
34.   static void FDECL(fprefx, (struct obj *));
35.   static void FDECL(fpostfx, (struct obj *));
36.   static int NDECL(bite);
37.   
38.   static int FDECL(rottenfood, (struct obj *));
39.   static void NDECL(eatspecial);
40.   static void FDECL(eataccessory, (struct obj *));
41.   static const char * FDECL(foodword, (struct obj *));
42.   
43.   char msgbuf[BUFSZ];
44.   
45.   #endif /* OVLB */
46.   
47.   /* hunger texts used on bottom line (each 8 chars long) */
48.   #define SATIATED	0
49.   #define NOT_HUNGRY	1
50.   #define HUNGRY		2
51.   #define WEAK		3
52.   #define FAINTING	4
53.   #define FAINTED		5
54.   #define STARVED		6
55.   
56.   #ifndef OVLB
57.   
58.   STATIC_DCL NEARDATA const char comestibles[];
59.   STATIC_DCL NEARDATA const char allobj[];
60.   STATIC_DCL boolean force_save_hs;
61.   
62.   #else
63.   
64.   STATIC_OVL NEARDATA const char comestibles[] = { FOOD_CLASS, 0 };
65.   
66.   /* Gold must come first for getobj(). */
67.   STATIC_OVL NEARDATA const char allobj[] = {
68.   	GOLD_CLASS, WEAPON_CLASS, ARMOR_CLASS, POTION_CLASS, SCROLL_CLASS,
69.   	WAND_CLASS, RING_CLASS, AMULET_CLASS, FOOD_CLASS, TOOL_CLASS,
70.   	GEM_CLASS, ROCK_CLASS, BALL_CLASS, CHAIN_CLASS, SPBOOK_CLASS, 0 };
71.   
72.   STATIC_OVL boolean force_save_hs = FALSE;
73.   
74.   const char *hu_stat[] = {
75.   	"Satiated",
76.   	"        ",
77.   	"Hungry  ",
78.   	"Weak    ",
79.   	"Fainting",
80.   	"Fainted ",
81.   	"Starved "
82.   };
83.   
84.   #endif /* OVLB */
85.   #ifdef OVL1
86.   
87.   /*
88.    * Decide whether a particular object can be eaten by the possibly
89.    * polymorphed character.  Not used for monster checks.
90.    */
91.   boolean
92.   is_edible(obj)
93.   register struct obj *obj;
94.   {
95.   	/* protect invocation tools but not Rider corpses (handled elsewhere)*/
96.        /* if (obj->oclass != FOOD_CLASS && obj_resists(obj, 0, 0)) */
97.   	if (objects[obj->otyp].oc_unique)
98.   		return FALSE;
99.   	/* above also prevents the Amulet from being eaten, so we must never
100.  	   allow fake amulets to be eaten either [which is already the case] */
101.  
102.  	if (metallivorous(uasmon) && is_metallic(obj))
103.  		return TRUE;
104.  	if (u.umonnum == PM_GELATINOUS_CUBE && is_organic(obj) &&
105.  		/* [g.cubes can eat containers and retain all contents
106.  		    as engulged items, but poly'd player can't do that] */
107.  	    !Has_contents(obj))
108.  		return TRUE;
109.  
110.       /* return((boolean)(!!index(comestibles, obj->oclass))); */
111.  	return (boolean)(obj->oclass == FOOD_CLASS);
112.  }
113.  
114.  #endif /* OVL1 */
115.  #ifdef OVLB
116.  
117.  void
118.  init_uhunger()
119.  {
120.  	u.uhunger = 900;
121.  	u.uhs = NOT_HUNGRY;
122.  }
123.  
124.  static const struct { const char *txt; int nut; } tintxts[] = {
125.  	{"deep fried",	 60},
126.  	{"pickled",	 40},
127.  	{"soup made from", 20},
128.  	{"pureed",	500},
129.  	{"rotten",	-50},
130.  	{"homemade",	 50},
131.  	{"", 0}
132.  };
133.  #define TTSZ	SIZE(tintxts)
134.  
135.  static NEARDATA struct {
136.  	struct	obj *tin;
137.  	int	usedtime, reqtime;
138.  } tin;
139.  
140.  static NEARDATA struct {
141.  	struct	obj *piece;	/* the thing being eaten, or last thing that
142.  				 * was partially eaten, unless that thing was
143.  				 * a tin, which uses the tin structure above */
144.  	int	usedtime,	/* turns spent eating */
145.  		reqtime;	/* turns required to eat */
146.  	int	nmod;		/* coded nutrition per turn */
147.  	Bitfield(canchoke,1);	/* was satiated at beginning */
148.  	Bitfield(fullwarn,1);	/* have warned about being full */
149.  	Bitfield(eating,1);	/* victual currently being eaten */
150.  	Bitfield(doreset,1);	/* stop eating at end of turn */
151.  } victual;
152.  
153.  STATIC_PTR
154.  int
155.  eatmdone()		/* called after mimicing is over */
156.  {
157.  	u.usym = Upolyd ? uasmon->mlet : S_HUMAN;
158.  	newsym(u.ux,u.uy);
159.  	return 0;
160.  }
161.  
162.  /* Created by GAN 01/28/87
163.   * Amended by AKP 09/22/87: if not hard, don't choke, just vomit.
164.   * Amended by 3.  06/12/89: if not hard, sometimes choke anyway, to keep risk.
165.   *		  11/10/89: if hard, rarely vomit anyway, for slim chance.
166.   */
167.  /*ARGSUSED*/
168.  static void
169.  choke(food)	/* To a full belly all food is bad. (It.) */
170.  	register struct obj *food;
171.  {
172.  	/* only happens if you were satiated */
173.  	if(u.uhs != SATIATED) return;
174.  
175.  	if (Role_is('K') && u.ualign.type == A_LAWFUL)
176.  		adjalign(-1);		/* gluttony is unchivalrous */
177.  
178.  	exercise(A_CON, FALSE);
179.  
180.  	if (Breathless || (!Strangled && !rn2(20))) {
181.  		You("stuff yourself and then vomit voluminously.");
182.  		morehungry(1000);	/* you just got *very* sick! */
183.  		vomit();
184.  	} else {
185.  		killer_format = KILLED_BY_AN;
186.  		/*
187.  		 * Note all "killer"s below read "Choked on %s" on the
188.  		 * high score list & tombstone.  So plan accordingly.
189.  		 */
190.  		if(food) {
191.  			You("choke over your %s.", foodword(food));
192.  			if (food->oclass == GOLD_CLASS) {
193.  				killer = "a very rich meal";
194.  			} else {
195.  				killer = singular(food, xname);
196.  			}
197.  		} else {
198.  			You("choke over it.");
199.  			killer = "quick snack";
200.  		}
201.  		You("die...");
202.  		done(CHOKING);
203.  	}
204.  }
205.  
206.  static void
207.  recalc_wt()	/* modify object wt. depending on time spent consuming it */
208.  {
209.  	register struct obj *piece = victual.piece;
210.  
211.  #ifdef DEBUG
212.  	debugpline("Old weight = %d", piece->owt);
213.  	debugpline("Used time = %d, Req'd time = %d",
214.  		victual.usedtime, victual.reqtime);
215.  #endif
216.  	/* weight(piece) = weight of full item */
217.  	if(victual.usedtime)
218.  	    piece->owt = eaten_stat(weight(piece), piece);
219.  #ifdef DEBUG
220.  	debugpline("New weight = %d", piece->owt);
221.  #endif
222.  }
223.  
224.  void
225.  reset_eat()		/* called when eating interrupted by an event */
226.  {
227.      /* we only set a flag here - the actual reset process is done after
228.       * the round is spent eating.
229.       */
230.  	if(victual.eating && !victual.doreset) {
231.  #ifdef DEBUG
232.  	    debugpline("reset_eat...");
233.  #endif
234.  	    victual.doreset = TRUE;
235.  	}
236.  	return;
237.  }
238.  
239.  static struct obj *
240.  touchfood(otmp)
241.  register struct obj *otmp;
242.  {
243.  	if (otmp->quan > 1L) {
244.  	    if(!carried(otmp))
245.  		(void) splitobj(otmp, 1L);
246.  	    else
247.  		otmp = splitobj(otmp, otmp->quan - 1L);
248.  #ifdef DEBUG
249.  	    debugpline("split object,");
250.  #endif
251.  	}
252.  
253.  	if (!otmp->oeaten) {
254.  	    if(((!carried(otmp) && costly_spot(otmp->ox, otmp->oy) &&
255.  		 !otmp->no_charge)
256.  		 || otmp->unpaid) &&
257.  		 (otmp->otyp == CORPSE || objects[otmp->otyp].oc_delay > 1)) {
258.  		/* create a dummy duplicate to put on bill */
259.  		verbalize("You bit it, you bought it!");
260.  		bill_dummy_object(otmp);
261.  		otmp->no_charge = 1;	/* you now own this */
262.  	    }
263.  	    otmp->oeaten = (otmp->otyp == CORPSE ?
264.  				mons[otmp->corpsenm].cnutrit :
265.  				objects[otmp->otyp].oc_nutrition);
266.  	}
267.  
268.  	if (carried(otmp)) {
269.  	    freeinv(otmp);
270.  	    if (inv_cnt() >= 52 && !merge_choice(invent, otmp))
271.  		dropy(otmp);
272.  	    else
273.  		otmp = addinv(otmp); /* unlikely but a merge is possible */
274.  	}
275.  	return(otmp);
276.  }
277.  
278.  /* When food decays, in the middle of your meal, we don't want to dereference
279.   * any dangling pointers, so set it to null (which should still trigger
280.   * do_reset_eat() at the beginning of eatfood()) and check for null pointers
281.   * in do_reset_eat().
282.   */
283.  void
284.  food_disappears(obj)
285.  register struct obj *obj;
286.  {
287.  	if (obj == victual.piece) victual.piece = (struct obj *)0;
288.  	if (obj->timed) obj_stop_timers(obj);
289.  }
290.  
291.  static void
292.  do_reset_eat()
293.  {
294.  #ifdef DEBUG
295.  	debugpline("do_reset_eat...");
296.  #endif
297.  	if (victual.piece) {
298.  		victual.piece = touchfood(victual.piece);
299.  		recalc_wt();
300.  	}
301.  	victual.fullwarn = victual.eating = victual.doreset = FALSE;
302.  	/* Do not set canchoke to FALSE; if we continue eating the same object
303.  	 * we need to know if canchoke was set when they started eating it the
304.  	 * previous time.  And if we don't continue eating the same object
305.  	 * canchoke always gets recalculated anyway.
306.  	 */
307.  	stop_occupation();
308.  	newuhs(FALSE);
309.  }
310.  
311.  STATIC_PTR
312.  int
313.  eatfood()		/* called each move during eating process */
314.  {
315.  	if(!victual.piece ||
316.  	 (!carried(victual.piece) && !obj_here(victual.piece, u.ux, u.uy))) {
317.  		/* maybe it was stolen? */
318.  		do_reset_eat();
319.  		return(0);
320.  	}
321.  	if(!victual.eating) return(0);
322.  
323.  	if(++victual.usedtime <= victual.reqtime) {
324.  	    if(bite()) return(0);
325.  	    return(1);	/* still busy */
326.  	} else {	/* done */
327.  	    done_eating(TRUE);
328.  	    return(0);
329.  	}
330.  }
331.  
332.  static void
333.  done_eating(message)
334.  boolean message;
335.  {
336.  #ifndef NO_SIGNAL
337.  	victual.piece->in_use = TRUE;
338.  #endif
339.  	occupation = 0; /* do this early, so newuhs() knows we're done */
340.  	newuhs(FALSE);
341.  	if (nomovemsg) {
342.  		if (message) pline(nomovemsg);
343.  		nomovemsg = 0;
344.  	} else if (message)
345.  		You("finish eating %s.", the(singular(victual.piece, xname)));
346.  
347.  	if(victual.piece->otyp == CORPSE)
348.  		cpostfx(victual.piece->corpsenm);
349.  	else
350.  		fpostfx(victual.piece);
351.  
352.  	if (carried(victual.piece)) useup(victual.piece);
353.  	else useupf(victual.piece);
354.  	victual.piece = (struct obj *) 0;
355.  	victual.fullwarn = victual.eating = victual.doreset = FALSE;
356.  }
357.  
358.  static void
359.  cprefx(pm)
360.  register int pm;
361.  {
362.  	boolean fix_petrification = FALSE;
363.  
364.  	if (Role_is('E') ? is_elf(&mons[pm]) : is_human(&mons[pm])) {
365.  		if (uasmon != &playermon) {
366.  			You("have a bad feeling deep inside.");
367.  		}
368.  		You("cannibal!  You will regret this!");
369.  		Aggravate_monster |= FROMOUTSIDE;
370.  		change_luck(-rn1(4,2));		/* -5..-2 */
371.  	}
372.  
373.  	switch(pm) {
374.  	    case PM_LITTLE_DOG:
375.  	    case PM_DOG:
376.  	    case PM_LARGE_DOG:
377.  	    case PM_KITTEN:
378.  	    case PM_HOUSECAT:
379.  	    case PM_LARGE_CAT:
380.  		You_feel("that eating the %s was a bad idea.", mons[pm].mname);
381.  		Aggravate_monster |= FROMOUTSIDE;
382.  		break;
383.  	    case PM_COCKATRICE:
384.  	    case PM_MEDUSA:
385.  		if (!resists_ston(&youmonst) &&
386.  		    !(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))) {
387.  			char *cruft;	/* killer is const char * */
388.  			killer_format = KILLED_BY;
389.  			killer = cruft = (char *)  /* sizeof "s" includes \0 */
390.  					alloc((unsigned) strlen(mons[pm].mname)
391.  						+ sizeof " meat");
392.  			Sprintf(cruft, "%s meat", mons[pm].mname);
393.  			You("turn to stone.");
394.  			done(STONING);
395.  			}
396.  			break;
397.  	    case PM_LIZARD:
398.  		if (Stoned) fix_petrification = TRUE;
399.  		break;
400.  	    case PM_DEATH:
401.  	    case PM_PESTILENCE:
402.  	    case PM_FAMINE:
403.  		{ char buf[BUFSZ];
404.  		    pline("Eating that is instantly fatal.");
405.  		    Sprintf(buf, "unwisely ate the body of %s",
406.  			    mons[pm].mname);
407.  		    killer = buf;
408.  		    killer_format = NO_KILLER_PREFIX;
409.  		    done(DIED);
410.  		    /* It so happens that since we know these monsters */
411.  		    /* cannot appear in tins, victual.piece will always */
412.  		    /* be what we want, which is not generally true. */
413.  		    (void) revive_corpse(victual.piece);
414.  		    return;
415.  		}
416.  	    default:
417.  		if (acidic(&mons[pm]) && Stoned)
418.  		    fix_petrification = TRUE;
419.  		break;
420.  	}
421.  
422.  	if (fix_petrification) {
423.  	    Stoned = 0;
424.  	    if (!Hallucination)
425.  		You_feel("limber!");
426.  	    else
427.  		pline("What a pity - you just ruined a future piece of %sart!",
428.  		      ACURR(A_CHA) > 15 ? "fine " : "");
429.  	}
430.  
431.  	return;
432.  }
433.  
434.  
435.  /*
436.   * If you add an intrinsic that can be gotten by eating a monster, add it
437.   * to intrinsic_possible() and givit().  (It must already be in prop.h to
438.   * be an intrinsic property.)
439.   * It would be very easy to make the intrinsics not try to give you one
440.   * that you already had by checking to see if you have it in
441.   * intrinsic_possible() instead of givit().
442.   */
443.  
444.  /* intrinsic_possible() returns TRUE iff a monster can give an intrinsic. */
445.  static int
446.  intrinsic_possible(type, ptr)
447.  int type;
448.  register struct permonst *ptr;
449.  {
450.  	switch (type) {
451.  	    case FIRE_RES:
452.  #ifdef DEBUG
453.  		if (ptr->mconveys & MR_FIRE) {
454.  			debugpline("can get fire resistance");
455.  			return(TRUE);
456.  		} else  return(FALSE);
457.  #else
458.  		return(ptr->mconveys & MR_FIRE);
459.  #endif
460.  	    case SLEEP_RES:
461.  #ifdef DEBUG
462.  		if (ptr->mconveys & MR_SLEEP) {
463.  			debugpline("can get sleep resistance");
464.  			return(TRUE);
465.  		} else  return(FALSE);
466.  #else
467.  		return(ptr->mconveys & MR_SLEEP);
468.  #endif
469.  	    case COLD_RES:
470.  #ifdef DEBUG
471.  		if (ptr->mconveys & MR_COLD) {
472.  			debugpline("can get cold resistance");
473.  			return(TRUE);
474.  		} else  return(FALSE);
475.  #else
476.  		return(ptr->mconveys & MR_COLD);
477.  #endif
478.  	    case DISINT_RES:
479.  #ifdef DEBUG
480.  		if (ptr->mconveys & MR_DISINT) {
481.  			debugpline("can get disintegration resistance");
482.  			return(TRUE);
483.  		} else  return(FALSE);
484.  #else
485.  		return(ptr->mconveys & MR_DISINT);
486.  #endif
487.  	    case SHOCK_RES:	/* shock (electricity) resistance */
488.  #ifdef DEBUG
489.  		if (ptr->mconveys & MR_ELEC) {
490.  			debugpline("can get shock resistance");
491.  			return(TRUE);
492.  		} else  return(FALSE);
493.  #else
494.  		return(ptr->mconveys & MR_ELEC);
495.  #endif
496.  	    case POISON_RES:
497.  #ifdef DEBUG
498.  		if (ptr->mconveys & MR_POISON) {
499.  			debugpline("can get poison resistance");
500.  			return(TRUE);
501.  		} else  return(FALSE);
502.  #else
503.  		return(ptr->mconveys & MR_POISON);
504.  #endif
505.  	    case TELEPORT:
506.  #ifdef DEBUG
507.  		if (can_teleport(ptr)) {
508.  			debugpline("can get teleport");
509.  			return(TRUE);
510.  		} else  return(FALSE);
511.  #else
512.  		return(can_teleport(ptr));
513.  #endif
514.  	    case TELEPORT_CONTROL:
515.  #ifdef DEBUG
516.  		if (control_teleport(ptr)) {
517.  			debugpline("can get teleport control");
518.  			return(TRUE);
519.  		} else  return(FALSE);
520.  #else
521.  		return(control_teleport(ptr));
522.  #endif
523.  	    case TELEPAT:
524.  #ifdef DEBUG
525.  		if (telepathic(ptr)) {
526.  			debugpline("can get telepathy");
527.  			return(TRUE);
528.  		} else  return(FALSE);
529.  #else
530.  		return(telepathic(ptr));
531.  #endif
532.  	    default:
533.  		return(FALSE);
534.  	}
535.  	/*NOTREACHED*/
536.  }
537.  
538.  /* givit() tries to give you an intrinsic based on the monster's level
539.   * and what type of intrinsic it is trying to give you.
540.   */
541.  static void
542.  givit(type, ptr)
543.  int type;
544.  register struct permonst *ptr;
545.  {
546.  	register int chance;
547.  
548.  #ifdef DEBUG
549.  	debugpline("Attempting to give intrinsic %d", type);
550.  #endif
551.  	/* some intrinsics are easier to get than others */
552.  	switch (type) {
553.  		case POISON_RES:
554.  			if ((ptr == &mons[PM_KILLER_BEE] ||
555.  					ptr == &mons[PM_SCORPION]) && !rn2(4))
556.  				chance = 1;
557.  			else
558.  				chance = 15;
559.  			break;
560.  		case TELEPORT:
561.  			chance = 10;
562.  			break;
563.  		case TELEPORT_CONTROL:
564.  			chance = 12;
565.  			break;
566.  		case TELEPAT:
567.  			chance = 1;
568.  			break;
569.  		default:
570.  			chance = 15;
571.  			break;
572.  	}
573.  
574.  	if (ptr->mlevel <= rn2(chance))
575.  		return;		/* failed die roll */
576.  
577.  	switch (type) {
578.  	    case FIRE_RES:
579.  #ifdef DEBUG
580.  		debugpline("Trying to give fire resistance");
581.  #endif
582.  		if(!(HFire_resistance & FROMOUTSIDE)) {
583.  			You(Hallucination ? "be chillin'." :
584.  			    "feel a momentary chill.");
585.  			HFire_resistance |= FROMOUTSIDE;
586.  		}
587.  		break;
588.  	    case SLEEP_RES:
589.  #ifdef DEBUG
590.  		debugpline("Trying to give sleep resistance");
591.  #endif
592.  		if(!(HSleep_resistance & FROMOUTSIDE)) {
593.  			You_feel("wide awake.");
594.  			HSleep_resistance |= FROMOUTSIDE;
595.  		}
596.  		break;
597.  	    case COLD_RES:
598.  #ifdef DEBUG
599.  		debugpline("Trying to give cold resistance");
600.  #endif
601.  		if(!(HCold_resistance & FROMOUTSIDE)) {
602.  			You_feel("full of hot air.");
603.  			HCold_resistance |= FROMOUTSIDE;
604.  		}
605.  		break;
606.  	    case DISINT_RES:
607.  #ifdef DEBUG
608.  		debugpline("Trying to give disintegration resistance");
609.  #endif
610.  		if(!(HDisint_resistance & FROMOUTSIDE)) {
611.  			You_feel(Hallucination ?
612.  			    "totally together, man." :
613.  			    "very firm.");
614.  			HDisint_resistance |= FROMOUTSIDE;
615.  		}
616.  		break;
617.  	    case SHOCK_RES:	/* shock (electricity) resistance */
618.  #ifdef DEBUG
619.  		debugpline("Trying to give shock resistance");
620.  #endif
621.  		if(!(HShock_resistance & FROMOUTSIDE)) {
622.  			if (Hallucination)
623.  				You_feel("grounded in reality.");
624.  			else
625.  				Your("health currently feels amplified!");
626.  			HShock_resistance |= FROMOUTSIDE;
627.  		}
628.  		break;
629.  	    case POISON_RES:
630.  #ifdef DEBUG
631.  		debugpline("Trying to give poison resistance");
632.  #endif
633.  		if(!(HPoison_resistance & FROMOUTSIDE)) {
634.  			You_feel("healthy.");
635.  			HPoison_resistance |= FROMOUTSIDE;
636.  		}
637.  		break;
638.  	    case TELEPORT:
639.  #ifdef DEBUG
640.  		debugpline("Trying to give teleport");
641.  #endif
642.  		if(!(HTeleportation & FROMOUTSIDE)) {
643.  			You_feel(Hallucination ? "diffuse." :
644.  			    "very jumpy.");
645.  			HTeleportation |= FROMOUTSIDE;
646.  		}
647.  		break;
648.  	    case TELEPORT_CONTROL:
649.  #ifdef DEBUG
650.  		debugpline("Trying to give teleport control");
651.  #endif
652.  		if(!(HTeleport_control & FROMOUTSIDE)) {
653.  			You_feel(Hallucination ?
654.  			    "centered in your personal space." :
655.  			    "in control of yourself.");
656.  			HTeleport_control |= FROMOUTSIDE;
657.  		}
658.  		break;
659.  	    case TELEPAT:
660.  #ifdef DEBUG
661.  		debugpline("Trying to give telepathy");
662.  #endif
663.  		if(!(HTelepat & FROMOUTSIDE)) {
664.  			You_feel(Hallucination ?
665.  			    "in touch with the cosmos." :
666.  			    "a strange mental acuity.");
667.  			HTelepat |= FROMOUTSIDE;
668.  			/* If blind, make sure monsters show up. */
669.  			if (Blind) see_monsters();
670.  		}
671.  		break;
672.  	    default:
673.  #ifdef DEBUG
674.  		debugpline("Tried to give an impossible intrinsic");
675.  #endif
676.  		break;
677.  	}
678.  }
679.  
680.  static void
681.  cpostfx(pm)		/* called after completely consuming a corpse */
682.  register int pm;
683.  {
684.  	register int tmp = 0;
685.  
686.  	switch(pm) {
687.  	    case PM_WRAITH:
688.  		pluslvl();
689.  		break;
690.  	    case PM_HUMAN_WERERAT:
691.  		u.ulycn = PM_WERERAT;
692.  		break;
693.  	    case PM_HUMAN_WEREJACKAL:
694.  		u.ulycn = PM_WEREJACKAL;
695.  		break;
696.  	    case PM_HUMAN_WEREWOLF:
697.  		u.ulycn = PM_WEREWOLF;
698.  		break;
699.  	    case PM_NURSE:
700.  		u.uhp = u.uhpmax;
701.  		flags.botl = 1;
702.  		break;
703.  	    case PM_STALKER:
704.  		if(!Invis) {
705.  			set_itimeout(&HInvis, (long)rn1(100, 50));
706.  		} else {
707.  			if (!(HInvis & INTRINSIC)) You_feel("hidden!");
708.  			HInvis |= FROMOUTSIDE;
709.  			HSee_invisible |= FROMOUTSIDE;
710.  		}
711.  		newsym(u.ux, u.uy);
712.  		/* fall into next case */
713.  	    case PM_YELLOW_LIGHT:
714.  		/* fall into next case */
715.  	    case PM_GIANT_BAT:
716.  		make_stunned(HStun + 30,FALSE);
717.  		/* fall into next case */
718.  	    case PM_BAT:
719.  		make_stunned(HStun + 30,FALSE);
720.  		break;
721.  	    case PM_GIANT_MIMIC:
722.  		tmp += 10;
723.  		/* fall into next case */
724.  	    case PM_LARGE_MIMIC:
725.  		tmp += 20;
726.  		/* fall into next case */
727.  	    case PM_SMALL_MIMIC:
728.  		tmp += 20;
729.  		if(u.usym == S_HUMAN) {
730.  		    You_cant("resist the temptation to mimic a pile of gold.");
731.  		    nomul(-tmp);
732.  		    afternmv = eatmdone;
733.  		    if (Role_is('E'))
734.  			nomovemsg = "You now prefer mimicking an elf again.";
735.  		    else
736.  			nomovemsg = "You now prefer mimicking a human again.";
737.  		    u.usym = 0; /* hack! no monster sym 0; use for gold */
738.  		    newsym(u.ux,u.uy);
739.  		    curs_on_u();
740.  		    flush_screen(0);	/* make gold symbol show up now */
741.  		}
742.  		break;
743.  	    case PM_QUANTUM_MECHANIC:
744.  		Your("velocity suddenly seems very uncertain!");
745.  		if (Fast & INTRINSIC) {
746.  			Fast &= ~INTRINSIC;
747.  			You("seem slower.");
748.  		} else {
749.  			Fast |= FROMOUTSIDE;
750.  			You("seem faster.");
751.  		}
752.  		break;
753.  	    case PM_LIZARD:
754.  		if (HStun > 2)  make_stunned(2L,FALSE);
755.  		if (HConfusion > 2)  make_confused(2L,FALSE);
756.  		break;
757.  	    case PM_CHAMELEON:
758.  		You_feel("a change coming over you.");
759.  		polyself();
760.  		break;
761.  	    case PM_MIND_FLAYER:
762.  		if (ABASE(A_INT) < ATTRMAX(A_INT)) {
763.  			if (!rn2(2)) {
764.  				pline("Yum! That was real brain food!");
765.  				(void) adjattrib(A_INT, 1, FALSE);
766.  				break;	/* don't give them telepathy, too */
767.  			}
768.  		}
769.  		else {
770.  			pline("For some reason, that tasted bland.");
771.  		}
772.  		/* fall through to default case */
773.  	    default: {
774.  		register struct permonst *ptr = &mons[pm];
775.  		int i, count;
776.  
777.  		if (dmgtype(ptr, AD_STUN) || dmgtype(ptr, AD_HALU) ||
778.  		    pm == PM_VIOLET_FUNGUS) {
779.  			pline ("Oh wow!  Great stuff!");
780.  			make_hallucinated(HHallucination + 200,FALSE,0L);
781.  		}
782.  		if(is_giant(ptr)) gainstr((struct obj *)0, 0);
783.  
784.  		/* Check the monster for all of the intrinsics.  If this
785.  		 * monster can give more than one, pick one to try to give
786.  		 * from among all it can give.
787.  		 *
788.  		 * If a monster can give 4 intrinsics then you have
789.  		 * a 1/1 * 1/2 * 2/3 * 3/4 = 1/4 chance of getting the first,
790.  		 * a 1/2 * 2/3 * 3/4 = 1/4 chance of getting the second,
791.  		 * a 1/3 * 3/4 = 1/4 chance of getting the third,
792.  		 * and a 1/4 chance of getting the fourth.
793.  		 *
794.  		 * And now a proof by induction:
795.  		 * it works for 1 intrinsic (1 in 1 of getting it)
796.  		 * for 2 you have a 1 in 2 chance of getting the second,
797.  		 *	otherwise you keep the first
798.  		 * for 3 you have a 1 in 3 chance of getting the third,
799.  		 *	otherwise you keep the first or the second
800.  		 * for n+1 you have a 1 in n+1 chance of getting the (n+1)st,
801.  		 *	otherwise you keep the previous one.
802.  		 * Elliott Kleinrock, October 5, 1990
803.  		 */
804.  
805.  		 count = 0;	/* number of possible intrinsics */
806.  		 tmp = 0;	/* which one we will try to give */
807.  		 for (i = 1; i <= LAST_PROP; i++) {
808.  			if (intrinsic_possible(i, ptr)) {
809.  				count++;
810.  				/* a 1 in count chance of replacing the old
811.  				 * one with this one, and a count-1 in count
812.  				 * chance of keeping the old one.  (note
813.  				 * that 1 in 1 and 0 in 1 are what we want
814.  				 * for the first one
815.  				 */
816.  				if (!rn2(count)) {
817.  #ifdef DEBUG
818.  					debugpline("Intrinsic %d replacing %d",
819.  								i, tmp);
820.  #endif
821.  					tmp = i;
822.  				}
823.  			}
824.  		 }
825.  
826.  		 /* if any found try to give them one */
827.  		 if (count) givit(tmp, ptr);
828.  	    }
829.  	    break;
830.  	}
831.  	return;
832.  }
833.  
834.  STATIC_PTR
835.  int
836.  opentin()		/* called during each move whilst opening a tin */
837.  {
838.  	register int r;
839.  	const char *what;
840.  	int which;
841.  
842.  	if(!carried(tin.tin) && !obj_here(tin.tin, u.ux, u.uy))
843.  					/* perhaps it was stolen? */
844.  		return(0);		/* %% probably we should use tinoid */
845.  	if(tin.usedtime++ >= 50) {
846.  		You("give up your attempt to open the tin.");
847.  		return(0);
848.  	}
849.  	if(tin.usedtime < tin.reqtime)
850.  		return(1);		/* still busy */
851.  	if(tin.tin->otrapped ||
852.  	   (tin.tin->cursed && tin.tin->spe != -1 && !rn2(8))) {
853.  		b_trapped("tin", 0);
854.  		goto use_me;
855.  	}
856.  	You("succeed in opening the tin.");
857.  	if(tin.tin->spe != 1) {
858.  	    if (tin.tin->corpsenm == NON_PM) {
859.  		pline("It turns out to be empty.");
860.  		tin.tin->dknown = tin.tin->known = TRUE;
861.  		goto use_me;
862.  	    }
863.  	    r = tin.tin->cursed ? 4 :		/* Always rotten if cursed */
864.  		    (tin.tin->spe == -1) ? 5 :	/* "homemade" if player made */
865.  			rn2(TTSZ-1);		/* else take your pick */
866.  	    if (tin.tin->spe == -1 && !tin.tin->blessed && !rn2(7))
867.  		r = 4;				/* some homemade tins go bad */
868.  	    which = 0;	/* 0=>plural, 1=>as-is, 2=>"the" prefix */
869.  	    if (Hallucination) {
870.  		what = rndmonnam();
871.  	    } else {
872.  		what = mons[tin.tin->corpsenm].mname;
873.  		if (mons[tin.tin->corpsenm].geno & G_UNIQ)
874.  		    which = type_is_pname(&mons[tin.tin->corpsenm]) ? 1 : 2;
875.  	    }
876.  	    if (which == 0) what = makeplural(what);
877.  	    pline("It smells like %s%s.", (which == 2) ? "the " : "", what);
878.  	    if (yn("Eat it?") == 'n') {
879.  		if (!Hallucination) tin.tin->dknown = tin.tin->known = TRUE;
880.  		if (flags.verbose) You("discard the open tin.");
881.  		goto use_me;
882.  	    }
883.  	    /* in case stop_occupation() was called on previous meal */
884.  	    victual.piece = (struct obj *)0;
885.  	    victual.fullwarn = victual.eating = victual.doreset = FALSE;
886.  
887.  	    You("consume %s %s.", tintxts[r].txt,
888.  			mons[tin.tin->corpsenm].mname);
889.  	    tin.tin->dknown = tin.tin->known = TRUE;
890.  	    cprefx(tin.tin->corpsenm); cpostfx(tin.tin->corpsenm);
891.  
892.  	    /* check for vomiting added by GAN 01/16/87 */
893.  	    if(tintxts[r].nut < 0) make_vomiting((long)rn1(15,10), FALSE);
894.  	    else lesshungry(tintxts[r].nut);
895.  
896.  	    if(r == 0) {			/* Deep Fried */
897.  	        /* Assume !Glib, because you can't open tins when Glib. */
898.  		incr_itimeout(&Glib, rnd(15));
899.  		pline("Eating deep fried food made your %s very slippery.",
900.  		      makeplural(body_part(FINGER)));
901.  	    }
902.  	} else {
903.  	    if (tin.tin->cursed)
904.  		pline("It contains some decaying %s substance.",
905.  			hcolor(green));
906.  	    else
907.  		pline("It contains spinach.");
908.  
909.  	    if (yn("Eat it?") == 'n') {
910.  		if (!Hallucination && !tin.tin->cursed)
911.  		    tin.tin->dknown = tin.tin->known = TRUE;
912.  		if (flags.verbose)
913.  		    You("discard the open tin.");
914.  		goto use_me;
915.  	    }
916.  	    if (!tin.tin->cursed)
917.  		pline("This makes you feel like %s!",
918.  		      Hallucination ? "Swee'pea" : "Popeye");
919.  	    lesshungry(600);
920.  	    gainstr(tin.tin, 0);
921.  	}
922.  	tin.tin->dknown = tin.tin->known = TRUE;
923.  use_me:
924.  	if (carried(tin.tin)) useup(tin.tin);
925.  	else useupf(tin.tin);
926.  	tin.tin = (struct obj *) 0;
927.  	return(0);
928.  }
929.  
930.  static void
931.  start_tin(otmp)		/* called when starting to open a tin */
932.  	register struct obj *otmp;
933.  {
934.  	register int tmp;
935.  
936.  	if (metallivorous(uasmon)) {
937.  		You("bite right into the metal tin...");
938.  		tmp = 1;
939.  	} else if (nolimbs(uasmon)) {
940.  		You("cannot handle the tin properly to open it.");
941.  		return;
942.  	} else if (otmp->blessed) {
943.  		pline_The("tin opens like magic!");
944.  		tmp = 1;
945.  	} else if(uwep) {
946.  		switch(uwep->otyp) {
947.  		case TIN_OPENER:
948.  			tmp = 1;
949.  			break;
950.  		case DAGGER:
951.  		case ELVEN_DAGGER:
952.  		case ORCISH_DAGGER:
953.  		case ATHAME:
954.  		case CRYSKNIFE:
955.  			tmp = 3;
956.  			break;
957.  		case PICK_AXE:
958.  		case AXE:
959.  			tmp = 6;
960.  			break;
961.  		default:
962.  			goto no_opener;
963.  		}
964.  		pline("Using your %s you try to open the tin.",
965.  			aobjnam(uwep, (char *)0));
966.  	} else {
967.  no_opener:
968.  		pline("It is not so easy to open this tin.");
969.  		if(Glib) {
970.  			pline_The("tin slips from your %s.",
971.  			      makeplural(body_part(FINGER)));
972.  			if(otmp->quan > 1L) {
973.  				register struct obj *obj;
974.  				obj = splitobj(otmp, 1L);
975.  				if(otmp == uwep) setuwep(obj);
976.  			}
977.  			if (carried(otmp)) dropx(otmp);
978.  			else stackobj(otmp);
979.  			return;
980.  		}
981.  		tmp = rn1(1 + 500/((int)(ACURR(A_DEX) + ACURRSTR)), 10);
982.  	}
983.  	tin.reqtime = tmp;
984.  	tin.usedtime = 0;
985.  	tin.tin = otmp;
986.  	set_occupation(opentin, "opening the tin", 0);
987.  	return;
988.  }
989.  
990.  int
991.  Hear_again()		/* called when waking up after fainting */
992.  {
993.  	flags.soundok = 1;
994.  	return 0;
995.  }
996.  
997.  /* called on the "first bite" of rotten food */
998.  static int
999.  rottenfood(obj)
1000. struct obj *obj;
1001. {
1002. 	pline("Blecch!  Rotten %s!", foodword(obj));
1003. 	if(!rn2(4)) {
1004. 		if (Hallucination) You_feel("rather trippy.");
1005. 		else You_feel("rather %s.", body_part(LIGHT_HEADED));
1006. 		make_confused(HConfusion + d(2,4),FALSE);
1007. 	} else if(!rn2(4) && !Blind) {
1008. 		pline("Everything suddenly goes dark.");
1009. 		make_blinded((long)d(2,10),FALSE);
1010. 	} else if(!rn2(3)) {
1011. 		const char *what, *where;
1012. 		if (!Blind)
1013. 		    what = "goes",  where = "dark";
1014. 		else if (Levitation || Is_airlevel(&u.uz) ||
1015. 			 Is_waterlevel(&u.uz))
1016. 		    what = "you lose control of",  where = "yourself";
1017. 		else
1018. 		    what = "you slap against the",  where = surface(u.ux,u.uy);
1019. 		pline_The("world spins and %s %s.", what, where);
1020. 		flags.soundok = 0;
1021. 		nomul(-rnd(10));
1022. 		nomovemsg = "You are conscious again.";
1023. 		afternmv = Hear_again;
1024. 		return(1);
1025. 	}
1026. 	return(0);
1027. }
1028. 
1029. static int
1030. eatcorpse(otmp)		/* called when a corpse is selected as food */
1031. 	register struct obj *otmp;
1032. {
1033. 	register const char *cname = corpse_xname(otmp, TRUE);
1034. 	register int tp;
1035. 	long sick_time, rotted = 0L;
1036. 
1037. 	tp = 0;
1038. 
1039. 	if(otmp->corpsenm != PM_LIZARD) {
1040. 		long age = peek_at_iced_corpse_age(otmp);
1041. 
1042. 		rotted = (monstermoves - age)/(10L + rn2(20));
1043. 		if(otmp->cursed) rotted += 2L;
1044. 		else if (otmp->blessed) rotted -= 2L;
1045. 	}
1046. 
1047. 	if(otmp->corpsenm != PM_ACID_BLOB && (rotted > 5L)) {
1048. 		char buf[BUFSZ];
1049. 		pline("Ulch - that %s was tainted!",
1050. 		      mons[otmp->corpsenm].mlet == S_FUNGUS ? "fungoid vegetation" :
1051. 		      is_meaty(&mons[otmp->corpsenm]) ? "meat" : "protoplasm");
1052. 		if (u.usym == S_FUNGUS)
1053. 			pline("It doesn't seem at all sickening, though...");
1054. 		else {
1055. 			sick_time = (long) rn1(10, 10);
1056. 			/* make sure new ill doesn't result in improvement */
1057. 			if (Sick && (sick_time > Sick))
1058. 			    sick_time = (Sick > 1L) ? Sick - 1L : 1L;
1059. 			Sprintf(buf, "rotted %s", cname);
1060. 			make_sick(sick_time, buf, TRUE, SICK_VOMITABLE);
1061. 		}
1062. 		if (carried(otmp)) useup(otmp);
1063. 		else useupf(otmp);
1064. 		return(1);
1065. 	} else if (acidic(&mons[otmp->corpsenm]) && !resists_acid(&youmonst)) {
1066. 		tp++;
1067. 		You("have a very bad case of stomach acid.");
1068. 		losehp(rnd(15), "acidic corpse", KILLED_BY_AN);
1069. 	} else if(poisonous(&mons[otmp->corpsenm]) && rn2(5)) {
1070. 		tp++;
1071. 		pline("Ecch - that must have been poisonous!");
1072. 		if(!Poison_resistance) {
1073. 			losestr(rnd(4));
1074. 			losehp(rnd(15), "poisonous corpse", KILLED_BY_AN);
1075. 		} else	You("seem unaffected by the poison.");
1076. 	/* now any corpse left too long will make you mildly ill */
1077. 	} else if ((rotted > 5L || (rotted > 3L && rn2(5)))
1078. 					&& u.usym != S_FUNGUS) {
1079. 		tp++;
1080. 		You("feel%s sick.", (Sick) ? " very" : "");
1081. 		losehp(rnd(8), "cadaver", KILLED_BY_AN);
1082. 	}
1083. 	if(!tp && otmp->corpsenm != PM_LIZARD && (otmp->orotten || !rn2(7))) {
1084. 	    if (rottenfood(otmp)) {
1085. 		otmp->orotten = TRUE;
1086. 		(void)touchfood(otmp);
1087. 		return(1);
1088. 	    }
1089. 	    otmp->oeaten >>= 2;
1090. 	} else {
1091. 	    pline("This %s %s!", cname,
1092. 		(carnivorous(uasmon) && !herbivorous(uasmon))
1093. 		? "is delicious" : "tastes terrible");
1094. 	}
1095. 
1096. 	/* delay is weight dependent */
1097. 	victual.reqtime = 3 + (mons[otmp->corpsenm].cwt >> 6);
1098. 	return(0);
1099. }
1100. 
1101. static void
1102. start_eating(otmp)		/* called as you start to eat */
1103. 	register struct obj *otmp;
1104. {
1105. #ifdef DEBUG
1106. 	debugpline("start_eating: %lx (victual = %lx)", otmp, victual.piece);
1107. 	debugpline("reqtime = %d", victual.reqtime);
1108. 	debugpline("(original reqtime = %d)", objects[otmp->otyp].oc_delay);
1109. 	debugpline("nmod = %d", victual.nmod);
1110. 	debugpline("oeaten = %d", otmp->oeaten);
1111. #endif
1112. 	victual.fullwarn = victual.doreset = FALSE;
1113. 	victual.eating = TRUE;
1114. 
1115. 	if (otmp->otyp == CORPSE) {
1116. 	    cprefx(victual.piece->corpsenm);
1117. 	    if (!victual.piece && victual.eating) do_reset_eat();
1118. 	    if (victual.eating == FALSE) return; /* died and lifesaved */
1119. 	}
1120. 
1121. 	if (bite()) return;
1122. 
1123. 	if(++victual.usedtime >= victual.reqtime) {
1124. 	    /* print "finish eating" message if they just resumed -dlc */
1125. 	    done_eating(victual.reqtime > 1 ? TRUE : FALSE);
1126. 	    return;
1127. 	}
1128. 
1129. 	Sprintf(msgbuf, "eating %s", the(singular(otmp, xname)));
1130. 	set_occupation(eatfood, msgbuf, 0);
1131. }
1132. 
1133. 
1134. static void
1135. fprefx(otmp)		/* called on "first bite" of (non-corpse) food */
1136. struct obj *otmp;
1137. {
1138. 	switch(otmp->otyp) {
1139. 
1140. 	    case FOOD_RATION:
1141. 		if(u.uhunger <= 200)
1142. 		    if (Hallucination) pline("Oh wow, like, superior, man!");
1143. 		    else	       pline("That food really hit the spot!");
1144. 		else if(u.uhunger <= 700) pline("That satiated your stomach!");
1145. 		break;
1146. 	    case TRIPE_RATION:
1147. 		if (carnivorous(uasmon) && !humanoid(uasmon))
1148. 		    pline("That tripe ration was surprisingly good!");
1149. 		else {
1150. 		    pline("Yak - dog food!");
1151. 		    more_experienced(1,0);
1152. 		    flags.botl = 1;
1153. 		}
1154. 		if (rn2(2) && (!carnivorous(uasmon) || humanoid(uasmon))) {
1155. 			make_vomiting((long)rn1(victual.reqtime, 14), FALSE);
1156. 		}
1157. 		break;
1158. 	    case CLOVE_OF_GARLIC:
1159. 		if (is_undead(uasmon)) {
1160. 			make_vomiting((long)rn1(victual.reqtime, 5), FALSE);
1161. 			break;
1162. 		}
1163. 		/* Fall through otherwise */
1164. 	    default:
1165. 		if (otmp->otyp==SLIME_MOLD && !otmp->cursed
1166. 			&& otmp->spe == current_fruit)
1167. 		    pline("My, that was a %s %s!",
1168. 			  Hallucination ? "primo" : "yummy",
1169. 			  singular(otmp, xname));
1170. 		else
1171. #ifdef UNIX
1172. 		if (otmp->otyp == APPLE || otmp->otyp == PEAR) {
1173. 		    if (!Hallucination) pline("Core dumped.");
1174. 		    else {
1175. /* This is based on an old Usenet joke, a fake a.out manual page */
1176. 			int x = rnd(100);
1177. 			if (x <= 75)
1178. 			    pline("Segmentation fault -- core dumped.");
1179. 			else if (x <= 99)
1180. 			    pline("Bus error -- core dumped.");
1181. 			else pline("Yo' mama -- core dumped.");
1182. 		    }
1183. 		} else
1184. #endif
1185. 		if (otmp->otyp == EGG && stale_egg(otmp)) {
1186. 		    pline("Ugh.  Rotten egg.");	/* perhaps others like it */
1187. 		    make_vomiting(Vomiting+d(10,4), TRUE);
1188. 		} else
1189. 		    pline("This %s is %s", singular(otmp, xname),
1190. 		      otmp->cursed ? (Hallucination ? "grody!" : "terrible!") :
1191. 		      (otmp->otyp == CRAM_RATION
1192. 		      || otmp->otyp == K_RATION
1193. 		      || otmp->otyp == C_RATION)
1194. 		      ? "bland." :
1195. 		      Hallucination ? "gnarly!" : "delicious!");
1196. 		break;
1197. 	}
1198. }
1199. 
1200. static void
1201. eataccessory(otmp)
1202. struct obj *otmp;
1203. {
1204. 	int typ = otmp->otyp;
1205. 	int oldprop;
1206. 
1207. 	/* Note: rings are not so common that this is unbalancing. */
1208. 	/* (How often do you even _find_ 3 rings of polymorph in a game?) */
1209. 	oldprop = !!(u.uprops[objects[typ].oc_oprop].p_flgs);
1210. 	otmp->known = otmp->dknown = 1; /* by taste */
1211. 	if (!rn2(otmp->oclass == RING_CLASS ? 3 : 5))
1212. 	  switch (otmp->otyp) {
1213. 	    default:
1214. 	        if (!objects[typ].oc_oprop) break; /* should never happen */
1215. 
1216. 		if (!(u.uprops[objects[typ].oc_oprop].p_flgs & FROMOUTSIDE))
1217. 		    pline("Magic spreads through your body as you digest the %s.",
1218. 			  otmp->oclass == RING_CLASS ? "ring" : "amulet");
1219. 
1220. 		u.uprops[objects[typ].oc_oprop].p_flgs |= FROMOUTSIDE;
1221. 
1222. 		switch (typ) {
1223. 		  case RIN_SEE_INVISIBLE:
1224. 		    set_mimic_blocking();
1225. 		    see_monsters();
1226. 		    if (Invis && !oldprop && !perceives(uasmon) && !Blind) {
1227. 			newsym(u.ux,u.uy);
1228. 			pline("Suddenly you can see yourself.");
1229. 			makeknown(typ);
1230. 		    }
1231. 		    break;
1232. 		  case RIN_INVISIBILITY:
1233. 		    if (!oldprop && !See_invisible && !Blind) {
1234. 			newsym(u.ux,u.uy);
1235. 			Your("body takes on a %s transparency...",
1236. 				Hallucination ? "normal" : "strange");
1237. 			makeknown(typ);
1238. 		    }
1239. 		    break;
1240. 		  case RIN_PROTECTION_FROM_SHAPE_CHAN:
1241. 		    rescham();
1242. 		    break;
1243. 		  case RIN_LEVITATION:
1244. 		    if (!Levitation) {
1245. 			float_up();
1246. 			HLevitation += d(10,20);
1247. 			makeknown(typ);
1248. 		    }
1249. 		    break;
1250. 		}
1251. 		break;
1252. 	    case RIN_ADORNMENT:
1253. 		if (adjattrib(A_CHA, otmp->spe, -1))
1254. 		    makeknown(typ);
1255. 		break;
1256. 	    case RIN_GAIN_STRENGTH:
1257. 		if (adjattrib(A_STR, otmp->spe, -1))
1258. 		    makeknown(typ);
1259. 		break;
1260. 	    case RIN_INCREASE_DAMAGE:
1261. 		u.udaminc += otmp->spe;
1262. 		break;
1263. 	    case RIN_PROTECTION:
1264. 		Protection |= FROMOUTSIDE;
1265. 		u.ublessed += otmp->spe;
1266. 		flags.botl = 1;
1267. 		break;
1268. 	    case AMULET_OF_CHANGE:
1269. 		makeknown(typ);
1270. 		change_sex();
1271. 		You("are suddenly very %s!",
1272. 		    flags.female ? "feminine" : "masculine");
1273. 		flags.botl = 1;
1274. 		break;
1275. 	    case AMULET_OF_STRANGULATION: /* bad idea! */
1276. 		choke(otmp);
1277. 		break;
1278. 	    case AMULET_OF_RESTFUL_SLEEP: /* another bad idea! */
1279. 		Sleeping = rnd(100);
1280. 		break;
1281. 	    case AMULET_OF_LIFE_SAVING:
1282. 	    case AMULET_OF_REFLECTION: /* nice try */
1283. 	    /* can't eat Amulet of Yendor or fakes,
1284. 	     * and no oc_prop even if you could -3.
1285. 	     */
1286. 		break;
1287. 	  }
1288. }
1289. 
1290. static void
1291. eatspecial() /* called after eating non-food */
1292. {
1293. 	register struct obj *otmp = victual.piece;
1294. 
1295. 	lesshungry(victual.nmod);
1296. 	victual.piece = (struct obj *)0;
1297. 	victual.eating = 0;
1298. 	if (otmp->oclass == GOLD_CLASS) {
1299. 		dealloc_obj(otmp);
1300. 		return;
1301. 	}
1302. 	if (otmp->oclass == POTION_CLASS) {
1303. 		otmp->quan++; /* dopotion() does a useup() */
1304. 		(void)dopotion(otmp);
1305. 	}
1306. 	if (otmp->oclass == RING_CLASS || otmp->oclass == AMULET_CLASS)
1307. 		eataccessory(otmp);
1308. 	else if (otmp->otyp == LEASH && otmp->leashmon)
1309. 		o_unleash(otmp);
1310. 
1311. 	if (otmp == uwep && otmp->quan == 1L) uwepgone();
1312. 	if (otmp == uball) unpunish();
1313. 	if (otmp == uchain) unpunish(); /* but no useup() */
1314. 	else if (carried(otmp)) useup(otmp);
1315. 	else useupf(otmp);
1316. }
1317. 
1318. /* NOTE: the order of these words exactly corresponds to the
1319.    order of oc_material values #define'd in objclass.h. */
1320. static const char *foodwords[] = {
1321. 	"meal", "liquid", "wax", "food", "meat",
1322. 	"paper", "cloth", "leather", "wood", "bone", "scale",
1323. 	"metal", "metal", "metal", "silver", "gold", "platinum", "mithril",
1324. 	"plastic", "glass", "rich food", "stone"
1325. };
1326. 
1327. static const char *
1328. foodword(otmp)
1329. register struct obj *otmp;
1330. {
1331. 	if (otmp->oclass == FOOD_CLASS) return "food";
1332. 	if (otmp->oclass == GEM_CLASS &&
1333. 	    objects[otmp->otyp].oc_material == GLASS &&
1334. 	    otmp->dknown)
1335. 		makeknown(otmp->otyp);
1336. 	return foodwords[objects[otmp->otyp].oc_material];
1337. }
1338. 
1339. static void
1340. fpostfx(otmp)		/* called after consuming (non-corpse) food */
1341. register struct obj *otmp;
1342. {
1343. 	switch(otmp->otyp) {
1344. 	    case SPRIG_OF_WOLFSBANE:
1345. 		if (u.ulycn >= LOW_PM) {
1346. 		    You_feel("purified.");
1347. 		    if (uasmon == &mons[u.ulycn] && !Polymorph_control)
1348. 			rehumanize();
1349. 		    u.ulycn = NON_PM;
1350. 		}
1351. 		break;
1352. 	    case CARROT:
1353. 		make_blinded(0L,TRUE);
1354. 		break;
1355. 	    case FORTUNE_COOKIE:
1356. 		outrumor(bcsign(otmp), TRUE);
1357. 		break;
1358. 	    case LUMP_OF_ROYAL_JELLY:
1359. 		/* This stuff seems to be VERY healthy! */
1360. 		gainstr(otmp, 1);
1361. 		u.uhp += (otmp->cursed) ? -rnd(20) : rnd(20);
1362. 		if(u.uhp > u.uhpmax) {
1363. 			if(!rn2(17)) u.uhpmax++;
1364. 			u.uhp = u.uhpmax;
1365. 		} else if(u.uhp <= 0) {
1366. 			killer_format = KILLED_BY_AN;
1367. 			killer = "rotten lump of royal jelly";
1368. 			done(POISONING);
1369. 		}
1370. 		if(!otmp->cursed) heal_legs();
1371. 		break;
1372. 	    case EGG:
1373. 		if(otmp->corpsenm == PM_COCKATRICE) {
1374. 		    if (!resists_ston(&youmonst) &&
1375. 			!(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))) {
1376. 			if (!Stoned) Stoned = 5;
1377. 			killer_format = KILLED_BY_AN;
1378. 			killer = "cockatrice egg";
1379. 		    }
1380. 		}
1381. 		break;
1382. 	}
1383. 	return;
1384. }
1385. 
1386. int
1387. doeat()		/* generic "eat" command funtion (see cmd.c) */
1388. {
1389. 	register struct obj *otmp;
1390. 	int basenutrit;			/* nutrition of full item */
1391. 
1392. 	if (Strangled) {
1393. 		pline("If you can't breathe air, how can you consume solids?");
1394. 		return 0;
1395. 	}
1396. 	if (!(otmp = floorfood("eat", 0))) return 0;
1397. 	if (check_capacity((char *)0)) return 0;
1398. 
1399. 	/* We have to make non-foods take 1 move to eat, unless we want to
1400. 	 * do ridiculous amounts of coding to deal with partly eaten plate
1401. 	 * mails, players who polymorph back to human in the middle of their
1402. 	 * metallic meal, etc....
1403. 	 */
1404. 	if (!is_edible(otmp)) {
1405. 	    You("cannot eat that!");
1406. 	    return 0;
1407. 	} else if ((otmp->owornmask & (W_ARMOR|W_TOOL|W_RING|W_AMUL)) != 0) {
1408. 	    You_cant("eat %s you're wearing.", something);
1409. 	    return 0;
1410. 	}
1411. 	if (is_metallic(otmp) &&
1412. 	    u.umonnum == PM_RUST_MONSTER && otmp->oerodeproof) {
1413. 	    	otmp->rknown = TRUE;
1414. 		if (otmp->quan > 1L) {
1415. 			if(!carried(otmp))
1416. 				(void) splitobj(otmp, 1L);
1417. 			else 
1418. 				otmp = splitobj(otmp, otmp->quan - 1L);
1419. 		}
1420. 		pline("Ulch - That %s was rustproofed!", xname(otmp));
1421. 		/* The regurgitated object's rustproofing is gone now */
1422. 		otmp->oerodeproof = 0;
1423. 		make_stunned(HStun + rn2(10), TRUE); 
1424. 		pline("You spit %s out onto the %s.", the(xname(otmp)),
1425. 			surface(u.ux, u.uy));
1426. 		if (carried(otmp)) {
1427. 			freeinv(otmp);
1428. 			dropy(otmp);
1429. 		}
1430. 		stackobj(otmp);
1431. 		return 1;
1432. 	}
1433. 	if (otmp->oclass != FOOD_CLASS) {
1434. 	    victual.reqtime = 1;
1435. 	    victual.piece = otmp;
1436. 		/* Don't split it, we don't need to if it's 1 move */
1437. 	    victual.usedtime = 0;
1438. 	    victual.canchoke = (u.uhs == SATIATED);
1439. 		/* Note: gold weighs 1 pt. for each 1000 pieces (see */
1440. 		/* pickup.c) so gold and non-gold is consistent. */
1441. 	    if (otmp->oclass == GOLD_CLASS)
1442. 		basenutrit = ((otmp->quan > 200000L) ? 2000
1443. 			: (int)(otmp->quan/100L));
1444. 	    else if(otmp->oclass == BALL_CLASS || otmp->oclass == CHAIN_CLASS)
1445. 		basenutrit = weight(otmp);
1446. 	    /* oc_nutrition is usually weight anyway */
1447. 	    else basenutrit = objects[otmp->otyp].oc_nutrition;
1448. 	    victual.nmod = basenutrit;
1449. 	    victual.eating = TRUE; /* needed for lesshungry() */
1450. 
1451. 	    if (otmp->cursed)
1452. 		(void) rottenfood(otmp);
1453. 
1454. 	    if (otmp->oclass == WEAPON_CLASS && otmp->opoisoned) {
1455. 		pline("Ecch - that must have been poisonous!");
1456. 		if(!Poison_resistance) {
1457. 		    losestr(rnd(4));
1458. 		    losehp(rnd(15), xname(otmp), KILLED_BY_AN);
1459. 		} else
1460. 		    You("seem unaffected by the poison.");
1461. 	    } else if (!otmp->cursed)
1462. 		pline("This %s is delicious!",
1463. 		      otmp->oclass == GOLD_CLASS ? foodword(otmp) :
1464. 		      singular(otmp, xname));
1465. 	    eatspecial();
1466. 	    return 1;
1467. 	}
1468. 
1469. 	if(otmp == victual.piece) {
1470. 	/* If they weren't able to choke, they don't suddenly become able to
1471. 	 * choke just because they were interrupted.  On the other hand, if
1472. 	 * they were able to choke before, if they lost food it's possible
1473. 	 * they shouldn't be able to choke now.
1474. 	 */
1475. 	    if (u.uhs != SATIATED) victual.canchoke = FALSE;
1476. 	    if(!carried(victual.piece)) {
1477. 		if(victual.piece->quan > 1L)
1478. 			(void) splitobj(victual.piece, 1L);
1479. 	    }
1480. 	    You("resume your meal.");
1481. 	    start_eating(victual.piece);
1482. 	    return(1);
1483. 	}
1484. 
1485. 	/* nothing in progress - so try to find something. */
1486. 	/* tins are a special case */
1487. 	if(otmp->otyp == TIN) {
1488. 	    start_tin(otmp);
1489. 	    return(1);
1490. 	}
1491. 
1492. 	victual.piece = otmp = touchfood(otmp);
1493. 	victual.usedtime = 0;
1494. 
1495. 	/* Now we need to calculate delay and nutritional info.
1496. 	 * The base nutrition calculated here and in eatcorpse() accounts
1497. 	 * for normal vs. rotten food.  The reqtime and nutrit values are
1498. 	 * then adjusted in accordance with the amount of food left.
1499. 	 */
1500. 	if(otmp->otyp == CORPSE) {
1501. 	    if(eatcorpse(otmp)) return(1);
1502. 	    /* else eatcorpse sets up reqtime and oeaten */
1503. 	} else {
1504. 	    victual.reqtime = objects[otmp->otyp].oc_delay;
1505. 	    if (otmp->otyp != FORTUNE_COOKIE &&
1506. 		(otmp->cursed ||
1507. 		 (((monstermoves - otmp->age) > (int) otmp->blessed ? 50:30) &&
1508. 		(otmp->orotten || !rn2(7))))) {
1509. 
1510. 		if (rottenfood(otmp)) {
1511. 		    otmp->orotten = TRUE;
1512. 		    return(1);
1513. 		}
1514. 		otmp->oeaten >>= 1;
1515. 	    } else fprefx(otmp);
1516. 	}
1517. 
1518. 	/* re-calc the nutrition */
1519. 	if (otmp->otyp == CORPSE) basenutrit = mons[otmp->corpsenm].cnutrit;
1520. 	else basenutrit = objects[otmp->otyp].oc_nutrition;
1521. 
1522. #ifdef DEBUG
1523. 	debugpline("before rounddiv: victual.reqtime == %d", victual.reqtime);
1524. 	debugpline("oeaten == %d, basenutrit == %d", otmp->oeaten, basenutrit);
1525. #endif
1526. 	victual.reqtime = (basenutrit == 0 ? 0 :
1527. 		rounddiv(victual.reqtime * (long)otmp->oeaten, basenutrit));
1528. #ifdef DEBUG
1529. 	debugpline("after rounddiv: victual.reqtime == %d", victual.reqtime);
1530. #endif
1531. 	/* calculate the modulo value (nutrit. units per round eating)
1532. 	 * note: this isn't exact - you actually lose a little nutrition
1533. 	 *	 due to this method.
1534. 	 * TODO: add in a "remainder" value to be given at the end of the
1535. 	 *	 meal.
1536. 	 */
1537. 	if(victual.reqtime == 0)
1538. 	    /* possible if most has been eaten before */
1539. 	    victual.nmod = 0;
1540. 	else if ((int)otmp->oeaten > victual.reqtime)
1541. 	    victual.nmod = -((int)otmp->oeaten / victual.reqtime);
1542. 	else
1543. 	    victual.nmod = victual.reqtime % otmp->oeaten;
1544. 	victual.canchoke = (u.uhs == SATIATED);
1545. 
1546. 	start_eating(otmp);
1547. 	return(1);
1548. }
1549. 
1550. /* Take a single bite from a piece of food, checking for choking and
1551.  * modifying usedtime.  Returns 1 if they choked and survived, 0 otherwise.
1552.  */
1553. static int
1554. bite()
1555. {
1556. 	if(victual.canchoke && u.uhunger >= 2000) {
1557. 		choke(victual.piece);
1558. 		return 1;
1559. 	}
1560. 	if (victual.doreset) {
1561. 		do_reset_eat();
1562. 		return 0;
1563. 	}
1564. 	force_save_hs = TRUE;
1565. 	if(victual.nmod < 0) {
1566. 		lesshungry(-victual.nmod);
1567. 		victual.piece->oeaten -= -victual.nmod;
1568. 	} else if(victual.nmod > 0 && (victual.usedtime % victual.nmod)) {
1569. 		lesshungry(1);
1570. 		victual.piece->oeaten--;
1571. 	}
1572. 	force_save_hs = FALSE;
1573. 	recalc_wt();
1574. 	return 0;
1575. }
1576. 
1577. #endif /* OVLB */
1578. #ifdef OVL0
1579. 
1580. void
1581. gethungry()	/* as time goes by - called by moveloop() and domove() */
1582. {
1583. 	if (u.uinvulnerable) return;	/* you don't feel hungrier */
1584. 
1585. 	if ((!u.usleep || !rn2(10))	/* slow metabolic rate while asleep */
1586. 		&& (carnivorous(uasmon) || herbivorous(uasmon)))
1587. 	    u.uhunger--;		/* ordinary food consumption */
1588. 
1589. 	if (moves % 2) {	/* odd turns */
1590. 	    /* Regeneration uses up food, unless due to an artifact */
1591. 	    if ((HRegeneration & (~W_ART)) &&
1592. 		(HRegeneration != W_WEP || !uwep->oartifact)) u.uhunger--;
1593. 	    if (near_capacity() > SLT_ENCUMBER) u.uhunger--;
1594. 	} else {		/* even turns */
1595. 	    if (Hunger) u.uhunger--;
1596. 	    /* Conflict uses up food too */
1597. 	    if ((Conflict & (~W_ARTI))) u.uhunger--;
1598. 	    /* +0 charged rings don't do anything, so don't affect hunger */
1599. 	    switch ((int)(moves % 20)) {	/* note: use even cases only */
1600. 	     case  4: if (uleft &&
1601. 			  (uleft->spe || !objects[uleft->otyp].oc_charged))
1602. 			    u.uhunger--;
1603. 		    break;
1604. 	     case  8: if (uamul) u.uhunger--;
1605. 		    break;
1606. 	     case 12: if (uright &&
1607. 			  (uright->spe || !objects[uright->otyp].oc_charged))
1608. 			    u.uhunger--;
1609. 		    break;
1610. 	     case 16: if (u.uhave.amulet) u.uhunger--;
1611. 		    break;
1612. 	     default: break;
1613. 	    }
1614. 	}
1615. 	newuhs(TRUE);
1616. }
1617. 
1618. #endif /* OVL0 */
1619. #ifdef OVLB
1620. 
1621. void
1622. morehungry(num)	/* called after vomiting and after performing feats of magic */
1623. register int num;
1624. {
1625. 	u.uhunger -= num;
1626. 	newuhs(TRUE);
1627. }
1628. 
1629. 
1630. void
1631. lesshungry(num)	/* called after eating (and after drinking fruit juice) */
1632. register int num;
1633. {
1634. #ifdef DEBUG
1635. 	debugpline("lesshungry(%d)", num);
1636. #endif
1637. 	u.uhunger += num;
1638. 	if(u.uhunger >= 2000) {
1639. 	    if (!victual.eating || victual.canchoke)
1640. 		if (victual.eating) {
1641. 			choke(victual.piece);
1642. 			reset_eat();
1643. 		} else
1644. 		if (tin.tin)
1645. 			choke(tin.tin);
1646. 		else
1647. 			choke((struct obj *) 0);
1648. 		/* no reset_eat() */
1649. 	} else {
1650. 	    /* Have lesshungry() report when you're nearly full so all eating
1651. 	     * warns when you're about to choke.
1652. 	     */
1653. 	    if (u.uhunger >= 1500) {
1654. 		if (!victual.eating || (victual.eating && !victual.fullwarn)) {
1655. 		    pline("You're having a hard time getting all of it down.");
1656. 		    nomovemsg = "You're finally finished.";
1657. 		    if (!victual.eating)
1658. 			multi = -2;
1659. 		    else {
1660. 			victual.fullwarn = TRUE;
1661. 			if (victual.canchoke && victual.reqtime > 1) {
1662. 			    /* a one-gulp food will not survive a stop */
1663. 			    if (yn_function("Stop eating?",ynchars,'y')=='y') {
1664. 				reset_eat();
1665. 				nomovemsg = (char *)0;
1666. 			    }
1667. 			}
1668. 		    }
1669. 		}
1670. 	    }
1671. 	}
1672. 	newuhs(FALSE);
1673. }
1674. 
1675. STATIC_PTR
1676. int
1677. unfaint()
1678. {
1679. 	(void) Hear_again();
1680. 	if(u.uhs > FAINTING)
1681. 		u.uhs = FAINTING;
1682. 	stop_occupation();
1683. 	flags.botl = 1;
1684. 	return 0;
1685. }
1686. 
1687. #endif /* OVLB */
1688. #ifdef OVL0
1689. 
1690. boolean
1691. is_fainted()
1692. {
1693. 	return((boolean)(u.uhs == FAINTED));
1694. }
1695. 
1696. void
1697. reset_faint()	/* call when a faint must be prematurely terminated */
1698. {
1699. 	if(is_fainted()) nomul(0);
1700. }
1701. 
1702. #if 0
1703. void
1704. sync_hunger()
1705. {
1706. 
1707. 	if(is_fainted()) {
1708. 
1709. 		flags.soundok = 0;
1710. 		nomul(-10+(u.uhunger/10));
1711. 		nomovemsg = "You regain consciousness.";
1712. 		afternmv = unfaint;
1713. 	}
1714. }
1715. #endif
1716. 
1717. void
1718. newuhs(incr)		/* compute and comment on your (new?) hunger status */
1719. boolean incr;
1720. {
1721. 	unsigned newhs;
1722. 	static unsigned save_hs;
1723. 	static boolean saved_hs = FALSE;
1724. 	int h = u.uhunger;
1725. 
1726. 	newhs = (h > 1000) ? SATIATED :
1727. 		(h > 150) ? NOT_HUNGRY :
1728. 		(h > 50) ? HUNGRY :
1729. 		(h > 0) ? WEAK : FAINTING;
1730. 
1731. 	/* While you're eating, you may pass from WEAK to HUNGRY to NOT_HUNGRY.
1732. 	 * This should not produce the message "you only feel hungry now";
1733. 	 * that message should only appear if HUNGRY is an endpoint.  Therefore
1734. 	 * we check to see if we're in the middle of eating.  If so, we save
1735. 	 * the first hunger status, and at the end of eating we decide what
1736. 	 * message to print based on the _entire_ meal, not on each little bit.
1737. 	 */
1738. 	/* It is normally possible to check if you are in the middle of a meal
1739. 	 * by checking occupation == eatfood, but there is one special case:
1740. 	 * start_eating() can call bite() for your first bite before it
1741. 	 * sets the occupation.
1742. 	 * Anyone who wants to get that case to work _without_ an ugly static
1743. 	 * force_save_hs variable, feel free.
1744. 	 */
1745. 	/* Note: If you become a certain hunger status in the middle of the
1746. 	 * meal, and still have that same status at the end of the meal,
1747. 	 * this will incorrectly print the associated message at the end of
1748. 	 * the meal instead of the middle.  Such a case is currently
1749. 	 * impossible, but could become possible if a message for SATIATED
1750. 	 * were added or if HUNGRY and WEAK were separated by a big enough
1751. 	 * gap to fit two bites.
1752. 	 */
1753. 	if (occupation == eatfood || force_save_hs) {
1754. 		if (!saved_hs) {
1755. 			save_hs = u.uhs;
1756. 			saved_hs = TRUE;
1757. 		}
1758. 		u.uhs = newhs;
1759. 		return;
1760. 	} else {
1761. 		if (saved_hs) {
1762. 			u.uhs = save_hs;
1763. 			saved_hs = FALSE;
1764. 		}
1765. 	}
1766. 
1767. 	if(newhs == FAINTING) {
1768. 		if(is_fainted()) newhs = FAINTED;
1769. 		if(u.uhs <= WEAK || rn2(20-u.uhunger/10) >= 19) {
1770. 			if(!is_fainted() && multi >= 0 /* %% */) {
1771. 				/* stop what you're doing, then faint */
1772. 				stop_occupation();
1773. 				You("faint from lack of food.");
1774. 				flags.soundok = 0;
1775. 				nomul(-10+(u.uhunger/10));
1776. 				nomovemsg = "You regain consciousness.";
1777. 				afternmv = unfaint;
1778. 				newhs = FAINTED;
1779. 			}
1780. 		} else
1781. 		if(u.uhunger < -(int)(200 + 20*ACURR(A_CON))) {
1782. 			u.uhs = STARVED;
1783. 			flags.botl = 1;
1784. 			bot();
1785. 			You("die from starvation.");
1786. 			killer_format = KILLED_BY;
1787. 			killer = "starvation";
1788. 			done(STARVING);
1789. 			/* if we return, we lifesaved, and that calls newuhs */
1790. 			return;
1791. 		}
1792. 	}
1793. 
1794. 	if(newhs != u.uhs) {
1795. 		if(newhs >= WEAK && u.uhs < WEAK)
1796. 			losestr(1);	/* this may kill you -- see below */
1797. 		else if(newhs < WEAK && u.uhs >= WEAK)
1798. 			losestr(-1);
1799. 		switch(newhs){
1800. 		case HUNGRY:
1801. 			if (Hallucination) {
1802. 			    pline((!incr) ?
1803. 				"You now have a lesser case of the munchies." :
1804. 				"You are getting the munchies.");
1805. 			} else
1806. 			    You((!incr) ? "only feel hungry now." :
1807. 				  (u.uhunger < 145) ? "feel hungry." :
1808. 				   "are beginning to feel hungry.");
1809. 			if (incr && occupation &&
1810. 			    (occupation != eatfood && occupation != opentin))
1811. 			    stop_occupation();
1812. 			break;
1813. 		case WEAK:
1814. 			if (Hallucination)
1815. 			    pline((!incr) ?
1816. 				  "You still have the munchies." :
1817.       "The munchies are interfering with your motor capabilities.");
1818. 			else if (incr &&
1819. 				(Role_is('W') || Role_is('E') || Role_is('V')))
1820. 			    pline("%s needs food, badly!", pl_character);
1821. 			else
1822. 			    You((!incr) ? "feel weak now." :
1823. 				  (u.uhunger < 45) ? "feel weak." :
1824. 				   "are beginning to feel weak.");
1825. 			if (incr && occupation &&
1826. 			    (occupation != eatfood && occupation != opentin))
1827. 			    stop_occupation();
1828. 			break;
1829. 		}
1830. 		u.uhs = newhs;
1831. 		flags.botl = 1;
1832. 		if(u.uhp < 1) {
1833. 			You("die from hunger and exhaustion.");
1834. 			killer_format = KILLED_BY;
1835. 			killer = "exhaustion";
1836. 			done(STARVING);
1837. 			return;
1838. 		}
1839. 	}
1840. }
1841. 
1842. #endif /* OVL0 */
1843. #ifdef OVLB
1844. 
1845. /* Returns an object representing food.  Object may be either on floor or
1846.  * in inventory.
1847.  */
1848. struct obj *
1849. floorfood(verb,corpsecheck)	/* get food from floor or pack */
1850. 	const char *verb;
1851. 	int corpsecheck; /* 0, no check, 1, corpses, 2, tinnable corpses */
1852. {
1853. 	register struct obj *otmp;
1854. 	char qbuf[QBUFSZ];
1855. 	char c;
1856. 	boolean feeding = (!strcmp(verb, "eat"));
1857. 
1858. 	if (feeding && metallivorous(uasmon)) {
1859. 	    struct obj *gold;
1860. 	    struct trap *ttmp = t_at(u.ux, u.uy);
1861. 
1862. 	    if (ttmp && ttmp->tseen && ttmp->ttyp == BEAR_TRAP) {
1863. 		/* If not already stuck in the trap, perhaps there should
1864. 		   be a chance to becoming trapped?  Probably not, because
1865. 		   then the trap would just get eaten on the _next_ turn... */
1866. 		Sprintf(qbuf, "There is a bear trap here (%s); eat it?",
1867. 			(u.utrap && u.utraptype == TT_BEARTRAP) ?
1868. 				"holding you" : "armed");
1869. 		if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
1870. 		    u.utrap = u.utraptype = 0;
1871. 		    deltrap(ttmp);
1872. 		    return mksobj(BEARTRAP, TRUE, FALSE);
1873. 		} else if (c == 'q') {
1874. 		    return (struct obj *)0;
1875. 		}
1876. 	    }
1877. 
1878. 	    if ((gold = g_at(u.ux, u.uy)) != 0) {
1879. 		if (gold->quan == 1L)
1880. 		    Sprintf(qbuf, "There is 1 gold piece here; eat it?");
1881. 		else
1882. 		    Sprintf(qbuf, "There are %ld gold pieces here; eat them?",
1883. 			    gold->quan);
1884. 		if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
1885. 		    obj_extract_self(gold);
1886. 		    return gold;
1887. 		} else if (c == 'q') {
1888. 		    return (struct obj *)0;
1889. 		}
1890. 	    }
1891. 	}
1892. 
1893. 	/* Is there some food (probably a heavy corpse) here on the ground? */
1894. 	if (!(Levitation && !Is_airlevel(&u.uz)  && !Is_waterlevel(&u.uz))
1895. 	    && !u.uswallow) {
1896. 	    for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) {
1897. 		if(corpsecheck ?
1898. 		(otmp->otyp==CORPSE && (corpsecheck == 1 || tinnable(otmp))) :
1899. 		    feeding ? (otmp->oclass != GOLD_CLASS && is_edible(otmp)) :
1900. 						otmp->oclass==FOOD_CLASS) {
1901. 			Sprintf(qbuf, "There %s %s here; %s %s?",
1902. 				(otmp->quan == 1L) ? "is" : "are",
1903. 				doname(otmp), verb,
1904. 				(otmp->quan == 1L) ? "it" : "one");
1905. 			if((c = yn_function(qbuf,ynqchars,'n')) == 'y')
1906. 				return(otmp);
1907. 			else if(c == 'q')
1908. 				return((struct obj *) 0);
1909. 		}
1910. 	    }
1911. 	}
1912. 	/* We cannot use ALL_CLASSES since that causes getobj() to skip its
1913. 	 * "ugly checks" and we need to check for inedible items.
1914. 	 */
1915. 	otmp = getobj(feeding ? (const char *)allobj :
1916. 				(const char *)comestibles, verb);
1917. 	if (corpsecheck && otmp)
1918. 	    if (otmp->otyp != CORPSE || (corpsecheck == 2 && !tinnable(otmp))) {
1919. 		You_cant("%s that!", verb);
1920. 		return (struct obj *)0;
1921. 	    }
1922. 	return otmp;
1923. }
1924. 
1925. /* Side effects of vomiting */
1926. /* added nomul (MRS) - it makes sense, you're too busy being sick! */
1927. void
1928. vomit()		/* A good idea from David Neves */
1929. {
1930. 	make_sick(0L, (char *) 0, TRUE, SICK_VOMITABLE);
1931. 	nomul(-2);
1932. }
1933. 
1934. int
1935. eaten_stat(base, obj)
1936. register int base;
1937. register struct obj *obj;
1938. {
1939. 	long uneaten_amt, full_amount;
1940. 
1941. 	uneaten_amt = (long)obj->oeaten;
1942. 	full_amount = (obj->otyp == CORPSE) ? (long)mons[obj->corpsenm].cnutrit
1943. 					: (long)objects[obj->otyp].oc_nutrition;
1944. 
1945. 	base = (int)(full_amount ? (long)base * uneaten_amt / full_amount : 0L);
1946. 	return (base < 1) ? 1 : base;
1947. }
1948. 
1949. #endif /* OVLB */
1950. 
1951. /*eat.c*/

Also on Fandom

Random Wiki