Source:NetHack 3.2.0/eat.c

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

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

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