About: Source:NetHack 3.1.0/eat.c   Sponge Permalink

An Entity of Type : owl:Thing, within Data Space : 134.155.108.49:8890 associated with source dataset(s)

Below is the full text to eat.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/eat.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code

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