Source:NetHack 3.3.0/eat.c

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