hack.eat.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. /* $NetBSD: hack.eat.c,v 1.6 2003/04/02 18:36:36 jsm Exp $ */
  2. /*
  3. * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
  4. * Amsterdam
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are
  9. * met:
  10. *
  11. * - Redistributions of source code must retain the above copyright notice,
  12. * this list of conditions and the following disclaimer.
  13. *
  14. * - Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. *
  18. * - Neither the name of the Stichting Centrum voor Wiskunde en
  19. * Informatica, nor the names of its contributors may be used to endorse or
  20. * promote products derived from this software without specific prior
  21. * written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  24. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  25. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  26. * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  27. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  28. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  29. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  30. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  31. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  32. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  33. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. /*
  36. * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
  37. * All rights reserved.
  38. *
  39. * Redistribution and use in source and binary forms, with or without
  40. * modification, are permitted provided that the following conditions
  41. * are met:
  42. * 1. Redistributions of source code must retain the above copyright
  43. * notice, this list of conditions and the following disclaimer.
  44. * 2. Redistributions in binary form must reproduce the above copyright
  45. * notice, this list of conditions and the following disclaimer in the
  46. * documentation and/or other materials provided with the distribution.
  47. * 3. The name of the author may not be used to endorse or promote products
  48. * derived from this software without specific prior written permission.
  49. *
  50. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  51. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  52. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  53. * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  54. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  55. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  56. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  57. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  58. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  59. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60. */
  61. #include <sys/cdefs.h>
  62. #ifndef lint
  63. __RCSID("$NetBSD: hack.eat.c,v 1.6 2003/04/02 18:36:36 jsm Exp $");
  64. #endif /* not lint */
  65. #include "hack.h"
  66. #include "extern.h"
  67. char POISONOUS[] = "ADKSVabhks";
  68. /* hunger texts used on bottom line (each 8 chars long) */
  69. #define SATIATED 0
  70. #define NOT_HUNGRY 1
  71. #define HUNGRY 2
  72. #define WEAK 3
  73. #define FAINTING 4
  74. #define FAINTED 5
  75. #define STARVED 6
  76. const char *const hu_stat[] = {
  77. "Satiated",
  78. " ",
  79. "Hungry ",
  80. "Weak ",
  81. "Fainting",
  82. "Fainted ",
  83. "Starved "
  84. };
  85. void
  86. init_uhunger()
  87. {
  88. u.uhunger = 900;
  89. u.uhs = NOT_HUNGRY;
  90. }
  91. #define TTSZ SIZE(tintxts)
  92. const struct {
  93. const char *txt;
  94. int nut;
  95. } tintxts[] = {
  96. { "It contains first quality peaches - what a surprise!", 40 },
  97. { "It contains salmon - not bad!", 60 },
  98. { "It contains apple juice - perhaps not what you hoped for.", 20 },
  99. { "It contains some nondescript substance, tasting awfully.", 500 },
  100. { "It contains rotten meat. You vomit.", -50 },
  101. { "It turns out to be empty.", 0 }
  102. };
  103. static struct {
  104. struct obj *tin;
  105. int usedtime, reqtime;
  106. } tin;
  107. int
  108. opentin()
  109. {
  110. int r;
  111. if (!carried(tin.tin)) /* perhaps it was stolen? */
  112. return (0); /* %% probably we should use tinoid */
  113. if (tin.usedtime++ >= 50) {
  114. pline("You give up your attempt to open the tin.");
  115. return (0);
  116. }
  117. if (tin.usedtime < tin.reqtime)
  118. return (1); /* still busy */
  119. pline("You succeed in opening the tin.");
  120. useup(tin.tin);
  121. r = rn2(2 * TTSZ);
  122. if (r < TTSZ) {
  123. pline(tintxts[r].txt);
  124. lesshungry(tintxts[r].nut);
  125. if (r == 1) { /* SALMON */
  126. Glib = rnd(15);
  127. pline("Eating salmon made your fingers very slippery.");
  128. }
  129. } else {
  130. pline("It contains spinach - this makes you feel like Popeye!");
  131. lesshungry(600);
  132. if (u.ustr < 118)
  133. u.ustr += rnd(((u.ustr < 17) ? 19 : 118) - u.ustr);
  134. if (u.ustr > u.ustrmax)
  135. u.ustrmax = u.ustr;
  136. flags.botl = 1;
  137. }
  138. return (0);
  139. }
  140. int
  141. Meatdone()
  142. {
  143. u.usym = '@';
  144. prme();
  145. return 0;
  146. }
  147. int
  148. doeat()
  149. {
  150. struct obj *otmp;
  151. struct objclass *ftmp;
  152. int tmp;
  153. /* Is there some food (probably a heavy corpse) here on the ground? */
  154. if (!Levitation)
  155. for (otmp = fobj; otmp; otmp = otmp->nobj) {
  156. if (otmp->ox == u.ux && otmp->oy == u.uy &&
  157. otmp->olet == FOOD_SYM) {
  158. pline("There %s %s here; eat %s? [ny] ",
  159. (otmp->quan == 1) ? "is" : "are",
  160. doname(otmp),
  161. (otmp->quan == 1) ? "it" : "one");
  162. if (readchar() == 'y') {
  163. if (otmp->quan != 1)
  164. (void) splitobj(otmp, 1);
  165. freeobj(otmp);
  166. otmp = addinv(otmp);
  167. addtobill(otmp);
  168. goto gotit;
  169. }
  170. }
  171. }
  172. otmp = getobj("%", "eat");
  173. if (!otmp)
  174. return (0);
  175. gotit:
  176. if (otmp->otyp == TIN) {
  177. if (uwep) {
  178. switch (uwep->otyp) {
  179. case CAN_OPENER:
  180. tmp = 1;
  181. break;
  182. case DAGGER:
  183. case CRYSKNIFE:
  184. tmp = 3;
  185. break;
  186. case PICK_AXE:
  187. case AXE:
  188. tmp = 6;
  189. break;
  190. default:
  191. goto no_opener;
  192. }
  193. pline("Using your %s you try to open the tin.",
  194. aobjnam(uwep, (char *) 0));
  195. } else {
  196. no_opener:
  197. pline("It is not so easy to open this tin.");
  198. if (Glib) {
  199. pline("The tin slips out of your hands.");
  200. if (otmp->quan > 1) {
  201. struct obj *obj;
  202. obj = splitobj(otmp, 1);
  203. if (otmp == uwep)
  204. setuwep(obj);
  205. }
  206. dropx(otmp);
  207. return (1);
  208. }
  209. tmp = 10 + rn2(1 + 500 / ((int) (u.ulevel + u.ustr)));
  210. }
  211. tin.reqtime = tmp;
  212. tin.usedtime = 0;
  213. tin.tin = otmp;
  214. occupation = opentin;
  215. occtxt = "opening the tin";
  216. return (1);
  217. }
  218. ftmp = &objects[otmp->otyp];
  219. multi = -ftmp->oc_delay;
  220. if (otmp->otyp >= CORPSE && eatcorpse(otmp))
  221. goto eatx;
  222. if (!rn2(7) && otmp->otyp != FORTUNE_COOKIE) {
  223. pline("Blecch! Rotten food!");
  224. if (!rn2(4)) {
  225. pline("You feel rather light headed.");
  226. Confusion += d(2, 4);
  227. } else if (!rn2(4) && !Blind) {
  228. pline("Everything suddenly goes dark.");
  229. Blind = d(2, 10);
  230. seeoff(0);
  231. } else if (!rn2(3)) {
  232. if (Blind)
  233. pline("The world spins and you slap against the floor.");
  234. else
  235. pline("The world spins and goes dark.");
  236. nomul(-rnd(10));
  237. nomovemsg = "You are conscious again.";
  238. }
  239. lesshungry(ftmp->nutrition / 4);
  240. } else {
  241. if (u.uhunger >= 1500) {
  242. pline("You choke over your food.");
  243. pline("You die...");
  244. killer = ftmp->oc_name;
  245. done("choked");
  246. }
  247. switch (otmp->otyp) {
  248. case FOOD_RATION:
  249. if (u.uhunger <= 200)
  250. pline("That food really hit the spot!");
  251. else if (u.uhunger <= 700)
  252. pline("That satiated your stomach!");
  253. else {
  254. pline("You're having a hard time getting all that food down.");
  255. multi -= 2;
  256. }
  257. lesshungry(ftmp->nutrition);
  258. if (multi < 0)
  259. nomovemsg = "You finished your meal.";
  260. break;
  261. case TRIPE_RATION:
  262. pline("Yak - dog food!");
  263. more_experienced(1, 0);
  264. flags.botl = 1;
  265. if (rn2(2)) {
  266. pline("You vomit.");
  267. morehungry(20);
  268. if (Sick) {
  269. Sick = 0; /* David Neves */
  270. pline("What a relief!");
  271. }
  272. } else
  273. lesshungry(ftmp->nutrition);
  274. break;
  275. default:
  276. if (otmp->otyp >= CORPSE)
  277. pline("That %s tasted terrible!", ftmp->oc_name);
  278. else
  279. pline("That %s was delicious!", ftmp->oc_name);
  280. lesshungry(ftmp->nutrition);
  281. if (otmp->otyp == DEAD_LIZARD && (Confusion > 2))
  282. Confusion = 2;
  283. else
  284. #ifdef QUEST
  285. if (otmp->otyp == CARROT && !Blind) {
  286. u.uhorizon++;
  287. setsee();
  288. pline("Your vision improves.");
  289. } else
  290. #endif /* QUEST */
  291. if (otmp->otyp == FORTUNE_COOKIE) {
  292. if (Blind) {
  293. pline("This cookie has a scrap of paper inside!");
  294. pline("What a pity, that you cannot read it!");
  295. } else
  296. outrumor();
  297. } else if (otmp->otyp == LUMP_OF_ROYAL_JELLY) {
  298. /* This stuff seems to be VERY healthy! */
  299. if (u.ustrmax < 118)
  300. u.ustrmax++;
  301. if (u.ustr < u.ustrmax)
  302. u.ustr++;
  303. u.uhp += rnd(20);
  304. if (u.uhp > u.uhpmax) {
  305. if (!rn2(17))
  306. u.uhpmax++;
  307. u.uhp = u.uhpmax;
  308. }
  309. heal_legs();
  310. }
  311. break;
  312. }
  313. }
  314. eatx:
  315. if (multi < 0 && !nomovemsg) {
  316. static char msgbuf[BUFSZ];
  317. (void) sprintf(msgbuf, "You finished eating the %s.",
  318. ftmp->oc_name);
  319. nomovemsg = msgbuf;
  320. }
  321. useup(otmp);
  322. return (1);
  323. }
  324. /* called in hack.main.c */
  325. void
  326. gethungry()
  327. {
  328. --u.uhunger;
  329. if (moves % 2) {
  330. if (Regeneration)
  331. u.uhunger--;
  332. if (Hunger)
  333. u.uhunger--;
  334. /*
  335. * a3: if(Hunger & LEFT_RING) u.uhunger--; if(Hunger &
  336. * RIGHT_RING) u.uhunger--; etc.
  337. */
  338. }
  339. if (moves % 20 == 0) { /* jimt@asgb */
  340. if (uleft)
  341. u.uhunger--;
  342. if (uright)
  343. u.uhunger--;
  344. }
  345. newuhs(TRUE);
  346. }
  347. /* called after vomiting and after performing feats of magic */
  348. void
  349. morehungry(num)
  350. int num;
  351. {
  352. u.uhunger -= num;
  353. newuhs(TRUE);
  354. }
  355. /* called after eating something (and after drinking fruit juice) */
  356. void
  357. lesshungry(num)
  358. int num;
  359. {
  360. u.uhunger += num;
  361. newuhs(FALSE);
  362. }
  363. int
  364. unfaint()
  365. {
  366. u.uhs = FAINTING;
  367. flags.botl = 1;
  368. return 0;
  369. }
  370. void
  371. newuhs(incr)
  372. boolean incr;
  373. {
  374. int newhs, h = u.uhunger;
  375. newhs = (h > 1000) ? SATIATED :
  376. (h > 150) ? NOT_HUNGRY :
  377. (h > 50) ? HUNGRY :
  378. (h > 0) ? WEAK : FAINTING;
  379. if (newhs == FAINTING) {
  380. if (u.uhs == FAINTED)
  381. newhs = FAINTED;
  382. if (u.uhs <= WEAK || rn2(20 - u.uhunger / 10) >= 19) {
  383. if (u.uhs != FAINTED && multi >= 0 /* %% */ ) {
  384. pline("You faint from lack of food.");
  385. nomul(-10 + (u.uhunger / 10));
  386. nomovemsg = "You regain consciousness.";
  387. afternmv = unfaint;
  388. newhs = FAINTED;
  389. }
  390. } else if (u.uhunger < -(int) (200 + 25 * u.ulevel)) {
  391. u.uhs = STARVED;
  392. flags.botl = 1;
  393. bot();
  394. pline("You die from starvation.");
  395. done("starved");
  396. }
  397. }
  398. if (newhs != u.uhs) {
  399. if (newhs >= WEAK && u.uhs < WEAK)
  400. losestr(1); /* this may kill you -- see below */
  401. else if (newhs < WEAK && u.uhs >= WEAK && u.ustr < u.ustrmax)
  402. losestr(-1);
  403. switch (newhs) {
  404. case HUNGRY:
  405. pline((!incr) ? "You only feel hungry now." :
  406. (u.uhunger < 145) ? "You feel hungry." :
  407. "You are beginning to feel hungry.");
  408. break;
  409. case WEAK:
  410. pline((!incr) ? "You feel weak now." :
  411. (u.uhunger < 45) ? "You feel weak." :
  412. "You are beginning to feel weak.");
  413. break;
  414. }
  415. u.uhs = newhs;
  416. flags.botl = 1;
  417. if (u.uhp < 1) {
  418. pline("You die from hunger and exhaustion.");
  419. killer = "exhaustion";
  420. done("starved");
  421. }
  422. }
  423. }
  424. #define CORPSE_I_TO_C(otyp) (char) ((otyp >= DEAD_ACID_BLOB)\
  425. ? 'a' + (otyp - DEAD_ACID_BLOB)\
  426. : '@' + (otyp - DEAD_HUMAN))
  427. int
  428. poisonous(otmp)
  429. struct obj *otmp;
  430. {
  431. return (strchr(POISONOUS, CORPSE_I_TO_C(otmp->otyp)) != 0);
  432. }
  433. /* returns 1 if some text was printed */
  434. int
  435. eatcorpse(otmp)
  436. struct obj *otmp;
  437. {
  438. char let = CORPSE_I_TO_C(otmp->otyp);
  439. int tp = 0;
  440. if (let != 'a' && moves > otmp->age + 50 + rn2(100)) {
  441. tp++;
  442. pline("Ulch -- that meat was tainted!");
  443. pline("You get very sick.");
  444. Sick = 10 + rn2(10);
  445. u.usick_cause = objects[otmp->otyp].oc_name;
  446. } else if (strchr(POISONOUS, let) && rn2(5)) {
  447. tp++;
  448. pline("Ecch -- that must have been poisonous!");
  449. if (!Poison_resistance) {
  450. losestr(rnd(4));
  451. losehp(rnd(15), "poisonous corpse");
  452. } else
  453. pline("You don't seem affected by the poison.");
  454. } else if (strchr("ELNOPQRUuxz", let) && rn2(5)) {
  455. tp++;
  456. pline("You feel sick.");
  457. losehp(rnd(8), "cadaver");
  458. }
  459. switch (let) {
  460. case 'L':
  461. case 'N':
  462. case 't':
  463. Teleportation |= INTRINSIC;
  464. break;
  465. case 'W':
  466. pluslvl();
  467. break;
  468. case 'n':
  469. u.uhp = u.uhpmax;
  470. flags.botl = 1;
  471. /* fall into next case */
  472. case '@':
  473. pline("You cannibal! You will be sorry for this!");
  474. /* not tp++; */
  475. /* fall into next case */
  476. case 'd':
  477. Aggravate_monster |= INTRINSIC;
  478. break;
  479. case 'I':
  480. if (!Invis) {
  481. Invis = 50 + rn2(100);
  482. if (!See_invisible)
  483. newsym(u.ux, u.uy);
  484. } else {
  485. Invis |= INTRINSIC;
  486. See_invisible |= INTRINSIC;
  487. }
  488. /* fall into next case */
  489. case 'y':
  490. #ifdef QUEST
  491. u.uhorizon++;
  492. #endif /* QUEST */
  493. /* fall into next case */
  494. case 'B':
  495. Confusion = 50;
  496. break;
  497. case 'D':
  498. Fire_resistance |= INTRINSIC;
  499. break;
  500. case 'E':
  501. Telepat |= INTRINSIC;
  502. break;
  503. case 'F':
  504. case 'Y':
  505. Cold_resistance |= INTRINSIC;
  506. break;
  507. case 'k':
  508. case 's':
  509. Poison_resistance |= INTRINSIC;
  510. break;
  511. case 'c':
  512. pline("You turn to stone.");
  513. killer = "dead cockatrice";
  514. done("died");
  515. /* NOTREACHED */
  516. case 'a':
  517. if (Stoned) {
  518. pline("What a pity - you just destroyed a future piece of art!");
  519. tp++;
  520. Stoned = 0;
  521. }
  522. break;
  523. case 'M':
  524. pline("You cannot resist the temptation to mimic a treasure chest.");
  525. tp++;
  526. nomul(-30);
  527. afternmv = Meatdone;
  528. nomovemsg = "You now again prefer mimicking a human.";
  529. u.usym = '$';
  530. prme();
  531. break;
  532. }
  533. return (tp);
  534. }