Source:NetHack 3.1.0/eat.c
Jump to navigation
Jump to search
Below is the full text to eat.c from the source code of NetHack 3.1.0.
Warning! This is the source code from an old release. For newer releases, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
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*/