|
|
1.1 root 1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2: /* hack.eat.c - version 1.0.3 */
3:
4: #include "hack.h"
5: char POISONOUS[] = "ADKSVabhks";
6: extern char *nomovemsg;
7: extern int (*afternmv)();
8: extern int (*occupation)();
9: extern char *occtxt;
10: extern 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:
21: char *hu_stat[] = {
22: "Satiated",
23: " ",
24: "Hungry ",
25: "Weak ",
26: "Fainting",
27: "Fainted ",
28: "Starved "
29: };
30:
31: init_uhunger(){
32: u.uhunger = 900;
33: u.uhs = NOT_HUNGRY;
34: }
35:
36: #define TTSZ SIZE(tintxts)
37: struct { 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:
46: static struct {
47: struct obj *tin;
48: int usedtime, reqtime;
49: } tin;
50:
51: opentin(){
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:
84: Meatdone(){
85: u.usym = '@';
86: prme();
87: }
88:
89: doeat(){
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);
115: gotit:
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: }
250: eatx:
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 */
262: gethungry(){
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 */
279: morehungry(num) register num; {
280: u.uhunger -= num;
281: newuhs(TRUE);
282: }
283:
284: /* called after eating something (and after drinking fruit juice) */
285: lesshungry(num) register num; {
286: u.uhunger += num;
287: newuhs(FALSE);
288: }
289:
290: unfaint(){
291: u.uhs = FAINTING;
292: flags.botl = 1;
293: }
294:
295: newuhs(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))
355: poisonous(otmp)
356: register 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 */
362: eatcorpse(otmp) register struct obj *otmp; {
363: register char let = CORPSE_I_TO_C(otmp->otyp);
364: register 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.