Source:Eat.c

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