Source:NetHack 2.3e/eat.c

Below is the full text to eat.c from the source code of NetHack 2.3e. To link to a particular line, write [[NetHack 2.3e/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	2.3	87/12/16 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.     4.    #include	"hack.h"  5.    #ifdef KAA 6.   char POISONOUS[] = "ADKSVabhks&"; 7.   #else 8.   char POISONOUS[] = "ADKSVabhks"; 9.   #endif 10.  extern char *nomovemsg; 11.  extern int (*afternmv); 12.  extern int (*occupation); 13.  extern char *occtxt; 14.  extern struct obj *splitobj, *addinv; 15.   16.   /* hunger texts used on bottom line (each 8 chars long) */ 17.  #define	SATIATED	0 18.  #define NOT_HUNGRY	1 19.  #define	HUNGRY		2 20.  #define	WEAK		3 21.  #define	FAINTING	4 22.  #define FAINTED		5 23.  #define STARVED		6 24.   25.   char *hu_stat[] = { 26.  	"Satiated", 27.  	"        ",  28.   	"Hungry  ", 29.  	"Weak    ", 30.  	"Fainting", 31.  	"Fainted ", 32.  	"Starved " 33.  };  34.    35.   init_uhunger{ 36.  	u.uhunger = 900; 37.  	u.uhs = NOT_HUNGRY; 38.  }  39.    40.   struct { char *txt; int nut; } tintxts[] = { 41.  	"It contains salmon - not bad!",	60, 42.  	"It contains first quality peaches - what a surprise!",	40, 43.  	"It contains apple juice - perhaps not what you hoped for.", 20, 44.  	"It contains some nondescript substance, tasting awfully.", 500, 45.  	"It contains rotten meat. You vomit.", -50, 46.  	"It turns out to be empty.",	0 47.  };  48.   #define	TTSZ	SIZE(tintxts) 49.   50.   static struct { 51.  	struct obj *tin; 52.  	int usedtime, reqtime; 53.  } tin; 54.   55.   opentin{ 56.  	register int r;  57. 58.  	if(!carried(tin.tin))		/* perhaps it was stolen? */ 59.   		return(0);		/* %% probably we should use tinoid */ 60.  	if(tin.usedtime++ >= 50) { 61.  		pline("You give up your attempt to open the tin."); 62.  		return(0); 63.  	}  64.   	if(tin.usedtime < tin.reqtime) 65.  		return(1);		/* still busy */ 66.   67.   	pline("You succeed in opening the tin."); 68.  	useup(tin.tin); 69.  	r = rn2(2*TTSZ); 70.  	if(r < TTSZ) { 71.  	    pline(tintxts[r].txt); 72.  	    lesshungry(tintxts[r].nut); 73.  	    /* check for vomiting added by GAN 01/16/87 */ 74.  	    if(tintxts[r].nut < 0 && Sick) { 75.  		Sick = 0; 76.  		pline("What a relief!"); 77.  	    }  78.   	    if(r == 0) {			/* Salmon */ 79.  		Glib = rnd(15); 80.  		pline("Eating salmon made your fingers very slippery."); 81.  	    }  82.   	} else { 83.  	    pline("It contains spinach - this makes you feel like %s!",  84.   		Hallucination ? "Swee'pea" : "Popeye"); 85.   86.   	    lesshungry(600); 87.  	    gainstr(0); 88.  	}  89.   	return(0); 90.  }  91.    92.   Meatdone{ 93.  	u.usym = '@'; 94.  	prme; 95.  }  96.    97.   doeat{ 98.  	register struct obj *otmp; 99.  	register struct objclass *ftmp; 100. 	register tmp; 101.  102.  	/* Is there some food (probably a heavy corpse) here on the ground? */ 103.  	if(!Levitation) 104. 	for(otmp = fobj; otmp; otmp = otmp->nobj) { 105. 		if(otmp->ox == u.ux && otmp->oy == u.uy &&  106.  		   otmp->olet == FOOD_SYM) { 107. 			pline("There %s %s here; eat %s? [ny] ",  108.  				(otmp->quan == 1) ? "is" : "are",  109.  				doname(otmp),  110.  				(otmp->quan == 1) ? "it" : "one"); 111. 			if(readchar == 'y') { 112. 				if(otmp->quan != 1) 113. 					(void) splitobj(otmp, 1); 114. 				freeobj(otmp); 115. 				otmp = addinv(otmp); 116. 				addtobill(otmp); 117. 				if(Invisible) newsym(u.ux, u.uy); 118. 				goto gotit; 119. 			}  120.  		}  121.  	}  122.  	otmp = getobj("%", "eat"); 123. 	if(!otmp) return(0); 124. gotit: 125. 	if(otmp->otyp == TIN) { 126. 		if(uwep) { 127. 			switch(uwep->otyp) { 128. 			case CAN_OPENER: 129. 				tmp = 1; 130. 				break; 131. 			case DAGGER: 132. 			case CRYSKNIFE: 133. 				tmp = 3; 134. 				break; 135. 			case PICK_AXE: 136. 			case AXE: 137. 				tmp = 6; 138. 				break; 139. 			default: 140. 				goto no_opener; 141. 			}  142.  			pline("Using your %s you try to open the tin.",  143.  				aobjnam(uwep, (char *) 0)); 144. 		} else { 145. 		no_opener: 146. 			pline("It is not so easy to open this tin."); 147. 			if(Glib) { 148. 				pline("The tin slips out of your hands."); 149. 				if(otmp->quan > 1) { 150. 					register struct obj *obj; 151. 					extern struct obj *splitobj; 152.  153.  					obj = splitobj(otmp, 1); 154. 					if(otmp == uwep) setuwep(obj); 155. 				}  156.  				dropx(otmp); 157. 				return(1); 158. 			}  159.  			tmp = 10 + rn2(1 + 500/((int)(u.ulevel + u.ustr))); 160. 		}  161.  		tin.reqtime = tmp; 162. 		tin.usedtime = 0; 163. 		tin.tin = otmp; 164. #ifdef DGK 165. 		set_occupation(opentin, "opening the tin", 0); 166. #else 167. 		occupation = opentin; 168. 		occtxt = "opening the tin"; 169. #endif 170. 		return(1); 171. 	}  172.  	ftmp = &objects[otmp->otyp]; 173. 	multi = -ftmp->oc_delay; 174. 	if(otmp->otyp >= CORPSE && eatcorpse(otmp)) goto eatx; 175. #ifdef DGKMOD 176. 	if(!rn2(7) && otmp->otyp != FORTUNE_COOKIE && otmp->otyp != DEAD_LIZARD) { 177. #else 178. 	if(!rn2(7) && otmp->otyp != FORTUNE_COOKIE) { 179. #endif 180. #ifdef KAA 181. 		if (otmp->otyp == DEAD_VIOLET_FUNGUS) 182. 			pline("Seems rather stale though..."); 183. 		else 184. #endif 185. 		pline("Blecch!  Rotten food!"); 186. 		if(!rn2(4)) { 187. 			if (Hallucination) pline("You feel rather trippy."); 188. 			else 189. 				pline("You feel rather light headed."); 190. 			HConfusion += d(2,4); 191. 		} else if(!rn2(4) && !Blind) { 192. 			pline("Everything suddenly goes dark."); 193. 			Blinded = d(2,10); 194. 			seeoff(0); 195. 		} else if(!rn2(3)) { 196. 			if(Blind) 197. 			  pline("The world spins and you slap against the floor."); 198. 			else 199. 			  pline("The world spins and goes dark."); 200. 			nomul(-rnd(10)); 201. 			nomovemsg = "You are conscious again."; 202. 		}  203.  		lesshungry(ftmp->nutrition / 4); 204. 	} else { 205. 		if(u.uhunger >= 1500) choke(ftmp); 206.  207.  		switch(otmp->otyp){ 208. 		case FOOD_RATION: 209. 			if(u.uhunger <= 200) 210. 			    if (Hallucination) 211. 				pline("Oh wow, like superior man!"); 212. 			    else 213. 				pline("That food really hit the spot!"); 214. 			else if(u.uhunger <= 700) 215. 				pline("That satiated your stomach!"); 216. #ifdef DGKMOD 217. 	/* Have lesshungry report when you're nearly full so all eating 218. 	 * warns when you're about to choke. 219. 	 */  220.  			lesshungry(ftmp->nutrition); 221. #else 222. 			else { 223. 	pline("You're having a hard time getting all that food down."); 224. 				multi -= 2; 225. 			}  226.  			lesshungry(ftmp->nutrition); 227. 			if(multi < 0) nomovemsg = "You finished your meal."; 228. #endif /* DGKMOD /**/ 229. 			break; 230. 		case TRIPE_RATION: 231. 			if (u.usym != '@') 232. 			    pline("That tripe ration was surprisingly good!"); 233. 			else { 234. 			    pline("Yak - dog food!"); 235. 			    more_experienced(1,0); 236. 			    flags.botl = 1; 237. 			}  238.  			if(rn2(2) && u.usym == '@'){ 239. 				pline("You vomit."); 240. 				morehungry(20); 241. 				if(Sick) { 242. 					Sick = 0;	/* David Neves */ 243. 					pline("What a relief!"); 244. 				}  245.  			} else	lesshungry(ftmp->nutrition); 246. 			break; 247. 		default: 248. 			if(u.usym == '@' && otmp->otyp >= CORPSE) { 249. #ifdef KAA 250. 			    if(otmp->otyp != DEAD_VIOLET_FUNGUS) 251. #endif 252. 			    pline("That %s tasted terrible!",ftmp->oc_name); 253. 			} else 254. 			pline("That %s was delicious!",ftmp->oc_name); 255. 			lesshungry(ftmp->nutrition); 256. #ifdef DGKMOD 257. 			/* Relief from cockatrices -dgk */ 258. 			if (otmp->otyp == DEAD_LIZARD) { 259. 				if (Stoned) { 260. 					Stoned = 0; 261. 					pline("You feel more limber!"); 262. 				}  263.  				if (HConfusion > 2) 264. 					HConfusion = 2; 265. 			}  266.  #else 267. 			if(otmp->otyp == DEAD_LIZARD && (HConfusion > 2)) 268. 				HConfusion = 2; 269. #endif /* DGKMOD /**/ 270. 			else 271. #ifdef QUEST 272. 			if(otmp->otyp == CARROT && !Blind) { 273. 				u.uhorizon++; 274. 				setsee; 275. 				pline("Your vision improves."); 276. 			} else 277. #endif 278. #ifdef KAA 279. 			if(otmp->otyp == CARROT && Blind) Blinded = 1; 280. 			else 281. #endif 282. 			if(otmp->otyp == FORTUNE_COOKIE) { 283. 			  if(Blind) { 284. 			    pline("This cookie has a scrap of paper inside!"); 285. 			    pline("What a pity, that you cannot read it!"); 286. 			  } else 287. 			    outrumor; 288. 			} else 289. 			if(otmp->otyp == LUMP_OF_ROYAL_JELLY) { 290. 				/* This stuff seems to be VERY healthy! */ 291.  				gainstr(1); 292. 				u.uhp += rnd(20); 293. 				if(u.uhp > u.uhpmax) { 294. 					if(!rn2(17)) u.uhpmax++; 295. 					u.uhp = u.uhpmax; 296. 				}  297.  				heal_legs; 298. 			}  299.  			break; 300. 		}  301.  	}  302.  eatx: 303. 	if(multi<0 && !nomovemsg){ 304. 		static char msgbuf[BUFSZ]; 305. 		(void) sprintf(msgbuf, "You finished eating the %s.",  306.  				ftmp->oc_name); 307. 		nomovemsg = msgbuf; 308. 	}  309.  	useup(otmp); 310. 	return(1); 311. }  312.   313.  /* called in main.c */ 314. gethungry{ 315. 	--u.uhunger; 316. 	if(moves % 2) { 317. 		if(HRegeneration) u.uhunger--; 318. 		if(Hunger) u.uhunger--; 319. 		/* a3:  if(Hunger & LEFT_RING) u.uhunger--; 320. 			if(Hunger & RIGHT_RING) u.uhunger--; 321. 		   etc. */ 322. 	}  323.  	if(moves % 20 == 0) {			/* jimt@asgb */ 324. 		if(uleft) u.uhunger--; 325. 		if(uright) u.uhunger--; 326. 	}  327.  	newuhs(TRUE); 328. }  329.   330.  /* called after vomiting and after performing feats of magic */ 331. morehungry(num) register num; { 332. 	u.uhunger -= num; 333. 	newuhs(TRUE); 334. }  335.   336.  /* called after eating something (and after drinking fruit juice) */ 337. lesshungry(num) register num; { 338. 	u.uhunger += num; 339. 	if(u.uhunger >= 2000) choke((struct objclass *) 0); 340. #ifdef DGKMOD 341. 	else { 342. 	    /* Have lesshungry report when you're nearly full so all eating 343. 	     * warns when you're about to choke. 344. 	     */  345.  	    if (u.uhunger >= 1500) { 346. 		pline("You're having a hard time getting all of it down."); 347. 		multi -= 2; 348. 		nomovemsg = "You're finally finished."; 349. 	    }  350.  	}  351.  #endif /* DGKMOD /**/ 352. 	newuhs(FALSE); 353. }  354.   355.  unfaint{ 356. 	u.uhs = FAINTING; 357. 	flags.botl = 1; 358. }  359.   360.  newuhs(incr) boolean incr; { 361. 	register int newhs, h = u.uhunger; 362.  363.  	newhs = (h > 1000) ? SATIATED : 364. 		(h > 150) ? NOT_HUNGRY : 365. 		(h > 50) ? HUNGRY : 366. 		(h > 0) ? WEAK : FAINTING; 367.  368.  	if(newhs == FAINTING) { 369. 		if(u.uhs == FAINTED) newhs = FAINTED; 370. 		if(u.uhs <= WEAK || rn2(20-u.uhunger/10) >= 19) { 371. 			if(u.uhs != FAINTED && multi >= 0 /* %% */) { 372. 				pline("You faint from lack of food."); 373. 				nomul(-10+(u.uhunger/10)); 374. 				nomovemsg = "You regain consciousness."; 375. 				afternmv = unfaint; 376. 				newhs = FAINTED; 377. 			}  378.  		} else 379. 		if(u.uhunger < -(int)(200 + 25*u.ulevel)) { 380. 			u.uhs = STARVED; 381. 			flags.botl = 1; 382. 			bot; 383. 			pline("You die from starvation."); 384. 			done("starved"); 385. 		}  386.  	}  387.   388.  	if(newhs != u.uhs) { 389. 		if(newhs >= WEAK && u.uhs < WEAK) 390. 			losestr(1);	/* this may kill you -- see below */ 391. 		else 392. 		if(newhs < WEAK && u.uhs >= WEAK && u.ustr < u.ustrmax) 393. 			losestr(-1); 394. 		switch(newhs){ 395. 		case HUNGRY: 396. 			if (Hallucination) { 397. 			    pline((!incr) ?  398.  				"You now have a lesser case of the munchies." :  399.  				"You are getting the munchies."); 400. 			} else 401. 			    pline((!incr) ? "You only feel hungry now." :  402.  				  (u.uhunger < 145) ? "You feel hungry." :  403.  				   "You are beginning to feel hungry."); 404. 			break; 405. 		case WEAK: 406. 			if (Hallucination) 407. 			    pline((!incr) ?  408.  				  "You still have the munchies." :  409.  				  "The munchies are starting to interfere with your motor capabilities."); 410. 			else 411. 			    pline((!incr) ? "You feel weak now." :  412.  				  (u.uhunger < 45) ? "You feel weak." :  413.  				   "You are beginning to feel weak."); 414. 			break; 415. 		}  416.  		u.uhs = newhs; 417. 		flags.botl = 1; 418. 		if(u.uhp < 1) { 419. 			pline("You die from hunger and exhaustion."); 420. 			killer = "exhaustion"; 421. 			done("starved"); 422. 		}  423.  	}  424.  }  425.   426.  #define	CORPSE_I_TO_C(otyp)	(char) ((otyp >= DEAD_ACID_BLOB)\  427.  		     ?  'a' + (otyp - DEAD_ACID_BLOB)\  428.  		     :	'@' + (otyp - DEAD_HUMAN)) 429. poisonous(otmp) 430. register struct obj *otmp; 431. {  432.  #ifdef KAA 433. 	if(otmp->otyp == DEAD_DEMON) return(1); 434. #endif 435. 	return(index(POISONOUS, CORPSE_I_TO_C(otmp->otyp)) != 0); 436. }  437.   438.  /* returns 1 if some text was printed */ 439. eatcorpse(otmp) register struct obj *otmp; { 440. #ifdef KAA 441. register char let; 442. #else 443. register char let = CORPSE_I_TO_C(otmp->otyp); 444. #endif 445. register tp = 0; 446. #ifdef KAA 447. 	if(otmp->otyp == DEAD_DEMON) let='&'; 448. 	else if (otmp->otyp == DEAD_GIANT) let='9'; 449. 	else let = CORPSE_I_TO_C(otmp->otyp); 450. #endif 451. #ifdef SAC 452. 	if(otmp->otyp == DEAD_SOLDIER) let='3'; 453. #endif /* SAC */ 454. 	if(let != 'a' && moves > otmp->age + 50 + rn2(100)) { 455. 		tp++; 456. 		pline("Ulch -- that meat was tainted!"); 457. 		pline("You get very sick."); 458. 		Sick = 10 + rn2(10); 459. 		u.usick_cause = objects[otmp->otyp].oc_name; 460. 	} else if(index(POISONOUS, let) && rn2(5)){ 461. 		tp++; 462. 		pline("Ecch -- that must have been poisonous!"); 463. 		if(!Poison_resistance){ 464. 			losestr(rnd(4)); 465. 			losehp(rnd(15), "poisonous corpse"); 466. 		} else 467. 			pline("You don't seem affected by the poison."); 468. 	} else if(index("ELNOPQRUuxz", let) && rn2(5)){ 469. 		tp++; 470. 		pline("You feel sick."); 471. 		losehp(rnd(8), "cadaver"); 472. 	}  473.  	switch(let) { 474. 	case 'L': 475. 	case 'N': 476. 	case 't': 477. #ifdef KAA 478. 	case 'Q': 479. #endif 480. 		HTeleportation |= INTRINSIC; 481. 		break; 482. 	case 'W': 483. 		pluslvl; 484. 		break; 485. 	case 'n': 486. 		u.uhp = u.uhpmax; 487. 		flags.botl = 1; 488. 		/* fall into next case */ 489. #ifdef SAC 490. 	case '3': 491. #endif 492. 	case '@': 493. 		pline("You cannibal! You will be sorry for this!"); 494. 		/* not tp++; */ 495. 		/* fall into next case */ 496. 	case 'd': 497. 		Aggravate_monster |= INTRINSIC; 498. 		break; 499. 	case 'I': 500. 		if(!Invis) { 501. 			HInvis = 50+rn2(100); 502. 			if(!See_invisible) 503. 				newsym(u.ux, u.uy); 504. 		} else { 505. 			HInvis |= INTRINSIC; 506. 			HSee_invisible |= INTRINSIC; 507. 		}  508.  		/* fall into next case */ 509. 	case 'y': 510. #ifdef QUEST 511. 		u.uhorizon++; 512. #endif 513. 		/* fall into next case */ 514. 	case 'B': 515. 		HConfusion += 50; 516. 		break; 517. 	case 'D': 518. 		HFire_resistance |= INTRINSIC; 519. 		break; 520. 	case 'E': 521. 		HTelepat |= INTRINSIC; 522. 		break; 523. 	case 'F': 524. 	case 'Y': 525. 		HCold_resistance |= INTRINSIC; 526. 		break; 527. #ifdef KAA 528. 	case '9': 529. 		gainstr(1); 530. 		break; 531. #endif 532. #ifdef KJSMODS 533. 	case 'S':	/* if a snake can kill you with poison, at least 534. 			 * have the possibility of getting resistance */ 535. 		if ( rn2(5) ) break; 536. 		/* fall into next case */ 537. #endif 538. 	case 'k': 539. 	case 's': 540. 		HPoison_resistance |= INTRINSIC; 541. 		break; 542. 	case 'c': 543. 		if (u.usym != 'c') { 544.  545.  			pline("You turn to stone."); 546. 			killer = "dead cockatrice"; 547. 			done("died"); 548. 		}  549.  		break; 550. 	case 'a': 551. 	  if(Stoned) { 552. 	      pline("What a pity - you just destroyed a future piece of art!"); 553. 	      tp++; 554. 	      Stoned = 0; 555. 	  }  556.  	  break; 557. #ifdef KAA 558. 	case 'v': 559. 		pline ("Oh wow!  Great stuff!"); 560. 		Hallucination += 200; 561. 		setsee; 562. 		break; 563. #endif 564. 	case 'M': 565. 		if(u.usym == '@') { 566. 		    pline("You cannot resist the temptation to mimic a treasure chest."); 567. 		    tp++; 568. 		    nomul(-30); 569. 		    afternmv = Meatdone; 570. 		    nomovemsg = "You now again prefer mimicking a human."; 571. 		    u.usym = GOLD_SYM; 572. 		    prme; 573. 		}  574.  		break; 575. 	}  576.  	return(tp); 577. }  578.   579.  /* Created by GAN 01/28/87 580.  * Amended by AKP 09/22/87: if not hard, don't choke, just vomit. 581.  *  582.   * Note that if you have enough food, you can always stop being Sick! 583.  * choke returns if you don't choke, kills you if you do. 584.  */  585.  choke(food) 586. register struct objclass *food; 587. {  588.  	/* only happens if you were satiated */ 589. 	if(u.uhs != SATIATED) return; 590. #ifdef HARD 591. 	if(food)	killer = food->oc_name; 592. 	else		killer = "exuberant appetite"; 593. 	pline("You choke over your food."); 594. 	pline("You die..."); 595. 	done("choked"); 596. #else 597. 	pline("You stuff yourself and then vomit voluminously."); 598. 	morehungry(1000);	/* you just got *very* sick! */ 599.  	if(Sick) { 600. 		Sick = 0;	/* A good idea from David Neves */ 601. 		pline("What a relief!"); 602. 	}  603.  #endif 604. }