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