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: }