Source:SLASH'EM 0.0.7E7F2/eat.c

Below is the full text to eat.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/eat.c#line123 ]], for example.

The latest source code for vanilla NetHack is at Source code.

1.   /*	SCCS Id: @(#)eat.c	3.4	2003/02/13	*/ 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 void FDECL(costly_tin, (const char*)); 19.  STATIC_PTR int NDECL(opentin); 20.  STATIC_PTR int NDECL(unfaint); 21.   22.   #ifdef OVLB 23.  STATIC_DCL const char *FDECL(food_xname, (struct obj *,BOOLEAN_P)); 24.  STATIC_DCL void FDECL(choke, (struct obj *)); 25.  STATIC_DCL void NDECL(recalc_wt); 26.  STATIC_DCL struct obj *FDECL(touchfood, (struct obj *)); 27.  STATIC_DCL void NDECL(do_reset_eat); 28.  STATIC_DCL void FDECL(done_eating, (BOOLEAN_P)); 29.  STATIC_DCL void FDECL(cprefx, (int)); 30.  STATIC_DCL int FDECL(intrinsic_possible, (int,struct permonst *)); 31.  STATIC_DCL void FDECL(givit, (int,struct permonst *)); 32.  STATIC_DCL void FDECL(cpostfx, (int)); 33.  STATIC_DCL void FDECL(start_tin, (struct obj *)); 34.  STATIC_DCL int FDECL(eatcorpse, (struct obj *)); 35.  STATIC_DCL void FDECL(start_eating, (struct obj *)); 36.  STATIC_DCL void FDECL(fprefx, (struct obj *)); 37.  STATIC_DCL void FDECL(accessory_has_effect, (struct obj *)); 38.  STATIC_DCL void FDECL(fpostfx, (struct obj *)); 39.  STATIC_DCL int NDECL(bite); 40.  STATIC_DCL int FDECL(edibility_prompts, (struct obj *)); 41.  STATIC_DCL int FDECL(rottenfood, (struct obj *)); 42.  STATIC_DCL void NDECL(eatspecial); 43.  STATIC_DCL void FDECL(eataccessory, (struct obj *)); 44.  STATIC_DCL const char *FDECL(foodword, (struct obj *)); 45.  STATIC_DCL boolean FDECL(maybe_cannibal, (int,BOOLEAN_P)); 46.  STATIC_DCL struct obj *FDECL(floorfood, (const char *)); 47.   48.   char msgbuf[BUFSZ]; 49.   50.   #endif /* OVLB */ 51.   52.   /* hunger texts used on bottom line (each 8 chars long) */ 53.  #define SATIATED	0 54.  #define NOT_HUNGRY	1 55.  #define HUNGRY		2 56.  #define WEAK		3 57.  #define FAINTING	4 58.  #define FAINTED		5 59.  #define STARVED		6 60.   61.   /* also used to see if you're allowed to eat cats and dogs */ 62.  #define CANNIBAL_ALLOWED (Role_if(PM_CAVEMAN) || Race_if(PM_ORC) || \  63.   			    Race_if(PM_HUMAN_WEREWOLF) || Race_if(PM_VAMPIRE)) 64.   65.   #ifndef OVLB 66.   67.   STATIC_DCL NEARDATA const char comestibles[]; 68.  STATIC_DCL NEARDATA const char allobj[]; 69.  STATIC_DCL boolean force_save_hs; 70.   71.   #else 72.   73.   STATIC_OVL NEARDATA const char comestibles[] = { FOOD_CLASS, 0 }; 74.   75.   /* Gold must come first for getobj. */ 76.   STATIC_OVL NEARDATA const char allobj[] = { COIN_CLASS, ALLOW_FLOOROBJ, 77.  	WEAPON_CLASS, ARMOR_CLASS, POTION_CLASS, SCROLL_CLASS, 78.  	WAND_CLASS, RING_CLASS, AMULET_CLASS, FOOD_CLASS, TOOL_CLASS, 79.  	GEM_CLASS, ROCK_CLASS, BALL_CLASS, CHAIN_CLASS, SPBOOK_CLASS, 0 }; 80.   81.   STATIC_OVL boolean force_save_hs = FALSE; 82.   83.   const char *hu_stat[] = { 84.  	"Satiated", 85.  	"        ",  86.   	"Hungry  ", 87.  	"Weak    ", 88.  	"Fainting", 89.  	"Fainted ", 90.  	"Starved " 91.  };  92.    93.   #endif /* OVLB */ 94.  #ifdef OVL1 95.   96.   /*  97.    * Decide whether a particular object can be eaten by the possibly 98.   * polymorphed character. Not used for monster checks. 99.   */  100.  boolean 101. is_edible(obj) 102. register struct obj *obj; 103. {  104.  	/* protect invocation tools but not Rider corpses (handled elsewhere)*/ 105.      /* if (obj->oclass != FOOD_CLASS && obj_resists(obj, 0, 0)) */ 106. 	if (evades_destruction(obj)) 107. 		return FALSE; 108. 	if (objects[obj->otyp].oc_unique) 109. 		return FALSE; 110. 	/* above also prevents the Amulet from being eaten, so we must never 111. 	   allow fake amulets to be eaten either [which is already the case] */ 112.  113.  	if (metallivorous(youmonst.data) && is_metallic(obj) &&  114.  	    (youmonst.data != &mons[PM_RUST_MONSTER] || is_rustprone(obj))) 115. 		return TRUE; 116. 	/* KMH -- Taz likes organics, too! */ 117.  	if ((u.umonnum == PM_GELATINOUS_CUBE || 118. 			u.umonnum == PM_TASMANIAN_DEVIL) && is_organic(obj) &&  119.  		/* [g.cubes can eat containers and retain all contents  120.  		    as engulfed items, but poly'd player can't do that] */  121.  	    !Has_contents(obj)) 122. 		return TRUE; 123.  124.  	/* Koalas only eat Eucalyptus leaves */ 125. 	if (u.umonnum == PM_KOALA) 126. 		return (boolean)(obj->otyp == EUCALYPTUS_LEAF); 127. 	  128.  	/* Ghouls, ghasts only eat corpses */ 129. 	if (u.umonnum == PM_GHOUL || u.umonnum == PM_GHAST) 130. 	   	return (boolean)(obj->otyp == CORPSE); 131. 	/* Vampires drink the blood of meaty corpses */ 132. 	/* [ALI] (fully) drained food is not presented as an option, 133. 	 * but partly eaten food is (even though you can't drain it). 134. 	 */  135.  	if (is_vampire(youmonst.data)) 136. 		return (boolean)(obj->otyp == CORPSE &&  137.  		  has_blood(&mons[obj->corpsenm]) && (!obj->odrained || 138. 		  obj->oeaten > drainlevel(obj))); 139.  140.       /* return((boolean)(!!index(comestibles, obj->oclass))); */ 141. 	return (boolean)(obj->oclass == FOOD_CLASS); 142. }  143.   144.  #endif /* OVL1 */ 145. #ifdef OVLB 146.  147.  void 148. init_uhunger 149. {  150.  	u.uhunger = 900; 151. 	u.uhs = NOT_HUNGRY; 152. }  153.   154.  static const struct { const char *txt; int nut; } tintxts[] = { 155. 	{"deep fried",	 60}, 156. 	{"pickled",	 40}, 157. 	{"soup made from", 20}, 158. 	{"pureed",	500}, 159. #define ROTTEN_TIN 4 160. 	{"rotten",	-50}, 161. #define HOMEMADE_TIN 5 162. 	{"homemade",	 50}, 163. 	{"stir fried",   80}, 164. 	{"candied",      100}, 165. 	{"boiled",       50}, 166. 	{"dried",        55}, 167. 	{"szechuan",     70}, 168. #define FRENCH_FRIED_TIN 11 169. 	{"french fried", 40}, 170. 	{"sauteed",      95}, 171. 	{"broiled",      80}, 172. 	{"smoked",       50}, 173. 	/* [Tom] added a few new styles */ 174. 	{"stir fried",   80}, 175. 	{"candied",      100}, 176. 	{"boiled",       50}, 177. 	{"dried",        55}, 178. 	{"szechuan",     70}, 179. 	{"french fried", 40}, 180. 	{"sauteed",      95}, 181. 	{"broiled",      80}, 182. 	{"smoked",       50}, 183. 	{"", 0}  184.  };  185.  #define TTSZ	SIZE(tintxts) 186.  187.  static NEARDATA struct { 188. 	struct	obj *tin; 189. 	int	usedtime, reqtime; 190. } tin; 191.  192.  static NEARDATA struct { 193. 	struct	obj *piece;	/* the thing being eaten, or last thing that 194. 				 * was partially eaten, unless that thing was 195. 				 * a tin, which uses the tin structure above, 196. 				 * in which case this should be 0 */ 197. 	/* doeat initializes these when piece is valid */ 198. 	int	usedtime,	/* turns spent eating */ 199. 		reqtime;	/* turns required to eat */ 200. 	int	nmod;		/* coded nutrition per turn */ 201. 	Bitfield(canchoke,1);	/* was satiated at beginning */ 202.  203.  	/* start_eating initializes these */ 204. 	Bitfield(fullwarn,1);	/* have warned about being full */ 205. 	Bitfield(eating,1);	/* victual currently being eaten */ 206. 	Bitfield(doreset,1);	/* stop eating at end of turn */ 207. } victual; 208.  209.  static char *eatmbuf = 0;	/* set by cpostfx */ 210.  211.  STATIC_PTR 212. int 213. eatmdone		/* called after mimicing is over */ 214. {  215.  	/* release `eatmbuf' */ 216. 	if (eatmbuf) { 217. 	    if (nomovemsg == eatmbuf) nomovemsg = 0; 218. 	    free((genericptr_t)eatmbuf),  eatmbuf = 0; 219. 	}  220.  	/* update display */ 221. 	if (youmonst.m_ap_type) { 222. 	    youmonst.m_ap_type = M_AP_NOTHING; 223. 	    newsym(u.ux,u.uy); 224. 	}  225.  	return 0; 226. }  227.   228.  /* ``[the(] singular(food, xname) [)]'' with awareness of unique monsters */ 229. STATIC_OVL const char * 230. food_xname(food, the_pfx) 231. struct obj *food; 232. boolean the_pfx; 233. {  234.  	const char *result; 235. 	int mnum = food->corpsenm; 236.  237.  	if (food->otyp == CORPSE && (mons[mnum].geno & G_UNIQ) && !Hallucination) { 238. 	    /* grab xname's modifiable return buffer for our own use */ 239. 	    char *bufp = xname(food); 240.  241.  	    Sprintf(bufp, "%s%s corpse",  242.  		    (the_pfx && !type_is_pname(&mons[mnum])) ? "the " : "",  243.  		    s_suffix(mons[mnum].mname)); 244. 	    result = bufp; 245. 	} else { 246. 	    /* the ordinary case */ 247. 	    result = singular(food, xname); 248. 	    if (the_pfx) result = the(result); 249. 	}  250.  	return result; 251. }  252.   253.   254.  /* Created by GAN 01/28/87 255.  * Amended by AKP 09/22/87: if not hard, don't choke, just vomit. 256.  * Amended by 3. 06/12/89: if not hard, sometimes choke anyway, to keep risk. 257.  *		  11/10/89: if hard, rarely vomit anyway, for slim chance. 258.  */  259.  STATIC_OVL void 260. choke(food)	/* To a full belly all food is bad. (It.) */ 261. register struct obj *food; 262. {  263.  	/* only happens if you were satiated */ 264. 	if (u.uhs != SATIATED) { 265. 		if (!food || food->otyp != AMULET_OF_STRANGULATION) 266. 			return; 267. 	} else if (Role_if(PM_KNIGHT) && u.ualign.type == A_LAWFUL) { 268. 			adjalign(-1);		/* gluttony is unchivalrous */ 269. 		You("feel like a glutton!"); 270. 	}  271.   272.  	exercise(A_CON, FALSE); 273.  274.  	if (Breathless || (!Strangled && !rn2(20))) { 275. 		/* choking by eating AoS doesn't involve stuffing yourself */ 276. 		/* ALI - nor does other non-food nutrition (eg., life-blood) */ 277. 		if (!food || food->otyp == AMULET_OF_STRANGULATION) { 278. 			nomovemsg = "You recover your composure."; 279. 			You("choke over it."); 280. 			nomul(-2); 281. 			return; 282. 		}  283.  		You("stuff yourself and then vomit voluminously."); 284. 		morehungry(1000);	/* you just got *very* sick! */ 285.  		nomovemsg = 0; 286. 		vomit; 287. 	} else { 288. 		killer_format = KILLED_BY_AN; 289. 		/*  290.  		 * Note all "killer"s below read "Choked on %s" on the 291. 		 * high score list & tombstone. So plan accordingly. 292. 		 */  293.  		if(food) { 294. 			You("choke over your %s.", foodword(food)); 295. 			if (food->oclass == COIN_CLASS) { 296. 				killer = "a very rich meal"; 297. 			} else { 298. 				killer = food_xname(food, FALSE); 299. 				if (food->otyp == CORPSE &&  300.  				    (mons[food->corpsenm].geno & G_UNIQ)) { 301. 				    if (!type_is_pname(&mons[food->corpsenm])) 302. 					killer = the(killer); 303. 				    killer_format = KILLED_BY; 304. 				}  305.  			}  306.  		} else { 307. 			You("choke over it."); 308. 			killer = "quick snack"; 309. 		}  310.  		You("die..."); 311. 		done(CHOKING); 312. 	}  313.  }  314.   315.  /* modify object wt. depending on time spent consuming it */ 316. STATIC_OVL void 317. recalc_wt 318. {  319.  	struct obj *piece = victual.piece; 320.  321.  #ifdef DEBUG 322. 	debugpline("Old weight = %d", piece->owt); 323. 	debugpline("Used time = %d, Req'd time = %d",  324.  		victual.usedtime, victual.reqtime); 325. #endif 326. 	piece->owt = weight(piece); 327. #ifdef DEBUG 328. 	debugpline("New weight = %d", piece->owt); 329. #endif 330. }  331.   332.  void 333. reset_eat		/* called when eating interrupted by an event */ 334. {  335.      /* we only set a flag here - the actual reset process is done after 336.      * the round is spent eating. 337.      */  338.  	if(victual.eating && !victual.doreset) { 339. #ifdef DEBUG 340. 	    debugpline("reset_eat..."); 341. #endif 342. 	    victual.doreset = TRUE; 343. 	}  344.  	return; 345. }  346.   347.  STATIC_OVL struct obj * 348. touchfood(otmp) 349. register struct obj *otmp; 350. {  351.  	if (otmp->quan > 1L) { 352. 	    if(!carried(otmp)) 353. 		(void) splitobj(otmp, otmp->quan - 1L); 354. 	    else 355. 		otmp = splitobj(otmp, 1L); 356.  357.  #ifdef DEBUG 358. 	    debugpline("split object,"); 359. #endif 360. 	}  361.   362.  	if (!otmp->oeaten) { 363. 	    if(((!carried(otmp) && costly_spot(otmp->ox, otmp->oy) &&  364.  		 !otmp->no_charge) 365. 		 || otmp->unpaid)) { 366. 		/* create a dummy duplicate to put on bill */ 367. 		verbalize("You bit it, you bought it!"); 368. 		bill_dummy_object(otmp); 369. 	    }  370.  	    otmp->oeaten = (otmp->otyp == CORPSE ?  371.  				mons[otmp->corpsenm].cnutrit :  372.  				objects[otmp->otyp].oc_nutrition); 373. 	}  374.   375.  	if (carried(otmp)) { 376. 	    freeinv(otmp); 377. 	    if (inv_cnt >= 52) { 378. 		sellobj_state(SELL_DONTSELL); 379. 		dropy(otmp); 380. 		sellobj_state(SELL_NORMAL); 381. 	    } else { 382. 		otmp->oxlth++;		/* hack to prevent merge */ 383. 		otmp = addinv(otmp); 384. 		otmp->oxlth--; 385. 	    }  386.  	}  387.  	return(otmp); 388. }  389.   390.  /* When food decays, in the middle of your meal, we don't want to dereference 391.  * any dangling pointers, so set it to null (which should still trigger  392.   * do_reset_eat at the beginning of eatfood) and check for null pointers 393.  * in do_reset_eat. 394.  */  395.  void 396. food_disappears(obj) 397. register struct obj *obj; 398. {  399.  	if (obj == victual.piece) victual.piece = (struct obj *)0; 400. 	if (obj->timed) obj_stop_timers(obj); 401. }  402.   403.  /* renaming an object usually results in it having a different address; 404.    so the sequence start eating/opening, get interrupted, name the food, 405.    resume eating/opening would restart from scratch */ 406. void 407. food_substitution(old_obj, new_obj) 408. struct obj *old_obj, *new_obj; 409. {  410.  	if (old_obj == victual.piece) victual.piece = new_obj; 411. 	if (old_obj == tin.tin) tin.tin = new_obj; 412. }  413.   414.  STATIC_OVL void 415. do_reset_eat 416. {  417.  #ifdef DEBUG 418. 	debugpline("do_reset_eat..."); 419. #endif 420. 	if (victual.piece) { 421. 		victual.piece = touchfood(victual.piece); 422. 		recalc_wt; 423. 	}  424.  	victual.fullwarn = victual.eating = victual.doreset = FALSE; 425. 	/* Do not set canchoke to FALSE; if we continue eating the same object 426. 	 * we need to know if canchoke was set when they started eating it the 427. 	 * previous time. And if we don't continue eating the same object 428. 	 * canchoke always gets recalculated anyway. 429. 	 */  430.  	stop_occupation; 431. 	newuhs(FALSE); 432. }  433.   434.  STATIC_PTR 435. int 436. eatfood		/* called each move during eating process */ 437. {  438.  	if(!victual.piece ||  439.  	 (!carried(victual.piece) && !obj_here(victual.piece, u.ux, u.uy))) { 440. 		/* maybe it was stolen? */ 441.  		do_reset_eat; 442. 		return(0); 443. 	}  444.  	if (is_vampire(youmonst.data) != victual.piece->odrained) { 445. 	    /* Polymorphed while eating/draining */ 446. 	    do_reset_eat; 447. 	    return(0); 448. 	}  449.  	if(!victual.eating) return(0); 450.  451.  	if(++victual.usedtime <= victual.reqtime) { 452. 	    if(bite) return(0); 453. 	    return(1);	/* still busy */ 454. 	} else {	/* done */ 455. 	    int crumbs = victual.piece->oeaten;		/* The last crumbs */ 456. 	    if (victual.piece->odrained) crumbs -= drainlevel(victual.piece); 457. 	    if (crumbs > 0) { 458. 		lesshungry(crumbs); 459. 		victual.piece->oeaten -= crumbs; 460. 	    }  461.  	    done_eating(TRUE); 462. 	    return(0); 463. 	}  464.  }  465.   466.  STATIC_OVL void 467. done_eating(message) 468. boolean message; 469. {  470.  	victual.piece->in_use = TRUE; 471. 	occupation = 0; /* do this early, so newuhs knows we're done */ 472. 	newuhs(FALSE); 473. 	if (nomovemsg) { 474. 		if (message) pline(nomovemsg); 475. 		nomovemsg = 0; 476. 	} else if (message) 477. 		You("finish %s %s.", victual.piece->odrained ? "draining" :  478.  		  "eating", food_xname(victual.piece, TRUE)); 479.  480.  	if(victual.piece->otyp == CORPSE) { 481. 		if (!victual.piece->odrained || Race_if(PM_VAMPIRE) && !rn2(5)) 482. 		cpostfx(victual.piece->corpsenm); 483. 	} else 484. 		fpostfx(victual.piece); 485.  486.  	if (victual.piece->odrained) 487. 		victual.piece->in_use = FALSE; 488. 	else 489. 	if (carried(victual.piece)) useup(victual.piece); 490. 	else useupf(victual.piece, 1L); 491. 	victual.piece = (struct obj *) 0; 492. 	victual.fullwarn = victual.eating = victual.doreset = FALSE; 493. }  494.   495.  STATIC_OVL boolean 496. maybe_cannibal(pm, allowmsg) 497. int pm; 498. boolean allowmsg; 499. {  500.  	if (your_race(&mons[pm])) { 501. 	    if (!CANNIBAL_ALLOWED) { 502. 		if (allowmsg) { 503. 		    if (Upolyd) 504. 			You("have a bad feeling deep inside."); 505. 		    You("cannibal!  You will regret this!"); 506. 		}  507.  		HAggravate_monster |= FROMOUTSIDE; 508. 		change_luck(-rn1(4,2));		/* -5..-2 */ 509. 	    } else if (Role_if(PM_CAVEMAN)) { 510. 		adjalign(sgn(u.ualign.type)); 511. 		You("honour the dead."); 512. 	    } else { 513. 		adjalign(-sgn(u.ualign.type)); 514. 		You_feel("evil and fiendish!"); 515. 	    }  516.  	    return TRUE; 517. 	}  518.  	return FALSE; 519. }  520.   521.  STATIC_OVL void 522. cprefx(pm) 523. register int pm; 524. {  525.  	(void) maybe_cannibal(pm,TRUE); 526. 	if (touch_petrifies(&mons[pm]) || pm == PM_MEDUSA) { 527. 	    if (!Stone_resistance &&  528.  		!(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) { 529. 		Sprintf(killer_buf, "tasting %s meat", mons[pm].mname); 530. 		killer_format = KILLED_BY; 531. 		killer = killer_buf; 532. 		You("turn to stone."); 533. 		done(STONING); 534. 		if (victual.piece) 535. 		    victual.eating = FALSE; 536. 		return; /* lifesaved */ 537. 	    }  538.  	}  539.   540.  	switch(pm) { 541. 	    case PM_LITTLE_DOG: 542. 	    case PM_DOG: 543. 	    case PM_LARGE_DOG: 544. 	    case PM_KITTEN: 545. 	    case PM_HOUSECAT: 546. 	    case PM_LARGE_CAT: 547. 		if (!CANNIBAL_ALLOWED) { 548. 		    You_feel("that %s the %s%s was a bad idea.",  549.  		      victual.eating ? "eating" : "biting",  550.  		      occupation == opentin ? "tinned " : "", mons[pm].mname); 551. 		    HAggravate_monster |= FROMOUTSIDE; 552. 		}  553.  		break; 554. 	    case PM_LIZARD: 555. 		if (Stoned) fix_petrification; 556. 		break; 557. 	    case PM_DEATH: 558. 	    case PM_PESTILENCE: 559. 	    case PM_FAMINE: 560. 		{ char buf[BUFSZ]; 561. 		    pline("Eating that is instantly fatal."); 562. 		    Sprintf(buf, "unwisely ate the body of %s",  563.  			    mons[pm].mname); 564. 		    killer = buf; 565. 		    killer_format = NO_KILLER_PREFIX; 566. 		    done(DIED); 567. 		    /* It so happens that since we know these monsters */ 568. 		    /* cannot appear in tins, victual.piece will always */ 569. 		    /* be what we want, which is not generally true. */ 570.  		    if (revive_corpse(victual.piece, FALSE)) 571. 			victual.piece = (struct obj *)0; 572. 		    return; 573. 		}  574.  	    case PM_GREEN_SLIME: 575. 		if (!Slimed && !Unchanging && !flaming(youmonst.data) &&  576.  			youmonst.data != &mons[PM_GREEN_SLIME]) { 577. 		    You("don't feel very well."); 578. 		    Slimed = 10L; 579. 		    flags.botl = 1; 580. 		}  581.  		/* Fall through */ 582. 	    default: 583. 		if (acidic(&mons[pm]) && Stoned) 584. 		    fix_petrification; 585. 		break; 586. 	}  587.  }  588.   589.  /*  590.   * Called when a vampire bites a monster. 591.  * Returns TRUE if hero died and was lifesaved. 592.  */  593.   594.  boolean 595. bite_monster(mon) 596. struct monst *mon; 597. {  598.      switch(monsndx(mon->data)) { 599. 	case PM_LIZARD: 600. 	    if (Stoned) fix_petrification; 601. 	    break; 602. 	case PM_DEATH: 603. 	case PM_PESTILENCE: 604. 	case PM_FAMINE: 605. 	    pline("Unfortunately, eating any of it is fatal."); 606. 	    done_in_by(mon); 607. 	    return TRUE;		/* lifesaved */ 608.  609.  	case PM_GREEN_SLIME: 610. 	    if (!Unchanging && youmonst.data != &mons[PM_FIRE_VORTEX] &&  611.  			    youmonst.data != &mons[PM_FIRE_ELEMENTAL] &&  612.  			    youmonst.data != &mons[PM_GREEN_SLIME]) { 613. 		You("don't feel very well."); 614. 		Slimed = 10L; 615. 	    }  616.  	    /* Fall through */ 617. 	default: 618. 	    if (acidic(mon->data) && Stoned) 619. 		fix_petrification; 620. 	    break; 621.     }  622.      return FALSE; 623. }  624.   625.  void 626. fix_petrification 627. {  628.  	Stoned = 0; 629. 	delayed_killer = 0; 630. 	if (Hallucination) 631. 	    pline("What a pity - you just ruined a future piece of %sart!",  632.  		  ACURR(A_CHA) > 15 ? "fine " : ""); 633. 	else 634. 	    You_feel("limber!"); 635. }  636.   637.  /*  638.   * If you add an intrinsic that can be gotten by eating a monster, add it  639. * to intrinsic_possible and givit. (It must already be in prop.h to 640.   * be an intrinsic property.) 641.  * It would be very easy to make the intrinsics not try to give you one 642.  * that you already had by checking to see if you have it in  643. * intrinsic_possible instead of givit. 644.  */  645.   646.  /* intrinsic_possible returns TRUE if a monster can give an intrinsic. */ 647.  STATIC_OVL int 648. intrinsic_possible(type, ptr) 649. int type; 650. register struct permonst *ptr; 651. {  652.  	switch (type) { 653. 	    case FIRE_RES: 654. #ifdef DEBUG 655. 		if (ptr->mconveys & MR_FIRE) { 656. 			debugpline("can get fire resistance"); 657. 			return(TRUE); 658. 		} else  return(FALSE); 659. #else 660. 		return(ptr->mconveys & MR_FIRE); 661. #endif 662. 	    case SLEEP_RES: 663. #ifdef DEBUG 664. 		if (ptr->mconveys & MR_SLEEP) { 665. 			debugpline("can get sleep resistance"); 666. 			return(TRUE); 667. 		} else  return(FALSE); 668. #else 669. 		return(ptr->mconveys & MR_SLEEP); 670. #endif 671. 	    case COLD_RES: 672. #ifdef DEBUG 673. 		if (ptr->mconveys & MR_COLD) { 674. 			debugpline("can get cold resistance"); 675. 			return(TRUE); 676. 		} else  return(FALSE); 677. #else 678. 		return(ptr->mconveys & MR_COLD); 679. #endif 680. 	    case DISINT_RES: 681. #ifdef DEBUG 682. 		if (ptr->mconveys & MR_DISINT) { 683. 			debugpline("can get disintegration resistance"); 684. 			return(TRUE); 685. 		} else  return(FALSE); 686. #else 687. 		return(ptr->mconveys & MR_DISINT); 688. #endif 689. 	    case SHOCK_RES:	/* shock (electricity) resistance */ 690. #ifdef DEBUG 691. 		if (ptr->mconveys & MR_ELEC) { 692. 			debugpline("can get shock resistance"); 693. 			return(TRUE); 694. 		} else  return(FALSE); 695. #else 696. 		return(ptr->mconveys & MR_ELEC); 697. #endif 698. 	    case POISON_RES: 699. #ifdef DEBUG 700. 		if (ptr->mconveys & MR_POISON) { 701. 			debugpline("can get poison resistance"); 702. 			return(TRUE); 703. 		} else  return(FALSE); 704. #else 705. 		return(ptr->mconveys & MR_POISON); 706. #endif 707. 	    case TELEPORT: 708. #ifdef DEBUG 709. 		if (can_teleport(ptr)) { 710. 			debugpline("can get teleport"); 711. 			return(TRUE); 712. 		} else  return(FALSE); 713. #else 714. 		return(can_teleport(ptr)); 715. #endif 716. 	    case TELEPORT_CONTROL: 717. #ifdef DEBUG 718. 		if (control_teleport(ptr)) { 719. 			debugpline("can get teleport control"); 720. 			return(TRUE); 721. 		} else  return(FALSE); 722. #else 723. 		return(control_teleport(ptr)); 724. #endif 725. 	    case TELEPAT: 726. #ifdef DEBUG 727. 		if (telepathic(ptr)) { 728. 			debugpline("can get telepathy"); 729. 			return(TRUE); 730. 		} else  return(FALSE); 731. #else 732. 		return(telepathic(ptr)); 733. #endif 734. 	    default: 735. 		return(FALSE); 736. 	}  737.  	/*NOTREACHED*/ 738. }  739.   740.  /* givit tries to give you an intrinsic based on the monster's level 741.  * and what type of intrinsic it is trying to give you. 742.  */  743.  /* KMH, balance patch -- eliminated temporary intrinsics from 744.  * corpses, and restored probabilities to NetHack levels. 745.  *  746.   * There were several ways to deal with this issue: 747.  * 1.  Let corpses convey permanent intrisics (as implemented in  748.   *     vanilla NetHack). This is the easiest method for players 749.  *     to understand and has the least player frustration. 750.  * 2.  Provide a temporary intrinsic if you don't already have it, 751.  *     a give the permanent intrinsic if you do have it (Slash's  752.   *     method). This is probably the most realistic solution, 753.  *     but players were extremely annoyed by it. 754.  * 3.  Let certain intrinsics be conveyed one way and the rest 755.  *     conveyed the other. However, there would certainly be 756. *    arguments about which should be which, and it would 757.  *     certainly become yet another FAQ. 758.  * 4.  Increase the timeouts. This is limited by the number of 759. *    bits reserved for the timeout. 760.  * 5.  Convey a permanent intrinsic if you have _ever_ been 761.  *     given the temporary intrinsic. This is a nice solution, 762.  *     but it would use another bit, and probably isn't worth 763.  *     the effort. 764.  * 6.  Give the player better notice when the timeout expires, 765.  *     and/or some method to check on intrinsics that is not as  766. *    revealing as enlightenment. 767.  * 7.  Some combination of the above. 768.  *  769.   * In the end, I decided that the simplest solution would be the 770.  * best solution. 771.  */  772.  STATIC_OVL void 773. givit(type, ptr) 774. int type; 775. register struct permonst *ptr; 776. {  777.  	register int chance; 778.  779.  #ifdef DEBUG 780. 	debugpline("Attempting to give intrinsic %d", type); 781. #endif 782. 	/* some intrinsics are easier to get than others */ 783. 	switch (type) { 784. 		case POISON_RES: 785. 			if ((ptr == &mons[PM_KILLER_BEE] || 786. 					ptr == &mons[PM_SCORPION]) && !rn2(4)) 787. 				chance = 1; 788. 			else 789. 				chance = 15; 790. 			break; 791. 		case TELEPORT: 792. 			chance = 10; 793. 			break; 794. 		case TELEPORT_CONTROL: 795. 			chance = 12; 796. 			break; 797. 		case TELEPAT: 798. 			chance = 1; 799. 			break; 800. 		default: 801. 			chance = 15; 802. 			break; 803. 	}  804.   805.  	if (ptr->mlevel <= rn2(chance)) 806. 		return;		/* failed die roll */ 807.  808.  	switch (type) { 809. 	    case FIRE_RES: 810. #ifdef DEBUG 811. 		debugpline("Trying to give fire resistance"); 812. #endif 813. 		if(!(HFire_resistance & FROMOUTSIDE)) { 814. 			You(Hallucination ? "be chillin'." :  815.  			    "feel a momentary chill."); 816. 			HFire_resistance |= FROMOUTSIDE; 817. 		}  818.  		break; 819. 	    case SLEEP_RES: 820. #ifdef DEBUG 821. 		debugpline("Trying to give sleep resistance"); 822. #endif 823. 		if(!(HSleep_resistance & FROMOUTSIDE)) { 824. 			You_feel("wide awake."); 825. 			HSleep_resistance |= FROMOUTSIDE; 826. 		}  827.  		break; 828. 	    case COLD_RES: 829. #ifdef DEBUG 830. 		debugpline("Trying to give cold resistance"); 831. #endif 832. 		if(!(HCold_resistance & FROMOUTSIDE)) { 833. 			You_feel("full of hot air."); 834. 			HCold_resistance |= FROMOUTSIDE; 835. 		}  836.  		break; 837. 	    case DISINT_RES: 838. #ifdef DEBUG 839. 		debugpline("Trying to give disintegration resistance"); 840. #endif 841. 		if(!(HDisint_resistance & FROMOUTSIDE)) { 842. 			You_feel(Hallucination ?  843.  			    "totally together, man." :  844.  			    "very firm."); 845. 			HDisint_resistance |= FROMOUTSIDE; 846. 		}  847.  		break; 848. 	    case SHOCK_RES:	/* shock (electricity) resistance */ 849. #ifdef DEBUG 850. 		debugpline("Trying to give shock resistance"); 851. #endif 852. 		if(!(HShock_resistance & FROMOUTSIDE)) { 853. 			if (Hallucination) 854. 				You_feel("grounded in reality."); 855. 			else 856. 				Your("health currently feels amplified!"); 857. 			HShock_resistance |= FROMOUTSIDE; 858. 		}  859.  		break; 860. 	    case POISON_RES: 861. #ifdef DEBUG 862. 		debugpline("Trying to give poison resistance"); 863. #endif 864. 		if(!(HPoison_resistance & FROMOUTSIDE)) { 865. 			You_feel(Poison_resistance ?  866.  				 "especially healthy." : "healthy."); 867. 			HPoison_resistance |= FROMOUTSIDE; 868. 		}  869.  		break; 870. 	    case TELEPORT: 871. #ifdef DEBUG 872. 		debugpline("Trying to give teleport"); 873. #endif 874. 		if(!(HTeleportation & FROMOUTSIDE)) { 875. 			You_feel(Hallucination ? "diffuse." :  876.  			    "very jumpy."); 877. 			HTeleportation |= FROMOUTSIDE; 878. 		}  879.  		break; 880. 	    case TELEPORT_CONTROL: 881. #ifdef DEBUG 882. 		debugpline("Trying to give teleport control"); 883. #endif 884. 		if(!(HTeleport_control & FROMOUTSIDE)) { 885. 			You_feel(Hallucination ?  886.  			    "centered in your personal space." :  887.  			    "in control of yourself."); 888. 			HTeleport_control |= FROMOUTSIDE; 889. 		}  890.  		break; 891. 	    case TELEPAT: 892. #ifdef DEBUG 893. 		debugpline("Trying to give telepathy"); 894. #endif 895. 		if(!(HTelepat & FROMOUTSIDE)) { 896. 			You_feel(Hallucination ?  897.  			    "in touch with the cosmos." :  898.  			    "a strange mental acuity."); 899. 			HTelepat |= FROMOUTSIDE; 900. 			/* If blind, make sure monsters show up. */ 901.  			if (Blind) see_monsters; 902. 		}  903.  		break; 904. 	    default: 905. #ifdef DEBUG 906. 		debugpline("Tried to give an impossible intrinsic"); 907. #endif 908. 		break; 909. 	}  910.  }  911.   912.  STATIC_OVL void 913. cpostfx(pm)		/* called after completely consuming a corpse */ 914. register int pm; 915. {  916.  	register int tmp = 0; 917. 	boolean catch_lycanthropy = FALSE; 918.  919.  	/* in case `afternmv' didn't get called for previously mimicking 920. 	   gold, clean up now to avoid `eatmbuf' memory leak */ 921. 	if (eatmbuf) (void)eatmdone; 922.  923.  	switch(pm) { 924. 	    case PM_NEWT: 925. 		/* MRKR: "eye of newt" may give small magical energy boost */ 926. 		if (rn2(3) || 3 * u.uen <= 2 * u.uenmax) { 927. 		    int old_uen = u.uen; 928. 		    u.uen += rnd(3); 929. 		    if (u.uen > u.uenmax) { 930. 			if (!rn2(3)) u.uenmax++; 931. 			u.uen = u.uenmax; 932. 		    }  933.  		    if (old_uen != u.uen) { 934. 			    You_feel("a mild buzz."); 935. 			    flags.botl = 1; 936. 		    }  937.  		}  938.  		break; 939. 	    case PM_WRAITH: 940. 		switch(rnd(10)) { 941. 		case 1: 942. 		    You("feel that was a bad idea."); 943. 		    losexp("eating a wraith corpse", FALSE); 944. 		    break; 945. 		case 2: 946. 		    You("don't feel so good ..."); 947. 		    if (Upolyd) { 948. 			u.mhmax -= 4; 949. 			if (u.mhmax < 1) u.mhmax = 1; 950. 		    } else { 951. 			u.uhpmax -= 4; 952. 			if (u.uhpmax < 1) u.uhpmax = 1; 953. 		    }  954.  		    u.uenmax -= 8; 955. 		    if (u.uenmax < 1) u.uenmax = 1; 956. 		    u.uen -= 8; 957. 		    if (u.uen < 0) u.uen = 0; 958. 		    losehp(4, "eating a wraith corpse", KILLED_BY); 959. 		    break; 960. 		case 3: 961. 		case 4: 962. 		    You("feel something strange for a moment."); 963. 		    break; 964. 		case 5: 965. 		    You("feel physically and mentally stronger!"); 966. 		    if (Upolyd) { 967. 			u.mhmax += 4; 968. 			u.mh = u.mhmax; 969. 		    } else { 970. 			u.uhpmax += 4; 971. 			u.uhp = u.uhpmax; 972. 		    }  973.  		    u.uenmax += 8; 974. 		    u.uen = u.uenmax; 975. 		    break; 976. 		case 6: 977. 		case 7: 978. 		case 8: 979. 		case 9: 980. 		case 10: 981. 		    You("feel that was a smart thing to do."); 982. 		pluslvl(FALSE); 983. 		break; 984. 		default: 985. 		    break; 986. 		}  987.  		flags.botl = 1; 988. 		break; 989. 	    case PM_HUMAN_WERERAT: 990. 		catch_lycanthropy = TRUE; 991. 		if (!Race_if(PM_HUMAN_WEREWOLF)) u.ulycn = PM_WERERAT; 992. 		break; 993. 	    case PM_HUMAN_WEREJACKAL: 994. 		catch_lycanthropy = TRUE; 995. 		if (!Race_if(PM_HUMAN_WEREWOLF)) u.ulycn = PM_WEREJACKAL; 996. 		break; 997. 	    case PM_HUMAN_WEREWOLF: 998. 		catch_lycanthropy = TRUE; 999. 		if (!Race_if(PM_HUMAN_WEREWOLF)) u.ulycn = PM_WEREWOLF; 1000. 		break; 1001. 	   case PM_HUMAN_WEREPANTHER: 1002. 		catch_lycanthropy = TRUE; 1003. 		if (!Race_if(PM_HUMAN_WEREWOLF)) u.ulycn = PM_WEREPANTHER; 1004. 		break; 1005. 	   case PM_HUMAN_WERETIGER: 1006. 		catch_lycanthropy = TRUE; 1007. 		if (!Race_if(PM_HUMAN_WEREWOLF)) u.ulycn = PM_WERETIGER; 1008. 		break; 1009. 	   case PM_HUMAN_WERESNAKE: 1010. 		catch_lycanthropy = TRUE; 1011. 		if (!Race_if(PM_HUMAN_WEREWOLF)) u.ulycn = PM_WERESNAKE; 1012. 		break; 1013. 	   case PM_HUMAN_WERESPIDER: 1014. 		catch_lycanthropy = TRUE; 1015. 		if (!Race_if(PM_HUMAN_WEREWOLF)) u.ulycn = PM_WERESPIDER; 1016. 		break; 1017. 	   case PM_NURSE: 1018. 		if (Upolyd) u.mh = u.mhmax; 1019. 		else u.uhp = u.uhpmax; 1020. 		flags.botl = 1; 1021. 		break; 1022. 	   case PM_STALKER: 1023. 		if(!Invis) { 1024. 			set_itimeout(&HInvis, (long)rn1(100, 50)); 1025. 			if (!Blind && !BInvis) self_invis_message; 1026. 		} else { 1027. 			if (!(HInvis & INTRINSIC)) You_feel("hidden!"); 1028. 			HInvis |= FROMOUTSIDE; 1029. 			HSee_invisible |= FROMOUTSIDE; 1030. 		} 1031. 		newsym(u.ux, u.uy); 1032. 		/* fall into next case */ 1033. 	   case PM_YELLOW_LIGHT: 1034. 		/* fall into next case */ 1035. 	   case PM_GIANT_BAT: 1036. 		make_stunned(HStun + 30,FALSE); 1037. 		/* fall into next case */ 1038. 	   case PM_BAT: 1039. 		make_stunned(HStun + 30,FALSE); 1040. 		break; 1041. 	   case PM_GIANT_MIMIC: 1042. 		tmp += 10; 1043. 		/* fall into next case */ 1044. 	   case PM_LARGE_MIMIC: 1045. 		tmp += 20; 1046. 		/* fall into next case */ 1047. 	   case PM_SMALL_MIMIC: 1048. 		tmp += 20; 1049. 		if (youmonst.data->mlet != S_MIMIC && !Unchanging) { 1050. 		   char buf[BUFSZ]; 1051. 		   You_cant("resist the temptation to mimic %s.",  1052. 			Hallucination ? "an orange" : "a pile of gold"); 1053. #ifdef STEED 1054.                    /* A pile of gold can't ride. */ 1055. 		    if (u.usteed) dismount_steed(DISMOUNT_FELL); 1056. #endif 1057. 		   nomul(-tmp); 1058. 		   Sprintf(buf, Hallucination ?  1059. 			"You suddenly dread being peeled and mimic %s again!" :  1060. 			"You now prefer mimicking %s again.",  1061. 			an(Upolyd ? youmonst.data->mname : urace.noun)); 1062. 		   eatmbuf = strcpy((char *) alloc(strlen(buf) + 1), buf); 1063. 		   nomovemsg = eatmbuf; 1064. 		   afternmv = eatmdone; 1065. 		   /* ??? what if this was set before? */ 1066. 		    youmonst.m_ap_type = M_AP_OBJECT; 1067. 		   youmonst.mappearance = Hallucination ? ORANGE : GOLD_PIECE; 1068. 		   newsym(u.ux,u.uy); 1069. 		   curs_on_u; 1070. 		   /* make gold symbol show up now */ 1071. 		   display_nhwindow(WIN_MAP, TRUE); 1072. 		} 1073. 		break; 1074. 	   case PM_QUANTUM_MECHANIC: 1075. 		Your("velocity suddenly seems very uncertain!"); 1076. 		if (HFast & INTRINSIC) { 1077. 			HFast &= ~INTRINSIC; 1078. 			You("seem slower."); 1079. 		} else { 1080. 			HFast |= FROMOUTSIDE; 1081. 			You("seem faster."); 1082. 		} 1083. 		break; 1084. 	   case PM_LIZARD: 1085. 		if (HStun > 2) make_stunned(2L,FALSE); 1086. 		if (HConfusion > 2) make_confused(2L,FALSE); 1087. 		break; 1088. 	   case PM_CHAMELEON: 1089. 	   case PM_DOPPELGANGER: 1090. 	 /* case PM_SANDESTIN: */ 1091. 		if (!Unchanging) { 1092. 		   You_feel("a change coming over you."); 1093. 		   polyself(FALSE); 1094. 		} 1095. 		break; 1096. 	   case PM_GENETIC_ENGINEER: /* Robin Johnson -- special msg */ 1097. 		if (!Unchanging) { 1098. 		   You("undergo a freakish metamorphosis!"); 1099. 		   polyself(FALSE); 1100. 		} 1101. 		break; 1102. 		/* WAC all mind flayers as per mondata.h have to be here */ 1103. 	   case PM_MASTER_MIND_FLAYER: 1104. 	   case PM_MIND_FLAYER: { 1105. #if 0 1106. 		int    temp; 1107. 		temp = urole.attrmax[A_INT]; 1108. #endif 1109. 		if (ABASE(A_INT) < ATTRMAX(A_INT)) { 1110. 			if (!rn2(2)) { 1111. 				pline("Yum! That was real brain food!"); 1112. 				(void) adjattrib(A_INT, 1, FALSE); 1113. 				break;	/* don't give them telepathy, too */ 1114. 			} 1115. 		}  1116. 		else { 1117. 			pline("For some reason, that tasted bland."); 1118. 		} 1119. 		}  1120. 		/* fall through to default case */ 1121. 	   default: { 1122. 		register struct permonst *ptr = &mons[pm]; 1123. 		int i, count; 1124. 1125. 		if (dmgtype(ptr, AD_STUN) || dmgtype(ptr, AD_HALU) ||  1126. 		    pm == PM_VIOLET_FUNGUS) { 1127. 			pline ("Oh wow! Great stuff!"); 1128. 			make_hallucinated(HHallucination + 200,FALSE,0L); 1129. 		} 1130. 		if(is_giant(ptr) && !rn2(4)) gainstr((struct obj *)0, 0); 1131. 1132. 		/* Check the monster for all of the intrinsics. If this 1133. 		 * monster can give more than one, pick one to try to give 1134. 		 * from among all it can give. 1135. 		 * 1136. 		 * If a monster can give 4 intrinsics then you have 1137. 		 * a 1/1 * 1/2 * 2/3 * 3/4 = 1/4 chance of getting the first, 1138. 		 * a 1/2 * 2/3 * 3/4 = 1/4 chance of getting the second, 1139. 		 * a 1/3 * 3/4 = 1/4 chance of getting the third, 1140. 		 * and a 1/4 chance of getting the fourth. 1141. 		 * 1142. 		 * And now a proof by induction: 1143. 		 * it works for 1 intrinsic (1 in 1 of getting it) 1144. 		 * for 2 you have a 1 in 2 chance of getting the second, 1145. 		 *	otherwise you keep the first 1146. 		 * for 3 you have a 1 in 3 chance of getting the third, 1147. 		 *	otherwise you keep the first or the second 1148. 		 * for n+1 you have a 1 in n+1 chance of getting the (n+1)st, 1149. 		 *	otherwise you keep the previous one. 1150. 		 * Elliott Kleinrock, October 5, 1990 1151. 		 */ 1152.  1153. 		 count = 0;	/* number of possible intrinsics */ 1154. 		 tmp = 0;	/* which one we will try to give */ 1155. 		 for (i = 1; i <= LAST_PROP; i++) { 1156. 			if (intrinsic_possible(i, ptr)) { 1157. 				count++; 1158. 				/* a 1 in count chance of replacing the old 1159. 				 * one with this one, and a count-1 in count 1160. 				 * chance of keeping the old one. (note 1161. 				 * that 1 in 1 and 0 in 1 are what we want  1162. 				 * for the first one  1163. 				 */  1164. 				if (!rn2(count)) {  1165. #ifdef DEBUG  1166. 					debugpline("Intrinsic %d replacing %d", 1167. 								i, tmp); 1168. #endif  1169. 					tmp = i;  1170. 				}  1171. 			}  1172. 		 }  1173.  1174. 		 /* if any found try to give them one */  1175. 		 if (count) givit(tmp, ptr);  1176. 	    }  1177. 	    break;  1178. 	}  1179.  1180. 	if (!Race_if(PM_HUMAN_WEREWOLF) && 1181. 		catch_lycanthropy && defends(AD_WERE, uwep)) { 1182. 	    if (!touch_artifact(uwep, &youmonst)) {  1183. 		dropx(uwep);  1184. 		uwepgone;  1185. 	    }  1186. 	}  1187.  1188. 	return;  1189. }  1190.  1191. void  1192. violated_vegetarian  1193. {  1194.     u.uconduct.unvegetarian++;  1195.     if (Role_if(PM_MONK)) {  1196. 	You_feel("guilty.");  1197. 	adjalign(-1);  1198.     }  1199.     return;  1200. }  1201.  1202. /* common code to check and possibly charge for 1 context.tin.tin,  1203.  * will split context.tin.tin if necessary */  1204. STATIC_PTR  1205. void  1206. costly_tin(verb)  1207. 	const char* verb;		/* if 0, the verb is "open" */  1208. {  1209. 	if(((!carried(tin.tin) && 1210. 	    costly_spot(tin.tin->ox, tin.tin->oy) && 1211. 	    !tin.tin->no_charge)  1212. 	    || tin.tin->unpaid)) {  1213. 	    verbalize("You %s it, you bought it!", verb ? verb : "open"); 1214. 	    if(tin.tin->quan > 1L) tin.tin = splitobj(tin.tin, 1L);  1215. 	    bill_dummy_object(tin.tin);  1216. 	}  1217. }  1218.  1219. STATIC_PTR  1220. int  1221. opentin		/* called during each move whilst opening a tin */  1222. {  1223. 	register int r;  1224. 	const char *what;  1225. 	int which;  1226.  1227. 	if(!carried(tin.tin) && !obj_here(tin.tin, u.ux, u.uy))  1228. 					/* perhaps it was stolen? */  1229. 		return(0);		/* %% probably we should use tinoid */  1230. 	if(tin.usedtime++ >= 50) {  1231. 		You("give up your attempt to open the tin.");  1232. 		return(0);  1233. 	}  1234. 	if(tin.usedtime < tin.reqtime)  1235. 		return(1);		/* still busy */  1236. 	if(tin.tin->otrapped || 1237. 	  (tin.tin->cursed && tin.tin->spe != -1 && !rn2(8))) {  1238. 		b_trapped("tin", 0);  1239. 		costly_tin("destroyed");  1240. 		goto use_me;  1241. 	}  1242. 	You("succeed in opening the tin.");  1243. 	if(tin.tin->spe != 1) {  1244. 	    if (tin.tin->corpsenm == NON_PM) {  1245. 		pline("It turns out to be empty.");  1246. 		tin.tin->dknown = tin.tin->known = TRUE;  1247. 		costly_tin((const char*)0);  1248. 		goto use_me;  1249. 	    }  1250. 	    r = tin.tin->cursed ? ROTTEN_TIN :	/* always rotten if cursed */  1251. 		    (tin.tin->spe == -1) ? HOMEMADE_TIN :  /* player made it */  1252. 			rn2(TTSZ-1);		/* else take your pick */  1253. 	    if (r == ROTTEN_TIN && (tin.tin->corpsenm == PM_LIZARD ||  1254. 			tin.tin->corpsenm == PM_LICHEN))  1255. 		r = HOMEMADE_TIN;		/* lizards don't rot */  1256. 	    else if (tin.tin->spe == -1 && !tin.tin->blessed && !rn2(7))  1257. 		r = ROTTEN_TIN;			/* some homemade tins go bad */ 1258. 	   which = 0;	/* 0=>plural, 1=>as-is, 2=>"the" prefix */ 1259. 	   if (Hallucination) { 1260. 		what = rndmonnam; 1261. 	   } else { 1262. 		what = mons[tin.tin->corpsenm].mname; 1263. 		if (mons[tin.tin->corpsenm].geno & G_UNIQ) 1264. 		   which = type_is_pname(&mons[tin.tin->corpsenm]) ? 1 : 2; 1265. 	    }  1266. 	    if (which == 0) what = makeplural(what); 1267. #ifdef EATEN_MEMORY 1268. 	   /* ALI - you already know the type of the tinned meat */ 1269. 	   if (tin.tin->known && mvitals[tin.tin->corpsenm].eaten < 255) 1270. 		mvitals[tin.tin->corpsenm].eaten++; 1271. 	   /* WAC - you only recognize if you've eaten this before */ 1272. 	   if (!mvitals[tin.tin->corpsenm].eaten && !Hallucination) { 1273. 		if (rn2(2)) 1274. 			pline ("It smells kind of like %s.", 1275. 				monexplain[mons[tin.tin->corpsenm].mlet]); 1276. 		else 1277. 			pline_The("smell is unfamiliar."); 1278. 	   } else 1279. #endif 1280. 	   pline("It smells like %s%s.", (which == 2) ? "the " : "", what); 1281. 1282. 	    if (yn("Eat it?") == 'n') { 1283. #ifdef EATEN_MEMORY 1284. 	   	/* ALI - you know the tin iff you recognized the contents */ 1285. 		if (mvitals[tin.tin->corpsenm].eaten) 1286. #endif 1287. 		if (!Hallucination) tin.tin->dknown = tin.tin->known = TRUE; 1288. 		if (flags.verbose) You("discard the open tin."); 1289. 		costly_tin((const char*)0); 1290. 		goto use_me; 1291. 	   }  1292. 	    /* in case stop_occupation was called on previous meal */ 1293. 	   victual.piece = (struct obj *)0; 1294. 	   victual.fullwarn = victual.eating = victual.doreset = FALSE; 1295. 1296. #ifdef EATEN_MEMORY 1297. 	   /* WAC - you only recognize if you've eaten this before */ 1298. 	   You("consume %s %s.", tintxts[r].txt,  1299. 				mvitals[tin.tin->corpsenm].eaten ?  1300. 				mons[tin.tin->corpsenm].mname : "food"); 1301. #else 1302. 	   You("consume %s %s.", tintxts[r].txt,  1303. 			mons[tin.tin->corpsenm].mname); 1304. #endif 1305. 1306. 	    /* KMH, conduct */ 1307. 	   u.uconduct.food++; 1308. 	   if (!vegan(&mons[tin.tin->corpsenm])) 1309. 		u.uconduct.unvegan++; 1310. 	   if (!vegetarian(&mons[tin.tin->corpsenm])) 1311. 		violated_vegetarian; 1312. 1313. #ifdef EATEN_MEMORY 1314. 	   if (mvitals[tin.tin->corpsenm].eaten) 1315. #endif 1316. 	   tin.tin->dknown = tin.tin->known = TRUE; 1317. 	   cprefx(tin.tin->corpsenm); cpostfx(tin.tin->corpsenm); 1318. 1319. 	    /* charge for one at pre-eating cost */ 1320. 	   costly_tin((const char*)0); 1321. 1322. 	    /* check for vomiting added by GAN 01/16/87 */ 1323. 	   if(tintxts[r].nut < 0) make_vomiting((long)rn1(15,10), FALSE); 1324. 	   else lesshungry(tintxts[r].nut); 1325. 1326. 	    if(r == 0 || r == FRENCH_FRIED_TIN) { 1327. 	       /* Assume !Glib, because you can't open tins when Glib. */ 1328. 		incr_itimeout(&Glib, rnd(15)); 1329. 		pline("Eating deep fried food made your %s very slippery.", 1330. 		      makeplural(body_part(FINGER))); 1331. 	   }  1332. 	} else { 1333. 	   if (tin.tin->cursed) 1334. 		pline("It contains some decaying%s%s substance.", 1335. 			Blind ? "" : " ", Blind ? "" : hcolor(NH_GREEN)); 1336. 	   else 1337. 		pline("It contains spinach."); 1338. 1339. 	    if (yn("Eat it?") == 'n') { 1340. 		if (!Hallucination && !tin.tin->cursed) 1341. 		   tin.tin->dknown = tin.tin->known = TRUE; 1342. 		if (flags.verbose) 1343. 		   You("discard the open tin."); 1344. 		costly_tin((const char*)0); 1345. 		goto use_me; 1346. 	   }  1347.  1348. 	    tin.tin->dknown = tin.tin->known = TRUE; 1349. 	   costly_tin((const char*)0); 1350. 1351. 	    if (!tin.tin->cursed) 1352. 		pline("This makes you feel like %s!", 1353. 		      Hallucination ? "Swee'pea" : "Popeye"); 1354. 	   lesshungry(600); 1355. 	   gainstr(tin.tin, 0); 1356. 	   u.uconduct.food++; 1357. 	} 1358. use_me: 1359. 	if (carried(tin.tin)) useup(tin.tin); 1360. 	else useupf(tin.tin, 1L); 1361. 	tin.tin = (struct obj *) 0; 1362. 	return(0); 1363. } 1364.  1365. STATIC_OVL void 1366. start_tin(otmp)		/* called when starting to open a tin */ 1367. 	register struct obj *otmp; 1368. { 1369. 	register int tmp; 1370. 1371. 	if (metallivorous(youmonst.data)) { 1372. 		You("bite right into the metal tin..."); 1373. 		tmp = 1; 1374. 	} else if (nolimbs(youmonst.data)) { 1375. 		You("cannot handle the tin properly to open it."); 1376. 		return; 1377. 	} else if (otmp->blessed) { 1378. 		pline_The("tin opens like magic!"); 1379. 		tmp = 1; 1380. 	} else if(uwep) { 1381. 		switch(uwep->otyp) { 1382. 		case TIN_OPENER: 1383. 			tmp = 1; 1384. 			break; 1385. 		case DAGGER: 1386. 		case SILVER_DAGGER: 1387. 		case ELVEN_DAGGER: 1388. 		case ORCISH_DAGGER: 1389. 		case ATHAME: 1390. 		case CRYSKNIFE: 1391. 		case DARK_ELVEN_DAGGER: 1392. 		case GREAT_DAGGER: 1393. 			tmp = 3; 1394. 			break; 1395. 		case PICK_AXE: 1396. 		case AXE: 1397. 			tmp = 6; 1398. 			break; 1399. 		default: 1400. 			goto no_opener; 1401. 		} 1402. 		pline("Using your %s you try to open the tin.",  1403. 			aobjnam(uwep, (char *)0)); 1404. 	} else { 1405. no_opener: 1406. 		pline("It is not so easy to open this tin."); 1407. 		if(Glib) { 1408. 			pline_The("tin slips from your %s.", 1409. 			      makeplural(body_part(FINGER))); 1410. 			if(otmp->quan > 1L) { 1411. 			   otmp = splitobj(otmp, 1L); 1412. 			} 1413. 			if (carried(otmp)) dropx(otmp); 1414. 			else stackobj(otmp); 1415. 			return; 1416. 		} 1417. 		tmp = rn1(1 + 500/((int)(ACURR(A_DEX) + ACURRSTR)), 10); 1418. 	} 1419. 	tin.reqtime = tmp; 1420. 	tin.usedtime = 0; 1421. 	tin.tin = otmp; 1422. 	set_occupation(opentin, "opening the tin", 0); 1423. 	return; 1424. } 1425.  1426. int 1427. Hear_again		/* called when waking up after fainting */ 1428. { 1429. 	flags.soundok = 1; 1430. 	return 0; 1431. } 1432.  1433. /* called on the "first bite" of rotten food */ 1434. STATIC_OVL int 1435. rottenfood(obj) 1436. struct obj *obj; 1437. { 1438. 	pline("Blecch!  Rotten %s!", foodword(obj)); 1439. 	if(!rn2(4)) { 1440. 		if (Hallucination) You_feel("rather trippy."); 1441. 		else You_feel("rather %s.", body_part(LIGHT_HEADED)); 1442. 		make_confused(HConfusion + d(2,4),FALSE); 1443. 	} else if(!rn2(4) && !Blind) { 1444. 		pline("Everything suddenly goes dark."); 1445. 		make_blinded((long)d(2,10),FALSE); 1446. 		if (!Blind) Your(vision_clears); 1447. 	} else if(!rn2(3)) { 1448. 		const char *what, *where; 1449. 		if (!Blind) 1450. 		   what = "goes",  where = "dark"; 1451. 		else if (Levitation || Is_airlevel(&u.uz) || 1452. 			 Is_waterlevel(&u.uz)) 1453. 		   what = "you lose control of",  where = "yourself"; 1454. 		else 1455. 		   what = "you slap against the", where = 1456. #ifdef STEED 1457. 			  (u.usteed) ? "saddle" : 1458. #endif 1459. 			  surface(u.ux,u.uy); 1460. 		pline_The("world spins and %s %s.", what, where); 1461. 		flags.soundok = 0; 1462. 		nomul(-rnd(10)); 1463. 		nomovemsg = "You are conscious again."; 1464. 		afternmv = Hear_again; 1465. 		return(1); 1466. 	} 1467. 	return(0); 1468. } 1469.  1470. /* [ALI] Return codes: 1471. *  1472.  *	0 - Ready to start eating 1473. *	1 - Corpse partly eaten, but don't start occupation 1474. *	2 - Corpse completely consumed, victual.piece left dangling 1475. *	3 - Corpse was inedible 1476. */  1477.  1478. STATIC_OVL int 1479. eatcorpse(otmp)		/* called when a corpse is selected as food */ 1480. 	register struct obj *otmp; 1481. { 1482. 	int tp = 0, mnum = otmp->corpsenm; 1483. 	long rotted = 0L; 1484. 	boolean uniq = !!(mons[mnum].geno & G_UNIQ); 1485. 	int retcode = 0; 1486. 	boolean stoneable = (touch_petrifies(&mons[mnum]) && !Stone_resistance && 1487. 				!poly_when_stoned(youmonst.data)); 1488. 1489.  1490. 	/* KMH, conduct */ 1491. 	if (!vegan(&mons[mnum])) u.uconduct.unvegan++; 1492. 	if (!vegetarian(&mons[mnum])) violated_vegetarian; 1493. 1494. 	if (mnum != PM_LIZARD && mnum != PM_LICHEN) { 1495. 		long age = peek_at_iced_corpse_age(otmp); 1496. 1497. 		rotted = (monstermoves - age)/(10L + rn2(20)); 1498. 		if (otmp->cursed) rotted += 2L; 1499. 		else if (otmp->blessed) rotted -= 2L; 1500. 	} 1501.  1502. 	/* Vampires only drink the blood of very young, meaty corpses 1503. 	 * is_edible only allows meaty corpses here 1504. 	 * Blood is assumed to be 1/5 of the nutrition 1505. 	 * Thus happens before the conduct checks intentionally - should it be after? 1506. 	 * Blood is assumed to be meat and flesh. 1507. 	 */ 1508. 	if (is_vampire(youmonst.data)) { 1509. 	   /* oeaten is set up by touchfood */ 1510. 	   if (otmp->odrained ? otmp->oeaten <= drainlevel(otmp) :  1511. 	      otmp->oeaten < mons[otmp->corpsenm].cnutrit) { 1512. 	   	pline("There is no blood left in this corpse!"); 1513. 	   	return 3; 1514. 	   } else if (rotted <= 0 &&  1515. 	      (peek_at_iced_corpse_age(otmp) + 5) >= monstermoves) { 1516. 		char buf[BUFSZ]; 1517. 1518. 		/* Generate the name for the corpse */ 1519. 		if (!uniq || Hallucination) 1520. 		   Sprintf(buf, "%s", the(corpse_xname(otmp,TRUE))); 1521. 		else 1522. 		   Sprintf(buf, "%s%s corpse",  1523. 			    !type_is_pname(&mons[mnum]) ? "the " : "",  1524. 			    s_suffix(mons[mnum].mname)); 1525. 1526. 	    	pline("You drain the blood from %s.", buf); 1527. 		otmp->odrained = 1; 1528. 	   } else { 1529. 	   	pline("The blood in this corpse has coagulated!"); 1530. 	   	return 3; 1531. 	   }  1532. 	}  1533. 	else 1534. 	   otmp->odrained = 0; 1535. 1536. 	/* Very rotten corpse will make you sick unless you are a ghoul or a ghast */ 1537. 	if (mnum != PM_ACID_BLOB && !stoneable && rotted > 5L) { 1538. 	   boolean cannibal = maybe_cannibal(mnum, FALSE); 1539. 	   if (u.umonnum == PM_GHOUL || u.umonnum == PM_GHAST) { 1540. 	   	pline("Yum - that %s was well aged%s!",  1541. 		      mons[mnum].mlet == S_FUNGUS ? "fungoid vegetation" :  1542. 		      !vegetarian(&mons[mnum]) ? "meat" : "protoplasm",  1543. 		      cannibal ? ", cannibal" : ""); 1544. 	   } else { 1545. 		pline("Ulch - that %s was tainted%s!", 1546. 		      mons[mnum].mlet == S_FUNGUS ? "fungoid vegetation" :  1547. 		      !vegetarian(&mons[mnum]) ? "meat" : "protoplasm",  1548. 		      cannibal ? ", cannibal" : ""); 1549. 		if (Sick_resistance) { 1550. 			pline("It doesn't seem at all sickening, though..."); 1551. 		} else { 1552. 			char buf[BUFSZ]; 1553. 			long sick_time; 1554. 1555. 			sick_time = (long) rn1(10, 10); 1556. 			/* make sure new ill doesn't result in improvement */ 1557. 			if (Sick && (sick_time > Sick)) 1558. 			   sick_time = (Sick > 1L) ? Sick - 1L : 1L; 1559. 			if (!uniq || Hallucination) 1560. 			   Sprintf(buf, "rotted %s", corpse_xname(otmp,TRUE)); 1561. 			else 1562. 			   Sprintf(buf, "%s%s rotted corpse",  1563. 				    !type_is_pname(&mons[mnum]) ? "the " : "",  1564. 				    s_suffix(mons[mnum].mname)); 1565. 			make_sick(sick_time, buf, TRUE, SICK_VOMITABLE); 1566. 		} 1567. 		if (carried(otmp)) useup(otmp); 1568. 		else useupf(otmp, 1L); 1569. 		return(2); 1570. 	   }  1571. 	} else if (youmonst.data == &mons[PM_GHOUL] ||  1572. 		   youmonst.data == &mons[PM_GHAST]) { 1573. 		pline ("This corpse is too fresh!"); 1574. 		return 3; 1575. 	} else if (acidic(&mons[mnum]) && !Acid_resistance) { 1576. 		tp++; 1577. 		You("have a very bad case of stomach acid."); /* not body_part */ 1578. 		losehp(rnd(15), "acidic corpse", KILLED_BY_AN); 1579. 	} else if (poisonous(&mons[mnum]) && rn2(5)) { 1580. 		tp++; 1581. 		pline("Ecch - that must have been poisonous!"); 1582. 		if(!Poison_resistance) { 1583. 			losestr(rnd(4)); 1584. 			losehp(rnd(15), "poisonous corpse", KILLED_BY_AN); 1585. 		} else	You("seem unaffected by the poison."); 1586. 	/* now any corpse left too long will make you mildly ill */ 1587. 	} else if ((rotted > 5L || (rotted > 3L && rn2(5))) 1588. 					&& !Sick_resistance) { 1589. 		tp++; 1590. 		You_feel("%ssick.", (Sick) ? "very " : ""); 1591. 		losehp(rnd(8), "cadaver", KILLED_BY_AN); 1592. 	} 1593.  1594. 	/* delay is weight dependent */ 1595. 	victual.reqtime = 3 + (mons[mnum].cwt >> 6); 1596. 	if (otmp->odrained) victual.reqtime = rounddiv(victual.reqtime, 5); 1597. 1598. 	if (!tp && mnum != PM_LIZARD && mnum != PM_LICHEN &&  1599. 			(otmp->orotten || !rn2(7))) { 1600. 	   if (rottenfood(otmp)) { 1601. 		otmp->orotten = TRUE; 1602. 		(void)touchfood(otmp); 1603. 		retcode = 1; 1604. 	   }  1605.  1606. 	    if (!mons[otmp->corpsenm].cnutrit) { 1607. 		/* no nutrution: rots away, no message if you passed out */ 1608. 		if (!retcode) pline_The("corpse rots away completely."); 1609. 		if (carried(otmp)) useup(otmp); 1610. 		else useupf(otmp, 1L); 1611. 		retcode = 2; 1612. 	   }  1613. 		     1614. 	    if (!retcode) consume_oeaten(otmp, 2);	/* oeaten >>= 2 */ 1615. 	   if (otmp->odrained && otmp->oeaten < drainlevel(otmp)) 1616. 	       otmp->oeaten = drainlevel(otmp); 1617. 	} else if (!is_vampire(youmonst.data)) { 1618. 	   pline("%s%s %s!",  1619. 		  !uniq ? "This " : !type_is_pname(&mons[mnum]) ? "The " : "",  1620. 		  food_xname(otmp, FALSE),  1621. 		  (vegan(&mons[mnum]) ? 1622. 		  (!carnivorous(youmonst.data) && herbivorous(youmonst.data)) : 1623. 		  (carnivorous(youmonst.data) && !herbivorous(youmonst.data)))  1624. 		  ? "is delicious" : "tastes terrible"); 1625. 	} 1626.  1627. #ifdef EATEN_MEMORY 1628. 	/* WAC Track food types eaten */ 1629. 	if (mvitals[mnum].eaten < 255) mvitals[mnum].eaten++; 1630. #endif 1631. 1632. 	return(retcode); 1633. } 1634.  1635. STATIC_OVL void 1636. start_eating(otmp)		/* called as you start to eat */ 1637. 	register struct obj *otmp; 1638. { 1639. #ifdef DEBUG 1640. 	debugpline("start_eating: %lx (victual = %lx)", otmp, victual.piece); 1641. 	debugpline("reqtime = %d", victual.reqtime); 1642. 	debugpline("(original reqtime = %d)", objects[otmp->otyp].oc_delay); 1643. 	debugpline("nmod = %d", victual.nmod); 1644. 	debugpline("oeaten = %d", otmp->oeaten); 1645. #endif 1646. 	victual.fullwarn = victual.doreset = FALSE; 1647. 	victual.eating = TRUE; 1648. 1649. 	if (otmp->otyp == CORPSE) { 1650. 	   cprefx(victual.piece->corpsenm); 1651. 	   if (!victual.piece || !victual.eating) { 1652. 		/* rider revived, or died and lifesaved */ 1653. 		return; 1654. 	   }  1655. 	}  1656.  1657. 	if (bite) return; 1658. 1659. 	if (++victual.usedtime >= victual.reqtime) { 1660. 	   /* print "finish eating" message if they just resumed -dlc */ 1661. 	   done_eating(victual.reqtime > 1 ? TRUE : FALSE); 1662. 	   return; 1663. 	} 1664.  1665. 	Sprintf(msgbuf, "%s %s", otmp->odrained ? "draining" : "eating",  1666. 	  food_xname(otmp, TRUE)); 1667. 	set_occupation(eatfood, msgbuf, 0); 1668. } 1669.  1670.  1671. /*  1672.  * called on "first bite" of (non-corpse) food. 1673. * used for non-rotten non-tin non-corpse food 1674. */  1675. STATIC_OVL void 1676. fprefx(otmp) 1677. struct obj *otmp; 1678. { 1679. 	switch(otmp->otyp) { 1680. 1681. 	    case FOOD_RATION: 1682. 		if(u.uhunger <= 200) 1683. 		   pline(Hallucination ? "Oh wow, like, superior, man!" :  1684. 			  "That food really hit the spot!"); 1685. 		else if(u.uhunger <= 700) pline("That satiated your %s!", 1686. 						body_part(STOMACH)); 1687. 		break; 1688. 	   case TRIPE_RATION: 1689. 		if (carnivorous(youmonst.data) && (!humanoid(youmonst.data)) || 1690. 			u.ulycn != NON_PM && carnivorous(&mons[u.ulycn]) &&  1691. 			!humanoid(&mons[u.ulycn])) 1692. 		   /* Symptom of lycanthropy is starting to like your 1693. 		    * alternative form's food! 1694. 		    */  1695. 		    pline("That tripe ration was surprisingly good!"); 1696. 		else if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC))) 1697. 		   pline(Hallucination ? "Tastes great! Less filling!" :  1698. 			  "Mmm, tripe... not bad!"); 1699. 		else { 1700. 		   pline("Yak - dog food!"); 1701. 		   more_experienced(1,0); 1702. 		   newexplevel; 1703. 		   /* not cannibalism, but we use similar criteria 1704. 		      for deciding whether to be sickened by this meal */ 1705. 		   if (rn2(2) && !CANNIBAL_ALLOWED) 1706. 			make_vomiting((long)rn1(victual.reqtime, 14), FALSE); 1707. 		} 1708. 		break; 1709. 	   case PILL: 1710. 		You("swallow the little pink pill."); 1711. 		switch(rn2(7)) 1712. 		{ 1713. 		   case 0: 1714. 			/* [Tom] wishing pills are from the Land of Oz */ 1715. 			pline ("The pink sugar coating hid a silver wishing pill!"); 1716. 			makewish; 1717. 			break; 1718. 		  case 1: 1719. 			if(!Poison_resistance) { 1720. 				You("feel your stomach twinge."); 1721. 				losestr(rnd(4)); 1722. 				losehp(rnd(15), "poisonous pill", KILLED_BY_AN); 1723. 			} else You("seem unaffected by the poison."); 1724. 			break; 1725. 		  case 2: 1726. 			pline ("Everything begins to get blurry."); 1727. 			make_stunned(HStun + 30,FALSE); 1728. 			break; 1729. 		  case 3: 1730. 			pline ("Oh wow! Look at the lights!"); 1731. 			make_hallucinated(HHallucination + 150,FALSE,0L); 1732. 			break; 1733. 		  case 4: 1734. 			pline("That tasted like vitamins..."); 1735. 			lesshungry(600); 1736. 			break; 1737. 		  case 5: 1738. 			if(Sleep_resistance) { 1739. 				pline("Hmm. Nothing happens."); 1740. 			} else { 1741. 				pline("You feel drowsy..."); 1742. 				nomul(-rn2(50)); 1743. 				u.usleep = 1; 1744. 				nomovemsg = "You wake up."; 1745. 			} 1746. 			break; 1747. 		  case 6: 1748. 			pline("Wow... everything is moving in slow motion..."); 1749. 			/* KMH, balance patch -- Use incr_itimeout instead of += */ 1750. 			incr_itimeout(&HFast, rn1(10,200)); 1751. 			break; 1752. 		} 1753. 		break; 1754. 	   case MUSHROOM: 1755. 	      pline("This %s is %s", singular(otmp, xname),  1756. 	       otmp->cursed ? (Hallucination ? "far-out!" : "terrible!") : 1757. 		      Hallucination ? "groovy!" : "delicious!"); 1758. 		switch(rn2(10)) 1759. 		{ 1760. 		   case 0: 1761. 		  case 1: 1762. 			if(!Poison_resistance) { 1763. 				You("feel rather ill...."); 1764. 				losestr(rnd(4)); 1765. 				losehp(rnd(15), "poisonous mushroom", KILLED_BY_AN); 1766. 			} else You("burp loudly."); 1767. 			break; 1768. 		  case 2: 1769. 			pline ("That mushroom tasted a little funny."); 1770. 			make_stunned(HStun + 30,FALSE); 1771. 			break; 1772. 		  case 3: 1773. 			pline ("Whoa! Everything looks groovy!"); 1774. 			make_hallucinated(HHallucination + 150,FALSE,0L); 1775. 			break; 1776. 		  case 4: 1777. 			gainstr(otmp, 1); 1778. 			pline ("You feel stronger!"); 1779. 			break; 1780. 		  case 5: 1781. 		  case 6: 1782. 		  case 7: 1783. 		  case 8: 1784. 		  case 9: 1785. 			break; 1786. 		} 1787. 		break; 1788. 	   case MEATBALL: 1789. 	   case MEAT_STICK: 1790. 	   case HUGE_CHUNK_OF_MEAT: 1791. 	   case MEAT_RING: 1792. 		goto give_feedback; 1793. 	    /* break; */ 1794. 	   case CLOVE_OF_GARLIC: 1795. 		if (is_undead(youmonst.data)) { 1796. 			make_vomiting((long)rn1(victual.reqtime, 5), FALSE); 1797. 			break; 1798. 		} 1799. 		/* Fall through otherwise */ 1800. 	   default: 1801. 		if (otmp->otyp == SLIME_MOLD && !otmp->cursed 1802. 			&& otmp->spe == current_fruit) 1803. 		   pline("My, that was a %s %s!",  1804. 			  Hallucination ? "primo" : "yummy",  1805. 			  singular(otmp, xname)); 1806. 		else 1807. #ifdef UNIX 1808. 		if (otmp->otyp == APPLE || otmp->otyp == PEAR) { 1809. 		   if (!Hallucination) pline("Core dumped."); 1810. 		   else { 1811. /* This is based on an old Usenet joke, a fake a.out manual page */ 1812. 			int x = rnd(100); 1813. 			if (x <= 75) 1814. 			   pline("Segmentation fault -- core dumped."); 1815. 			else if (x <= 99) 1816. 			   pline("Bus error -- core dumped."); 1817. 			else pline("Yo' mama -- core dumped."); 1818. 		   }  1819. 		} else 1820. #endif 1821. #ifdef MAC	/* KMH -- Why should Unix have all the fun? */ 1822. 		if (otmp->otyp == APPLE) { 1823. 			pline("This Macintosh is wonderful!"); 1824. 		} else 1825. #endif 1826. 		if (otmp->otyp == EGG && stale_egg(otmp)) { 1827. 		   pline("Ugh.  Rotten egg.");	/* perhaps others like it */ 1828. 		   make_vomiting(Vomiting+d(10,4), TRUE); 1829. 		} else { 1830. 		   boolean bad_for_you; 1831. give_feedback: 1832. 		   bad_for_you = otmp->cursed || 1833. 		     (Race_if(PM_HUMAN_WEREWOLF) &&  1834. 		      otmp->otyp == SPRIG_OF_WOLFSBANE); 1835. 		   pline("This %s is %s", singular(otmp, xname),  1836. 		      bad_for_you ? (Hallucination ? "grody!" : "terrible!") : 1837. 		      (otmp->otyp == CRAM_RATION 1838. 		     || otmp->otyp == K_RATION 1839. 		     || otmp->otyp == C_RATION)  1840. 		      ? "bland." :  1841. 		      Hallucination ? "gnarly!" : "delicious!"); 1842. 		} 1843. 		break; 1844. 	} 1845. }  1846.  1847. STATIC_OVL void 1848. accessory_has_effect(otmp) 1849. struct obj *otmp; 1850. { 1851. 	pline("Magic spreads through your body as you digest the %s.",  1852. 	    otmp->oclass == RING_CLASS ? "ring" : "amulet"); 1853. } 1854.  1855. STATIC_OVL void 1856. eataccessory(otmp) 1857. struct obj *otmp; 1858. { 1859. 	int typ = otmp->otyp; 1860. 	long oldprop; 1861. 1862. 	/* Note: rings are not so common that this is unbalancing. */ 1863. 	/* (How often do you even _find_ 3 rings of polymorph in a game?) */ 1864. 	/* KMH, intrinsic patch -- several changes below */ 1865. 	oldprop = u.uprops[objects[typ].oc_oprop].intrinsic; 1866. 	if (otmp == uleft || otmp == uright) { 1867. 	   Ring_gone(otmp); 1868. 	   if (u.uhp <= 0) return; /* died from sink fall */ 1869. 	} 1870. 	otmp->known = otmp->dknown = 1; /* by taste */ 1871. 	if (!rn2(otmp->oclass == RING_CLASS ? 3 : 5)) { 1872. 	  switch (otmp->otyp) { 1873. 	   default: 1874. 	       if (!objects[typ].oc_oprop) break; /* should never happen */ 1875. 1876. 		if (!(u.uprops[objects[typ].oc_oprop].intrinsic & FROMOUTSIDE)) 1877. 		   accessory_has_effect(otmp); 1878. 1879. 		u.uprops[objects[typ].oc_oprop].intrinsic |= FROMOUTSIDE; 1880. 1881. 		switch (typ) { 1882. 		 case RIN_SEE_INVISIBLE: 1883. 		   set_mimic_blocking; 1884. 		   see_monsters; 1885. 		   if (Invis && !oldprop && !ESee_invisible &&  1886. 				!perceives(youmonst.data) && !Blind) { 1887. 			newsym(u.ux,u.uy); 1888. 			pline("Suddenly you can see yourself."); 1889. 			makeknown(typ); 1890. 		   }  1891. 		    break; 1892. 		 case RIN_INVISIBILITY: 1893. 		   if (!oldprop && !EInvis && !BInvis &&  1894. 					!See_invisible && !Blind) { 1895. 			newsym(u.ux,u.uy); 1896. 			Your("body takes on a %s transparency...", 1897. 				Hallucination ? "normal" : "strange"); 1898. 			makeknown(typ); 1899. 		   }  1900. 		    break; 1901. 		 case RIN_PROTECTION_FROM_SHAPE_CHAN: 1902. 		   rescham; 1903. 		   break; 1904. 		 case RIN_LEVITATION: 1905. 		   /* undo the `.intrinsic |= FROMOUTSIDE' done above */ 1906. 		   u.uprops[LEVITATION].intrinsic = oldprop; 1907. 		   if (!Levitation) { 1908. 			float_up; 1909. 			incr_itimeout(&HLevitation, d(10,20)); 1910. 			makeknown(typ); 1911. 		   }  1912. 		    break; 1913. 		} 1914. 		break; 1915. 	   case RIN_ADORNMENT: 1916. 		accessory_has_effect(otmp); 1917. 		if (adjattrib(A_CHA, otmp->spe, -1)) 1918. 		   makeknown(typ); 1919. 		break; 1920. 	   case RIN_GAIN_STRENGTH: 1921. 		accessory_has_effect(otmp); 1922. 		if (adjattrib(A_STR, otmp->spe, -1)) 1923. 		   makeknown(typ); 1924. 		break; 1925. 	   case RIN_GAIN_CONSTITUTION: 1926. 		accessory_has_effect(otmp); 1927. 		if (adjattrib(A_CON, otmp->spe, -1)) 1928. 		   makeknown(typ); 1929. 		break; 1930. 	   case RIN_GAIN_INTELLIGENCE: 1931. 		accessory_has_effect(otmp); 1932. 		if (adjattrib(A_INT, otmp->spe, -1)) 1933. 		   makeknown(typ); 1934. 		break; 1935. 	   case RIN_GAIN_WISDOM: 1936. 		accessory_has_effect(otmp); 1937. 		if (adjattrib(A_WIS, otmp->spe, -1)) 1938. 		   makeknown(typ); 1939. 		break; 1940. 	   case RIN_GAIN_DEXTERITY: 1941. 		accessory_has_effect(otmp); 1942. 		if (adjattrib(A_DEX, otmp->spe, -1)) 1943. 		   makeknown(typ); 1944. 		break; 1945. 	   case RIN_INCREASE_ACCURACY: 1946. 		accessory_has_effect(otmp); 1947. 		u.uhitinc += otmp->spe; 1948. 		break; 1949. 	   case RIN_INCREASE_DAMAGE: 1950. 		accessory_has_effect(otmp); 1951. 		u.udaminc += otmp->spe; 1952. 		break; 1953. 	   case RIN_PROTECTION: 1954. 		accessory_has_effect(otmp); 1955. 		HProtection |= FROMOUTSIDE; 1956. 		u.ublessed += otmp->spe; 1957. 		flags.botl = 1; 1958. 		break; 1959. 	   case RIN_FREE_ACTION: 1960. 		/* Give sleep resistance instead */ 1961. 		if (!(HSleep_resistance & FROMOUTSIDE)) 1962. 		   accessory_has_effect(otmp); 1963. 		if (!Sleep_resistance) 1964. 		   You_feel("wide awake."); 1965. 		HSleep_resistance |= FROMOUTSIDE; 1966. 		break; 1967. 	   case AMULET_OF_CHANGE: 1968. 		accessory_has_effect(otmp); 1969. 		makeknown(typ); 1970. 		change_sex; 1971. 		You("are suddenly very %s!", 1972. 		    flags.female ? "feminine" : "masculine"); 1973. 		flags.botl = 1; 1974. 		break; 1975. 	   case AMULET_OF_UNCHANGING: 1976. 		/* un-change: it's a pun */ 1977. 		if (!Unchanging && Upolyd) { 1978. 		   accessory_has_effect(otmp); 1979. 		   makeknown(typ); 1980. 		   rehumanize; 1981. 		} 1982. 		break; 1983. 	   case AMULET_OF_STRANGULATION: /* bad idea! */ 1984. 		/* no message--this gives no permanent effect */ 1985. 		choke(otmp); 1986. 		break; 1987. 	   case AMULET_OF_RESTFUL_SLEEP: /* another bad idea! */ 1988. 	    case RIN_SLEEPING: 1989. 		if (!(HSleeping & FROMOUTSIDE)) 1990. 		   accessory_has_effect(otmp); 1991. 		HSleeping = FROMOUTSIDE | rnd(100); 1992. 		break; 1993. 	   case AMULET_VERSUS_STONE: 1994. 		/* no message--this gives no permanent effect */ 1995. 		(void)uunstone; 1996. 		break; 1997. 	   case RIN_SUSTAIN_ABILITY: 1998. 	   case AMULET_OF_FLYING: /* Intrinsic flying not supported --ALI */ 1999. 	   case AMULET_OF_LIFE_SAVING: 2000. 	   case AMULET_OF_REFLECTION: /* nice try */ 2001. 	   case AMULET_OF_DRAIN_RESISTANCE: 2002. 	   /* can't eat Amulet of Yendor or fakes, 2003. 	    * and no oc_prop even if you could -3. 2004. 	    */  2005. 		break; 2006. 	 }  2007. 	}  2008. }  2009.  2010. STATIC_OVL void 2011. eatspecial /* called after eating non-food */ 2012. { 2013. 	register struct obj *otmp = victual.piece; 2014. 2015. 	/* lesshungry wants an occupation to handle choke messages correctly */ 2016. 	set_occupation(eatfood, "eating non-food", 0); 2017. 	lesshungry(victual.nmod); 2018. 	occupation = 0; 2019. 	victual.piece = (struct obj *)0; 2020. 	victual.eating = 0; 2021. 	if (otmp->oclass == COIN_CLASS) { 2022. #ifdef GOLDOBJ 2023. 		if (carried(otmp)) 2024. 		   useupall(otmp); 2025. #else 2026. 		if (otmp->where == OBJ_FREE) 2027. 		   dealloc_obj(otmp); 2028. #endif 2029. 		else 2030. 		   useupf(otmp, otmp->quan); 2031. 		return; 2032. 	} 2033. 	if (otmp->oclass == POTION_CLASS) { 2034. 		otmp->quan++; /* dopotion does a useup */ 2035. 		(void)dopotion(otmp); 2036. 	} 2037. 	if (otmp->oclass == RING_CLASS || otmp->oclass == AMULET_CLASS) 2038. 		eataccessory(otmp); 2039. 	else if (otmp->otyp == LEASH && otmp->leashmon) 2040. 		o_unleash(otmp); 2041. 2042. 	/* KMH -- idea by "Tommy the Terrorist" */ 2043. 	if ((otmp->otyp == TRIDENT) && !otmp->cursed) 2044. 	{ 2045. 		pline(Hallucination ? "Four out of five dentists agree." :  2046. 				"That was pure chewing satisfaction!"); 2047. 		exercise(A_WIS, TRUE); 2048. 	} 2049. 	if ((otmp->otyp == FLINT) && !otmp->cursed) 2050. 	{ 2051. 		pline("Yabba-dabba delicious!"); 2052. 		exercise(A_CON, TRUE); 2053. 	} 2054.  2055. 	if (otmp == uwep && otmp->quan == 1L) uwepgone; 2056. 	if (otmp == uquiver && otmp->quan == 1L) uqwepgone; 2057. 	if (otmp == uswapwep && otmp->quan == 1L) uswapwepgone; 2058. 2059. 	if (otmp == uball) unpunish; 2060. 	if (otmp == uchain) unpunish; /* but no useup */ 2061. 	else if (carried(otmp)) useup(otmp); 2062. 	else useupf(otmp, 1L); 2063. } 2064.  2065. /* NOTE: the order of these words exactly corresponds to the 2066.   order of oc_material values #define'd in objclass.h. */ 2067. static const char *foodwords[] = { 2068. 	"meal", "liquid", "wax", "food", "meat", 2069. 	"paper", "cloth", "leather", "wood", "bone", "scale", 2070. 	"metal", "metal", "metal", "silver", "gold", "platinum", "mithril", 2071. 	"plastic", "glass", "rich food", "stone" 2072. }; 2073.  2074. STATIC_OVL const char * 2075. foodword(otmp) 2076. register struct obj *otmp; 2077. { 2078. 	if (otmp->oclass == FOOD_CLASS) return "food"; 2079. 	if (otmp->oclass == GEM_CLASS && 2080. 	    objects[otmp->otyp].oc_material == GLASS &&  2081. 	    otmp->dknown) 2082. 		makeknown(otmp->otyp); 2083. 	return foodwords[objects[otmp->otyp].oc_material]; 2084. } 2085.  2086. STATIC_OVL void 2087. fpostfx(otmp)		/* called after consuming (non-corpse) food */ 2088. register struct obj *otmp; 2089. { 2090. 	switch(otmp->otyp) { 2091. 	   case SPRIG_OF_WOLFSBANE: 2092. 		if (u.ulycn >= LOW_PM || is_were(youmonst.data) || Race_if(PM_HUMAN_WEREWOLF)) 2093. 		   you_unwere(TRUE); 2094. 		break; 2095. 	   case HOLY_WAFER: 2096. 		if (u.ualign.type == A_LAWFUL) { 2097. 			if (u.uhp < u.uhpmax) { 2098. 				You("feel warm inside."); 2099. 				u.uhp += rn1(20,20); 2100. 				if (u.uhp > u.uhpmax) u.uhp = u.uhpmax; 2101. 			} 2102. 		}  2103. 		if (Sick) make_sick(0L, (char *)0, TRUE, SICK_ALL); 2104. 		if (u.ulycn != -1) { 2105. 		   you_unwere(TRUE); 2106. 		} 2107. 		if (u.ualign.type == A_CHAOTIC) { 2108. 		   You("feel a burning inside!"); 2109. 		   u.uhp -= rn1(10,10); 2110. 		   /* KMH, balance patch 2 -- should not have 0 hp */ 2111. 		   if (u.uhp < 1) u.uhp = 1; 2112. 		} 2113. 		break; 2114. 	   case CARROT: 2115. 		make_blinded((long)u.ucreamed,TRUE); 2116. 		break; 2117. 	   /* body parts -- now checks for artifact and name*/ 2118. 	   case EYEBALL: 2119. 		if (!otmp->oartifact) break; 2120. 		You("feel a burning inside!"); 2121. 		u.uhp -= rn1(50,150); 2122. 		if (u.uhp <= 0) { 2123. 		 killer_format = KILLED_BY; 2124. 		 killer = food_xname(otmp, TRUE); 2125. 		 done(CHOKING); 2126. 		} 2127. 		break; 2128. 	   case SEVERED_HAND: 2129. 		if (!otmp->oartifact) break; 2130. 		You("feel the hand scrabbling around inside of you!"); 2131. 		u.uhp -= rn1(50,150); 2132. 		if (u.uhp <= 0) { 2133. 		 killer_format = KILLED_BY; 2134. 		 killer = food_xname(otmp, TRUE); 2135. 		 done(CHOKING); 2136. 		} 2137. 		break; 2138. 	   case FORTUNE_COOKIE: 2139. 	   	if (yn("Read the fortune?") == 'y') { 2140. 		outrumor(bcsign(otmp), BY_COOKIE); 2141. 		if (!Blind) u.uconduct.literate++; 2142. 		} 2143. 		break; 2144. /* STEHPEN WHITE'S NEW CODE */ 2145. 	   case LUMP_OF_ROYAL_JELLY: 2146. 		/* This stuff seems to be VERY healthy! */ 2147. 		gainstr(otmp, 1); 2148. 		if (Upolyd) { 2149. 		   u.mh += otmp->cursed ? -rnd(20) : rnd(20); 2150. 		   if (u.mh > u.mhmax) { 2151. 			if (!rn2(17)) u.mhmax++; 2152. 			u.mh = u.mhmax; 2153. 		   } else if (u.mh <= 0) { 2154. 			rehumanize; 2155. 		   }  2156. 		} else { 2157. 		   u.uhp += otmp->cursed ? -rnd(20) : rnd(20); 2158. 		   if (u.uhp > u.uhpmax) { 2159. 			if(!rn2(17)) u.uhpmax++; 2160. 			u.uhp = u.uhpmax; 2161. 		   } else if(u.uhp <= 0) { 2162. 			killer_format = KILLED_BY_AN; 2163. 			killer = "rotten lump of royal jelly"; 2164. 			done(POISONING); 2165. 		   }  2166. 		}  2167. 		if(!otmp->cursed) heal_legs; 2168. 		break; 2169. 	   case EGG: 2170. 		if (touch_petrifies(&mons[otmp->corpsenm])) { 2171. 		   if (!Stone_resistance &&  2172. 			!(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) { 2173. 			if (!Stoned) Stoned = 5; 2174. 			killer_format = KILLED_BY_AN; 2175. 			Sprintf(killer_buf, "%s egg", mons[otmp->corpsenm].mname); 2176. 			delayed_killer = killer_buf; 2177. 		   }  2178. 		}  2179. 		break; 2180. 	   case EUCALYPTUS_LEAF: 2181. 		if (Sick && !otmp->cursed) 2182. 		   make_sick(0L, (char *)0, TRUE, SICK_ALL); 2183. 		if (Vomiting && !otmp->cursed) 2184. 		   make_vomiting(0L, TRUE); 2185. 		break; 2186. 	} 2187.  2188. 	return; 2189. } 2190. /*  2191.  * return 0 if the food was not dangerous. 2192. * return 1 if the food was dangerous and you chose to stop. 2193. * return 2 if the food was dangerous and you chose to eat it anyway. 2194. */  2195. STATIC_OVL int 2196. edibility_prompts(otmp) 2197. struct obj *otmp; 2198. { 2199. 	/* blessed food detection granted you a one-use 2200. 	  ability to detect food that is unfit for consumption 2201. 	  or dangerous and avoid it. */ 2202.  2203. 	char buf[BUFSZ], foodsmell[BUFSZ], 2204. 	    it_or_they[QBUFSZ], eat_it_anyway[QBUFSZ]; 2205. 	boolean cadaver = (otmp->otyp == CORPSE), 2206. 		stoneorslime = FALSE; 2207. 	int material = objects[otmp->otyp].oc_material, 2208. 	   mnum = otmp->corpsenm; 2209. 	long rotted = 0L; 2210. 2211. 	Strcpy(foodsmell, Tobjnam(otmp, "smell")); 2212. 	Strcpy(it_or_they, (otmp->quan == 1L) ? "it" : "they"); 2213. 	Sprintf(eat_it_anyway, "Eat %s anyway?", 2214. 		(otmp->quan == 1L) ? "it" : "one"); 2215. 2216. 	if (cadaver || otmp->otyp == EGG || otmp->otyp == TIN) { 2217. 		/* These checks must match those in eatcorpse */ 2218. 	 	stoneorslime = (touch_petrifies(&mons[mnum]) &&  2219. 				!Stone_resistance &&  2220. 				!poly_when_stoned(youmonst.data)); 2221. 2222. 		if (mnum == PM_GREEN_SLIME) 2223. 		   stoneorslime = (!Unchanging && !flaming(youmonst.data) &&  2224. 			youmonst.data != &mons[PM_GREEN_SLIME]); 2225. 2226. 		if (cadaver && mnum != PM_LIZARD && mnum != PM_LICHEN) { 2227. 			long age = peek_at_iced_corpse_age(otmp); 2228. 			/* worst case rather than random 2229. 			  in this calculation to force prompt */ 2230. 			rotted = (monstermoves - age)/(10L + 0 /* was rn2(20) */); 2231. 			if (otmp->cursed) rotted += 2L; 2232. 			else if (otmp->blessed) rotted -= 2L; 2233. 		} 2234. 	}  2235.  2236. 	/*  2237. 	 * These problems with food should be checked in  2238. * order from most detrimental to least detrimental. 2239. 	 */ 2240.  2241. 	if (cadaver && mnum != PM_ACID_BLOB && rotted > 5L && !Sick_resistance) { 2242. 		/* Tainted meat */ 2243. 		Sprintf(buf, "%s like %s could be tainted! %s", 2244. 			foodsmell, it_or_they, eat_it_anyway); 2245. 		if (yn_function(buf,ynchars,'n')=='n') return 1; 2246. 		else return 2; 2247. 	} 2248. 	if (stoneorslime) { 2249. 		Sprintf(buf, "%s like %s could be something very dangerous! %s", 2250. 			foodsmell, it_or_they, eat_it_anyway); 2251. 		if (yn_function(buf,ynchars,'n')=='n') return 1; 2252. 		else return 2; 2253. 	} 2254. 	if (otmp->orotten || (cadaver && rotted > 3L)) { 2255. 		/* Rotten */ 2256. 		Sprintf(buf, "%s like %s could be rotten! %s", 2257. 			foodsmell, it_or_they, eat_it_anyway); 2258. 		if (yn_function(buf,ynchars,'n')=='n') return 1; 2259. 		else return 2; 2260. 	} 2261. 	if (cadaver && poisonous(&mons[mnum]) && !Poison_resistance) { 2262. 		/* poisonous */ 2263. 		Sprintf(buf, "%s like %s might be poisonous! %s", 2264. 			foodsmell, it_or_they, eat_it_anyway); 2265. 		if (yn_function(buf,ynchars,'n')=='n') return 1; 2266. 		else return 2; 2267. 	} 2268. 	if (cadaver && !vegetarian(&mons[mnum]) &&  2269. 	    !u.uconduct.unvegetarian && Role_if(PM_MONK)) { 2270. 		Sprintf(buf, "%s unhealthy. %s", 2271. 			foodsmell, eat_it_anyway); 2272. 		if (yn_function(buf,ynchars,'n')=='n') return 1; 2273. 		else return 2; 2274. 	} 2275. 	if (cadaver && acidic(&mons[mnum]) && !Acid_resistance) { 2276. 		Sprintf(buf, "%s rather acidic. %s", 2277. 			foodsmell, eat_it_anyway); 2278. 		if (yn_function(buf,ynchars,'n')=='n') return 1; 2279. 		else return 2; 2280. 	} 2281. 	if (Upolyd && u.umonnum == PM_RUST_MONSTER &&  2282. 	    is_metallic(otmp) && otmp->oerodeproof) { 2283. 		Sprintf(buf, "%s disgusting to you right now. %s", 2284. 			foodsmell, eat_it_anyway); 2285. 		if (yn_function(buf,ynchars,'n')=='n') return 1; 2286. 		else return 2; 2287. 	} 2288.  2289. 	/*  2290. 	 * Breaks conduct, but otherwise safe. 2291. 	 */ 2292. 	  2293. 	if (!u.uconduct.unvegan &&  2294. 	    ((material == LEATHER || material == BONE ||  2295. 	      material == EYEBALL || material == SEVERED_HAND ||  2296. 	      material == DRAGON_HIDE || material == WAX) || 2297. 	    (cadaver && !vegan(&mons[mnum])))) { 2298. 		Sprintf(buf, "%s foul and unfamiliar to you. %s", 2299. 			foodsmell, eat_it_anyway); 2300. 		if (yn_function(buf,ynchars,'n')=='n') return 1; 2301. 		else return 2; 2302. 	} 2303. 	if (!u.uconduct.unvegetarian &&  2304. 	    ((material == LEATHER || material == BONE ||  2305. 	      material == EYEBALL || material == SEVERED_HAND ||  2306. 	      material == DRAGON_HIDE) || 2307. 	    (cadaver && !vegetarian(&mons[mnum])))) { 2308. 		Sprintf(buf, "%s unfamiliar to you. %s", 2309. 			foodsmell, eat_it_anyway); 2310. 		if (yn_function(buf,ynchars,'n')=='n') return 1; 2311. 		else return 2; 2312. 	} 2313.  2314. 	if (cadaver && mnum != PM_ACID_BLOB && rotted > 5L && Sick_resistance) { 2315. 		/* Tainted meat with Sick_resistance */ 2316. 		Sprintf(buf, "%s like %s could be tainted! %s", 2317. 			foodsmell, it_or_they, eat_it_anyway); 2318. 		if (yn_function(buf,ynchars,'n')=='n') return 1; 2319. 		else return 2; 2320. 	} 2321. 	return 0; 2322. } 2323.  2324. int 2325. doeat		/* generic "eat" command funtion (see cmd.c) */ 2326. { 2327. 	register struct obj *otmp; 2328. 	int basenutrit;			/* nutrition of full item */ 2329. 	int nutrit;			/* nutrition available */ 2330. 	char qbuf[QBUFSZ]; 2331. 	char c; 2332. 2333. 	boolean dont_start = FALSE; 2334. 	if (Strangled) { 2335. 		pline("If you can't breathe air, how can you consume solids?"); 2336. 		return 0; 2337. 	} 2338. 	if (!(otmp = floorfood("eat"))) return 0; 2339. 	if (check_capacity((char *)0)) return 0; 2340. 2341. 	if (u.uedibility) { 2342. 		int res = edibility_prompts(otmp); 2343. 		if (res) { 2344. 		   Your("%s stops tingling and your sense of smell returns to normal.",  2345. 			body_part(NOSE)); 2346. 		   u.uedibility = 0; 2347. 		   if (res == 1) return 0; 2348. 		} 2349. 	}  2350.  2351. 	/* We have to make non-foods take 1 move to eat, unless we want to  2352. * do ridiculous amounts of coding to deal with partly eaten plate 2353. 	 * mails, players who polymorph back to human in the middle of their 2354. 	 * metallic meal, etc.... 2355. */ 2356. 	if (!is_edible(otmp)) { 2357. 	   You("cannot eat that!"); 2358. 	   return 0; 2359. 	} else if ((otmp->owornmask & (W_ARMOR|W_TOOL|W_AMUL 2360. #ifdef STEED  2361. 			|W_SADDLE  2362. #endif  2363. 			)) != 0) { 2364. 	   /* let them eat rings */ 2365. 	   You_cant("eat %s you're wearing.", something); 2366. 	   return 0; 2367. 	} 2368. 	if (is_metallic(otmp) &&  2369. 	    u.umonnum == PM_RUST_MONSTER && otmp->oerodeproof) { 2370. 	   	otmp->rknown = TRUE; 2371. 		if (otmp->quan > 1L) { 2372. 		   if(!carried(otmp)) 2373. 			(void) splitobj(otmp, otmp->quan - 1L); 2374. 		   else 2375. 			otmp = splitobj(otmp, 1L); 2376. 		} 2377. 		pline("Ulch - That %s was rustproofed!", xname(otmp)); 2378. 		/* The regurgitated object's rustproofing is gone now */ 2379. 		otmp->oerodeproof = 0; 2380. 		make_stunned(HStun + rn2(10), TRUE); 2381. 		You("spit %s out onto the %s.", the(xname(otmp)), 2382. 			surface(u.ux, u.uy)); 2383. 		if (carried(otmp)) { 2384. 			freeinv(otmp); 2385. 			dropy(otmp); 2386. 		} 2387. 		stackobj(otmp); 2388. 		return 1; 2389. 	} 2390. 	if (otmp->otyp == EYEBALL || otmp->otyp == SEVERED_HAND) { 2391. 	   Strcpy(qbuf,"Are you sure you want to eat that?"); 2392. 	   if ((c = yn_function(qbuf, ynqchars, 'n')) != 'y') return 0; 2393. 	} 2394.  2395. 	/* KMH -- Slow digestion is... indigestible */ 2396. 	if (otmp->otyp == RIN_SLOW_DIGESTION) { 2397. 		pline("This ring is indigestible!"); 2398. 		(void) rottenfood(otmp); 2399. 		if (otmp->dknown && !objects[otmp->otyp].oc_name_known 2400. 				&& !objects[otmp->otyp].oc_uname) 2401. 			docall(otmp); 2402. 		return (1); 2403. 	} 2404.  2405. 	if (otmp->oclass != FOOD_CLASS) { 2406. 	   int material; 2407. 	   victual.reqtime = 1; 2408. 	   victual.piece = otmp; 2409. 		/* Don't split it, we don't need to if it's 1 move */ 2410. 	   victual.usedtime = 0; 2411. 	   victual.canchoke = (u.uhs == SATIATED); 2412. 		/* Note: gold weighs 1 pt. for each 1000 pieces (see */ 2413. 		/* pickup.c) so gold and non-gold is consistent. */ 2414. 	    if (otmp->oclass == COIN_CLASS) 2415. 		basenutrit = ((otmp->quan > 200000L) ? 2000 2416. 			: (int)(otmp->quan/100L)); 2417. 	   else if(otmp->oclass == BALL_CLASS || otmp->oclass == CHAIN_CLASS) 2418. 		basenutrit = weight(otmp); 2419. 	   /* oc_nutrition is usually weight anyway */ 2420. 	   else basenutrit = objects[otmp->otyp].oc_nutrition; 2421. 	   victual.nmod = basenutrit; 2422. 	   victual.eating = TRUE; /* needed for lesshungry */ 2423. 2424. 	    material = objects[otmp->otyp].oc_material; 2425. 	   if (material == LEATHER ||  2426. 		material == EYEBALL || material == SEVERED_HAND ||  2427. 		material == BONE || material == DRAGON_HIDE) { 2428. 	 		u.uconduct.unvegan++; 2429. 	   		violated_vegetarian; 2430. 	   } else if (material == WAX) 2431. 			u.uconduct.unvegan++; 2432. 	   u.uconduct.food++; 2433. 	    2434. 	    if (otmp->cursed) 2435. 		(void) rottenfood(otmp); 2436. 2437. 	    if (otmp->oclass == WEAPON_CLASS && otmp->opoisoned) { 2438. 		pline("Ecch - that must have been poisonous!"); 2439. 		if(!Poison_resistance) { 2440. 		   losestr(rnd(4)); 2441. 		   losehp(rnd(15), xname(otmp), KILLED_BY_AN); 2442. 		} else 2443. 		   You("seem unaffected by the poison."); 2444. 	   } else if (!otmp->cursed) 2445. 		pline("This %s is delicious!", 2446. 		      otmp->oclass == COIN_CLASS ? foodword(otmp) :  2447. 		      singular(otmp, xname)); 2448. 2449. 	    eatspecial; 2450. 	   return 1; 2451. 	} 2452.  2453. 	/* [ALI] Hero polymorphed in the meantime. 2454. 	 */ 2455. 	if (otmp == victual.piece &&  2456. 	  is_vampire(youmonst.data) != otmp->odrained) 2457. 	   victual.piece = (struct obj *)0;	/* Can't resume */ 2458. 2459. 	/* [ALI] Blood can coagulate during the interruption 2460. 	 *      but not during the draining process. 2461. 	 */ 2462. 	if(otmp == victual.piece && otmp->odrained &&  2463. 	  (peek_at_iced_corpse_age(otmp) + victual.usedtime + 5) < monstermoves) 2464. 	   victual.piece = (struct obj *)0;	/* Can't resume */ 2465. 2466. 	if(otmp == victual.piece) { 2467. 	/* If they weren't able to choke, they don't suddenly become able to 2468. * choke just because they were interrupted. On the other hand, if 2469. * they were able to choke before, if they lost food it's possible 2470. 	 * they shouldn't be able to choke now. 2471. 	 */ 2472. 	    if (u.uhs != SATIATED) victual.canchoke = FALSE; 2473. 	   victual.piece = touchfood(otmp); 2474. 	   You("resume your meal."); 2475. 	   start_eating(victual.piece); 2476. 	   return(1); 2477. 	} 2478.  2479. 	/* nothing in progress - so try to find something. */ 2480. 	/* tins are a special case */ 2481. 	/* tins must also check conduct separately in case they're discarded */ 2482. 	if(otmp->otyp == TIN) { 2483. 	   start_tin(otmp); 2484. 	   return(1); 2485. 	} 2486.  2487. 	/* KMH, conduct */ 2488. 	u.uconduct.food++; 2489. 2490. 	victual.piece = otmp = touchfood(otmp); 2491. 	victual.usedtime = 0; 2492. 2493. 	/* Now we need to calculate delay and nutritional info. 2494. 	 * The base nutrition calculated here and in eatcorpse accounts 2495. 	 * for normal vs. rotten food. The reqtime and nutrit values are 2496. 	 * then adjusted in accordance with the amount of food left. 2497. 	 */ 2498. 	if(otmp->otyp == CORPSE) { 2499. 	   int tmp = eatcorpse(otmp); 2500. 	   if (tmp == 3) { 2501. 		/* inedible */ 2502. 		victual.piece = (struct obj *)0; 2503. 		/* 2504. 		 * The combination of odrained == TRUE and oeaten == cnutrit 2505. 		 * represents the case of starting to drain a corpse but not 2506. 		 * getting any further (eg., loosing consciousness due to 2507. 		 * rotten food). We must preserve this case to avoid corpses 2508. 		 * changing appearance after a failed attempt to eat. 2509. 		 */ 2510. 		if (!otmp->odrained &&  2511. 			otmp->oeaten == mons[otmp->corpsenm].cnutrit) 2512. 		   otmp->oeaten = 0; 2513. 		/* ALI, conduct: didn't eat it after all */ 2514. 		u.uconduct.food--; 2515. 		return 0; 2516. 	   } else if (tmp == 2) { 2517. 		/* used up */ 2518. 		victual.piece = (struct obj *)0; 2519. 		return(1); 2520. 	   } else if (tmp) 2521. 		dont_start = TRUE; 2522. 	   /* if not used up, eatcorpse sets up reqtime and may modify 2523. 	    * oeaten */ 2524. 	} else { 2525. 	   /* No checks for WAX, LEATHER, BONE, DRAGON_HIDE. These are 2526. 	    * all handled in the != FOOD_CLASS case, above */ 2527. 	   switch (objects[otmp->otyp].oc_material) { 2528. 	   case FLESH: 2529. 		u.uconduct.unvegan++; 2530. 		if (otmp->otyp != EGG && otmp->otyp != CHEESE) { 2531. 		   violated_vegetarian; 2532. 		} 2533. 		break; 2534. 2535. 	    default: 2536. 		if (otmp->otyp == PANCAKE || 2537. 		    otmp->otyp == FORTUNE_COOKIE || /* eggs */  2538. 		    otmp->otyp == CREAM_PIE ||  2539. 		    otmp->otyp == CANDY_BAR || /* milk */  2540. 		    otmp->otyp == LUMP_OF_ROYAL_JELLY) 2541. 		   u.uconduct.unvegan++; 2542. 		break; 2543. 	   }  2544.  2545. 	    victual.reqtime = objects[otmp->otyp].oc_delay; 2546. 	   if (otmp->otyp != FORTUNE_COOKIE &&  2547. 		(otmp->cursed || 2548. 		 (((monstermoves - otmp->age) > (int) otmp->blessed ? 50:30) && 2549. 		(otmp->orotten || !rn2(7))))) { 2550. 2551. 		if (rottenfood(otmp)) { 2552. 		   otmp->orotten = TRUE; 2553. 		   dont_start = TRUE; 2554. 		} 2555. 		if (otmp->oeaten < 2) { 2556. 		   victual.piece = (struct obj *)0; 2557. 		   if (carried(otmp)) useup(otmp); 2558. 		   else useupf(otmp, 1L); 2559. 		   return 1; 2560. 		} else 2561. 		consume_oeaten(otmp, 1);	/* oeaten >>= 1 */ 2562. 	   } else fprefx(otmp); 2563. 	} 2564.  2565. 	/* re-calc the nutrition */ 2566. 	if (otmp->otyp == CORPSE) basenutrit = mons[otmp->corpsenm].cnutrit; 2567. 	else basenutrit = objects[otmp->otyp].oc_nutrition; 2568. 	nutrit = otmp->oeaten; 2569. 	if (otmp->otyp == CORPSE && otmp->odrained) { 2570. 	   nutrit -= drainlevel(otmp); 2571. 	   basenutrit -= drainlevel(otmp); 2572. 	} 2573.  2574. #ifdef DEBUG 2575. 	debugpline("before rounddiv: victual.reqtime == %d", victual.reqtime); 2576. 	debugpline("oeaten == %d, basenutrit == %d", otmp->oeaten, basenutrit); 2577. 	debugpline("nutrit == %d, cnutrit == %d", nutrit, otmp->otyp == CORPSE ? 2578. 	  mons[otmp->corpsenm].cnutrit : objects[otmp->otyp].oc_nutrition); 2579. #endif 2580. 	victual.reqtime = (basenutrit == 0 ? 0 : 2581. 		rounddiv(victual.reqtime * (long)nutrit, basenutrit)); 2582. #ifdef DEBUG 2583. 	debugpline("after rounddiv: victual.reqtime == %d", victual.reqtime); 2584. #endif 2585. 	/* calculate the modulo value (nutrit. units per round eating) 2586. 	 * [ALI] Note: although this is not exact, the remainder is 2587. *      now dealt with in done_eating. 2588. 	 */ 2589. 	if (victual.reqtime == 0 || nutrit == 0) 2590. 	   /* possible if most has been eaten before */ 2591. 	   victual.nmod = 0; 2592. 	else if (nutrit >= victual.reqtime) 2593. 	   victual.nmod = -(nutrit / victual.reqtime); 2594. 	else 2595. 	   victual.nmod = victual.reqtime % nutrit; 2596. 	victual.canchoke = (u.uhs == SATIATED); 2597. 2598. 	if (!dont_start) start_eating(otmp); 2599. 	return(1); 2600. } 2601.  2602. /* Take a single bite from a piece of food, checking for choking and 2603. * modifying usedtime. Returns 1 if they choked and survived, 0 otherwise. 2604. */  2605. STATIC_OVL int 2606. bite 2607. { 2608. 	if(victual.canchoke && u.uhunger >= 2000) { 2609. 		choke(victual.piece); 2610. 		return 1; 2611. 	} 2612. 	if (victual.doreset) { 2613. 		do_reset_eat; 2614. 		return 0; 2615. 	} 2616. 	force_save_hs = TRUE; 2617. 	if(victual.nmod < 0) { 2618. 		lesshungry(-victual.nmod); 2619. 		consume_oeaten(victual.piece, victual.nmod); /* -= -nmod */ 2620. 	} else if(victual.nmod > 0 && (victual.usedtime % victual.nmod)) { 2621. 		lesshungry(1); 2622. 		consume_oeaten(victual.piece, -1);		 /* -= 1 */ 2623. 	} 2624. 	force_save_hs = FALSE; 2625. 	recalc_wt; 2626. 	return 0; 2627. } 2628.  2629. #endif /* OVLB */ 2630. #ifdef OVL0 2631. 2632. void 2633. gethungry	/* as time goes by - called by moveloop and domove */ 2634. { 2635. 	if (u.uinvulnerable) return;	/* you don't feel hungrier */ 2636. 2637. 	if ((!u.usleep || !rn2(10))	/* slow metabolic rate while asleep */  2638. 		&& (carnivorous(youmonst.data) || herbivorous(youmonst.data))  2639. 		&& !Slow_digestion) 2640. 	   u.uhunger--;		/* ordinary food consumption */ 2641. 2642. 	if (moves % 2) {	/* odd turns */ 2643. 	   /* Regeneration uses up food, unless due to an artifact */ 2644. 	   if (HRegeneration || ((ERegeneration & (~W_ART)) && 2645. 				(ERegeneration != W_WEP || !uwep->oartifact))) 2646. 			u.uhunger--; 2647. 	   if (near_capacity > SLT_ENCUMBER) u.uhunger--; 2648. 	} else {		/* even turns */ 2649. 	   if (Hunger) u.uhunger--; 2650. 	   /* Conflict uses up food too */ 2651. 	   if (HConflict || (EConflict & (~W_ARTI))) u.uhunger--; 2652. 	   /* +0 charged rings don't do anything, so don't affect hunger */ 2653. 	   /* Slow digestion still uses ring hunger */ 2654. 	   switch ((int)(moves % 20)) {	/* note: use even cases only */ 2655. 	    case  4: if (uleft &&  2656. 			  (uleft->spe || !objects[uleft->otyp].oc_charged)) 2657. 			   u.uhunger--; 2658. 		   break; 2659. 	    case  8: if (uamul) u.uhunger--; 2660. 		   break; 2661. 	    case 12: if (uright &&  2662. 			  (uright->spe || !objects[uright->otyp].oc_charged)) 2663. 			   u.uhunger--; 2664. 		   break; 2665. 	    case 16: if (u.uhave.amulet) u.uhunger--; 2666. 		   break; 2667. 	    default: break; 2668. 	   }  2669. 	}  2670. 	newuhs(TRUE); 2671. } 2672.  2673. #endif /* OVL0 */ 2674. #ifdef OVLB 2675. 2676. void 2677. morehungry(num)	/* called after vomiting and after performing feats of magic */ 2678. register int num; 2679. { 2680. 	u.uhunger -= num; 2681. 	newuhs(TRUE); 2682. } 2683.  2684.  2685. void 2686. lesshungry(num)	/* called after eating (and after drinking fruit juice) */ 2687. register int num; 2688. { 2689. 	/* See comments in newuhs for discussion on force_save_hs */ 2690. 	boolean iseating = occupation == eatfood || force_save_hs; 2691. #ifdef DEBUG 2692. 	debugpline("lesshungry(%d)", num); 2693. #endif 2694. 	u.uhunger += num; 2695. 	if(u.uhunger >= 2000) { 2696. 	   if (!iseating || victual.canchoke) { 2697. 		if (iseating) { 2698. 		   choke(victual.piece); 2699. 		   reset_eat; 2700. 		} else 2701. 		   choke(occupation == opentin ? tin.tin : (struct obj *)0); 2702. 		/* no reset_eat */ 2703. 	   }  2704. 	} else { 2705. 	   /* Have lesshungry report when you're nearly full so all eating 2706. 	    * warns when you're about to choke. 2707. 	    */  2708. 	    if (u.uhunger >= 1500) { 2709. 		if (!victual.eating || (victual.eating && !victual.fullwarn)) { 2710. 		   pline("You're having a hard time getting all of it down."); 2711. 		   nomovemsg = "You're finally finished."; 2712. 		   if (!victual.eating) 2713. 			multi = -2; 2714. 		   else { 2715. 			victual.fullwarn = TRUE; 2716. 			if (victual.canchoke && victual.reqtime > 1) { 2717. 			   /* a one-gulp food will not survive a stop */ 2718. 			   if (yn_function("Stop eating?",ynchars,'y')=='y') { 2719. 				reset_eat; 2720. 				nomovemsg = (char *)0; 2721. 			   }  2722. 			}  2723. 		    }  2724. 		}  2725. 	    }  2726. 	}  2727. 	newuhs(FALSE); 2728. } 2729.  2730. STATIC_PTR 2731. int 2732. unfaint 2733. { 2734. 	(void) Hear_again; 2735. 	if(u.uhs > FAINTING) 2736. 		u.uhs = FAINTING; 2737. 	stop_occupation; 2738. 	flags.botl = 1; 2739. 	return 0; 2740. } 2741.  2742. #endif /* OVLB */ 2743. #ifdef OVL0 2744. 2745. boolean 2746. is_fainted 2747. { 2748. 	return((boolean)(u.uhs == FAINTED)); 2749. } 2750.  2751. void 2752. reset_faint	/* call when a faint must be prematurely terminated */ 2753. { 2754. 	if(is_fainted) nomul(0); 2755. } 2756.  2757. #if 0 2758. void 2759. sync_hunger 2760. { 2761. 	if(is_fainted) { 2762. 		flags.soundok = 0; 2763. 		nomul(-10+(u.uhunger/10)); 2764. 		nomovemsg = "You regain consciousness."; 2765. 		afternmv = unfaint; 2766. 	} 2767. }  2768. #endif 2769. 2770. void 2771. newuhs(incr)		/* compute and comment on your (new?) hunger status */ 2772. boolean incr; 2773. { 2774. 	unsigned newhs; 2775. 	static unsigned save_hs; 2776. 	static boolean saved_hs = FALSE; 2777. 	int h = u.uhunger; 2778. 2779. 	newhs = (h > 1000) ? SATIATED : 2780. 		(h > 150) ? NOT_HUNGRY : 2781. 		(h > 50) ? HUNGRY : 2782. 		(h > 0) ? WEAK : FAINTING; 2783. 2784. 	/* While you're eating, you may pass from WEAK to HUNGRY to NOT_HUNGRY. 2785. 	 * This should not produce the message "you only feel hungry now"; 2786. 	 * that message should only appear if HUNGRY is an endpoint. Therefore 2787. 	 * we check to see if we're in the middle of eating. If so, we save 2788. 	 * the first hunger status, and at the end of eating we decide what 2789. 	 * message to print based on the _entire_ meal, not on each little bit. 2790. 	 */ 2791. 	/* It is normally possible to check if you are in the middle of a meal 2792. 	 * by checking occupation == eatfood, but there is one special case: 2793. 	 * start_eating can call bite for your first bite before it 2794. * sets the occupation. 2795. 	 * Anyone who wants to get that case to work _without_ an ugly static 2796. 	 * force_save_hs variable, feel free. 2797. 	 */ 2798. 	/* Note: If you become a certain hunger status in the middle of the 2799. 	 * meal, and still have that same status at the end of the meal, 2800. 	 * this will incorrectly print the associated message at the end of 2801. * the meal instead of the middle. Such a case is currently 2802. 	 * impossible, but could become possible if a message for SATIATED 2803. 	 * were added or if HUNGRY and WEAK were separated by a big enough 2804. 	 * gap to fit two bites. 2805. 	 */ 2806. 	if (occupation == eatfood || force_save_hs) { 2807. 		if (!saved_hs) { 2808. 			save_hs = u.uhs; 2809. 			saved_hs = TRUE; 2810. 		} 2811. 		u.uhs = newhs; 2812. 		return; 2813. 	} else { 2814. 		if (saved_hs) { 2815. 			u.uhs = save_hs; 2816. 			saved_hs = FALSE; 2817. 		} 2818. 	}  2819.  2820. 	if(newhs == FAINTING) { 2821. 		if(is_fainted) newhs = FAINTED; 2822. 		if(u.uhs <= WEAK || rn2(20-u.uhunger/10) >= 19) { 2823. 			if(!is_fainted && multi >= 0 /* %% */) { 2824. 				/* stop what you're doing, then faint */ 2825. 				stop_occupation; 2826. 				You("faint from lack of food."); 2827. 				flags.soundok = 0; 2828. 				nomul(-10+(u.uhunger/10)); 2829. 				nomovemsg = "You regain consciousness."; 2830. 				afternmv = unfaint; 2831. 				newhs = FAINTED; 2832. 			} 2833. 		} else 2834. 		if(u.uhunger < -(int)(200 + 20*ACURR(A_CON))) { 2835. 			u.uhs = STARVED; 2836. 			flags.botl = 1; 2837. 			bot; 2838. 			You("die from starvation."); 2839. 			killer_format = KILLED_BY; 2840. 			killer = "starvation"; 2841. 			done(STARVING); 2842. 			/* if we return, we lifesaved, and that calls newuhs */ 2843. 			return; 2844. 		} 2845. 	}  2846.  2847. 	if(newhs != u.uhs) { 2848. 		if(newhs >= WEAK && u.uhs < WEAK) 2849. 			losestr(1);	/* this may kill you -- see below */ 2850. 		else if(newhs < WEAK && u.uhs >= WEAK) 2851. 			losestr(-1); 2852. 		switch(newhs){ 2853. 		case HUNGRY: 2854. 			if (Hallucination) { 2855. 			   You((!incr) ?  2856. 				"now have a lesser case of the munchies." :  2857. 				"are getting the munchies."); 2858. 			} else 2859. 			   You((!incr) ? "only feel hungry now." :  2860. 				  (u.uhunger < 145) ? "feel hungry." :  2861. 				   "are beginning to feel hungry."); 2862. 			if (incr && occupation && 2863. 			    (occupation != eatfood && occupation != opentin)) 2864. 			   stop_occupation; 2865. 			break; 2866. 		case WEAK: 2867. 			if (Hallucination) 2868. 			   pline((!incr) ?  2869. 				  "You still have the munchies." :  2870.       "The munchies are interfering with your motor capabilities."); 2871. 			else if (incr && 2872. 				(Role_if(PM_WIZARD) || Race_if(PM_ELF) || 2873. 				 Role_if(PM_VALKYRIE))) 2874. 			   pline("%s needs food, badly!",  2875. 				  (Role_if(PM_WIZARD) || Role_if(PM_VALKYRIE)) ?  2876. 				  urole.name.m : "Elf"); 2877. 			else 2878. 			   You((!incr) ? "feel weak now." :  2879. 				  (u.uhunger < 45) ? "feel weak." :  2880. 				   "are beginning to feel weak."); 2881. 			if (incr && occupation && 2882. 			    (occupation != eatfood && occupation != opentin)) 2883. 			   stop_occupation; 2884. 			break; 2885. 		} 2886. 		u.uhs = newhs; 2887. 		flags.botl = 1; 2888. 		bot; 2889. 		if ((Upolyd ? u.mh : u.uhp) < 1) { 2890. 			You("die from hunger and exhaustion."); 2891. 			killer_format = KILLED_BY; 2892. 			killer = "exhaustion"; 2893. 			done(STARVING); 2894. 			return; 2895. 		} 2896. 	}  2897. }  2898.  2899. #endif /* OVL0 */ 2900. #ifdef OVLB 2901. 2902. boolean can_reach_floorobj 2903. { 2904.     return can_reach_floor && 2905. 	 !((is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) &&  2906. 	    (Wwalking || is_clinger(youmonst.data) || (Flying && !Breathless))); 2907. } 2908.  2909. /* Returns an object representing food. Object may be either on floor or 2910. * in inventory. 2911. */  2912. STATIC_OVL struct obj * 2913. floorfood(verb)		/* get food from floor or pack */ 2914. 	const char *verb; 2915. { 2916. 	register struct obj *otmp; 2917. 	/* We cannot use ALL_CLASSES since that causes getobj to skip its 2918. 	 * "ugly checks" and we need to check for inedible items. 2919. 	 */ 2920. 	const char *edibles = (const char *)allobj; 2921. 	char qbuf[QBUFSZ]; 2922. 	char c; 2923. 2924. #ifdef STEED 2925. 	if (u.usteed)	/* can't eat off floor while riding */ 2926. 	   edibles++; 2927. 	else 2928. #endif 2929. 	if (metallivorous(youmonst.data)) { 2930. 	   struct trap *ttmp = t_at(u.ux, u.uy); 2931. 2932. 	    if (ttmp && ttmp->tseen && ttmp->ttyp == BEAR_TRAP) { 2933. 		/* If not already stuck in the trap, perhaps there should 2934. 		  be a chance to becoming trapped? Probably not, because 2935. 		  then the trap would just get eaten on the _next_ turn... */ 2936. 		Sprintf(qbuf, "There is a bear trap here (%s); eat it?",  2937. 			(u.utrap && u.utraptype == TT_BEARTRAP) ?  2938. 				"holding you" : "armed"); 2939. 		if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') { 2940. 		   u.utrap = u.utraptype = 0; 2941. 		   deltrap(ttmp); 2942. 		   return mksobj(BEARTRAP, TRUE, FALSE); 2943. 		} else if (c == 'q') { 2944. 		   return (struct obj *)0; 2945. 		} 2946. 	    }  2947. 	}  2948.  2949. 	otmp = getobj(edibles, verb); 2950. 	if (otmp && otmp->oclass == COIN_CLASS) 2951. 	   obj_extract_self(otmp); 2952. 	return otmp; 2953. } 2954.  2955. /* Side effects of vomiting */ 2956. /* added nomul (MRS) - it makes sense, you're too busy being sick! */ 2957. void 2958. vomit		/* A good idea from David Neves */ 2959. { 2960. 	make_sick(0L, (char *) 0, TRUE, SICK_VOMITABLE); 2961. 	nomul(-2); 2962. 	nomovemsg = 0; 2963. } 2964.  2965. int 2966. eaten_stat(base, obj) 2967. register int base; 2968. register struct obj *obj; 2969. { 2970. 	long uneaten_amt, full_amount; 2971. 2972. 	uneaten_amt = (long)obj->oeaten; 2973. 	full_amount = (obj->otyp == CORPSE) ? (long)mons[obj->corpsenm].cnutrit 2974. 					: (long)objects[obj->otyp].oc_nutrition; 2975. 	if (uneaten_amt > full_amount) { 2976. 	   impossible(  2977. 	  "partly eaten food (%ld) more nutritious than untouched food (%ld)",  2978. 		       uneaten_amt, full_amount); 2979. 	   uneaten_amt = full_amount; 2980. 	} 2981.  2982. 	base = (int)(full_amount ? (long)base * uneaten_amt / full_amount : 0L); 2983. 	return (base < 1) ? 1 : base; 2984. } 2985.  2986. /* reduce obj's oeaten field, making sure it never hits or passes 0 */ 2987. void 2988. consume_oeaten(obj, amt) 2989. struct obj *obj; 2990. int amt; 2991. { 2992.     /*  2993.      * This is a hack to try to squelch several long standing mystery 2994.     * food bugs. A better solution would be to rewrite the entire 2995.     * victual handling mechanism from scratch using a less complex 2996.     * model. Alternatively, this routine could call done_eating 2997.     * or food_disappears but its callers would need revisions to  2998. * cope with victual.piece unexpectedly going away. 2999.     *  3000.      * Multi-turn eating operates by setting the food's oeaten field 3001.     * to its full nutritional value and then running a counter which 3002.     * independently keeps track of whether there is any food left. 3003.     * The oeaten field can reach exactly zero on the last turn, and 3004.     * the object isn't removed from inventory until the next turn 3005.     * when the "you finish eating" message gets delivered, so the 3006.     * food would be restored to the status of untouched during that 3007.     * interval. This resulted in unexpected encumbrance messages 3008.     * at the end of a meal (if near enough to a threshold) and would 3009.     * yield full food if there was an interruption on the critical 3010.     * turn. Also, there have been reports over the years of food 3011.     * becoming massively heavy or producing unlimited satiation; 3012.     * this would occur if reducing oeaten via subtraction attempted 3013.     * to drop it below 0 since its unsigned type would produce a  3014. * huge positive value instead. So far, no one has figured out 3015.     * _why_ that inappropriate subtraction might sometimes happen. 3016.     */  3017.  3018.     if (amt > 0) { 3019. 	/* bit shift to divide the remaining amount of food */ 3020. 	obj->oeaten >>= amt; 3021.    } else { 3022. 	/* simple decrement; value is negative so we actually add it */ 3023. 	if ((int) obj->oeaten > -amt) 3024. 	   obj->oeaten += amt; 3025. 	else 3026. 	   obj->oeaten = 0; 3027.    }  3028.  3029.     if (obj->oeaten == 0) { 3030. 	if (obj == victual.piece)	/* always true unless wishing... */ 3031. 	    victual.reqtime = victual.usedtime;	/* no bites left */ 3032. 	obj->oeaten = 1;	/* smallest possible positive value */ 3033.    }  3034. }  3035.  3036. #endif /* OVLB */ 3037. #ifdef OVL1 3038. 3039. /* called when eatfood occupation has been interrupted, 3040.   or in the case of theft, is about to be interrupted */ 3041. boolean 3042. maybe_finished_meal(stopping) 3043. boolean stopping; 3044. { 3045. 	/* in case consume_oeaten has decided that the food is all gone */ 3046. 	if (occupation == eatfood && victual.usedtime >= victual.reqtime) { 3047. 	   if (stopping) occupation = 0;	/* for do_reset_eat */ 3048. 	   (void) eatfood; /* calls done_eating to use up victual.piece */ 3049. 	   return TRUE; 3050. 	} 3051. 	return FALSE; 3052. } 3053.  3054. #endif /* OVL1 */ 3055. 3056. /*eat.c*/ 3057.