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