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