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