Source:NetHack 3.1.0/eat.c

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