Source:NetHack 3.4.0/eat.c

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