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