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