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