1/* $NetBSD: command4.c,v 1.4 2021/05/02 12:50:43 rillig Exp $ */ 2 3/* 4 * Copyright (c) 1983, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33#ifndef lint 34#if 0 35static char sccsid[] = "@(#)com4.c 8.2 (Berkeley) 4/28/95"; 36#else 37__RCSID("$NetBSD: command4.c,v 1.4 2021/05/02 12:50:43 rillig Exp $"); 38#endif 39#endif /* not lint */ 40 41#include "extern.h" 42 43int 44take(unsigned int from[]) 45{ 46 int firstnumber, heavy, bulky, value; 47 48 firstnumber = wordnumber; 49 if (wordnumber < wordcount && wordvalue[wordnumber + 1] == OFF) { 50 wordnumber++; 51 wordvalue[wordnumber] = TAKEOFF; 52 wordtype[wordnumber] = VERB; 53 return (cypher()); 54 } else { 55 wordnumber++; 56 while (wordnumber <= wordcount && wordtype[wordnumber] == 57 OBJECT) { 58 value = wordvalue[wordnumber]; 59 printf("%s:\n", objsht[value]); 60 heavy = (carrying + objwt[value]) <= WEIGHT; 61 bulky = (encumber + objcumber[value]) <= CUMBER; 62 if ((testbit(from, value) || wiz || tempwiz) && 63 heavy && bulky && !testbit(inven, value)) { 64 setbit(inven, value); 65 carrying += objwt[value]; 66 encumber += objcumber[value]; 67 ourtime++; 68 if (testbit(from, value)) 69 printf("Taken.\n"); 70 else 71 printf("Zap! Taken from thin air.\n"); 72 clearbit(from, value); 73 if (value == MEDALION) 74 win--; 75 } else if (testbit(inven, value)) 76 printf("You're already holding %s%s.\n", 77 A_OR_AN_OR_BLANK(value), 78 objsht[value]); 79 else if (!testbit(from, value)) 80 printf("I don't see any %s around here.\n", 81 objsht[value]); 82 else if (!heavy) 83 printf("The %s %stoo heavy.\n", objsht[value], 84 IS_OR_ARE(value)); 85 else 86 printf("The %s %stoo cumbersome to hold.\n", 87 objsht[value], IS_OR_ARE(value)); 88 if (wordnumber < wordcount - 1 && 89 wordvalue[++wordnumber] == AND) 90 wordnumber++; 91 else 92 return (firstnumber); 93 } 94 } 95 /* special cases with their own return()'s */ 96 97 if (wordnumber <= wordcount && wordtype[wordnumber] == NOUNS) 98 switch (wordvalue[wordnumber]) { 99 100 case SWORD: 101 if (testbit(from, SWORD)) { 102 wordtype[wordnumber--] = OBJECT; 103 return (take(from)); 104 } 105 if (testbit(from, TWO_HANDED)) { 106 wordvalue[wordnumber] = TWO_HANDED; 107 wordtype[wordnumber--] = OBJECT; 108 return (take(from)); 109 } 110 wordvalue[wordnumber] = BROAD; 111 wordtype[wordnumber--] = OBJECT; 112 return (take(from)); 113 114 case BODY: 115 if (testbit(from, MAID)) { 116 wordvalue[wordnumber] = MAID; 117 wordtype[wordnumber--] = OBJECT; 118 return (take(from)); 119 } else if (testbit(from, DEADWOOD)) { 120 wordvalue[wordnumber] = DEADWOOD; 121 wordtype[wordnumber--] = OBJECT; 122 return (take(from)); 123 } else if (testbit(from, DEADNATIVE)) { 124 wordvalue[wordnumber] = DEADNATIVE; 125 wordtype[wordnumber--] = OBJECT; 126 return (take(from)); 127 } else { 128 if (testbit(from, DEADGOD)) { 129 wordvalue[wordnumber] = DEADGOD; 130 wordtype[wordnumber--] = OBJECT; 131 return (take(from)); 132 } else { 133 wordvalue[wordnumber] = DEADTIME; 134 wordtype[wordnumber--] = OBJECT; 135 return (take(from)); 136 } 137 } 138 break; 139 140 case AMULET: 141 if (testbit(location[position].objects, AMULET)) { 142 printf("The amulet is warm to the touch, and "); 143 puts("its beauty catches your breath."); 144 printf("A mist falls over your eyes, but "); 145 puts("then it is gone. Sounds seem clearer"); 146 printf("and sharper but far away as if in a "); 147 puts("dream. The sound of purling water"); 148 printf("reaches you from afar. The mist "); 149 printf("falls again, and your heart leaps in "); 150 puts("horror."); 151 printf("The gold freezes your hands and "); 152 puts("fathomless darkness engulfs your soul."); 153 } 154 wordtype[wordnumber--] = OBJECT; 155 return (take(from)); 156 157 case MEDALION: 158 if (testbit(location[position].objects, MEDALION)) { 159 printf("The medallion is warm, and it "); 160 printf("rekindles your spirit with the "); 161 puts("warmth of life."); 162 printf("Your amulet begins to glow as the "); 163 printf("medallion is brought near to it, "); 164 printf("and together\nthey radiate.\n"); 165 } 166 wordtype[wordnumber--] = OBJECT; 167 return (take(from)); 168 169 case TALISMAN: 170 if (testbit(location[position].objects, TALISMAN)) { 171 printf("The talisman is cold to the touch, "); 172 puts("and it sends a chill down your spine."); 173 } 174 wordtype[wordnumber--] = OBJECT; 175 return (take(from)); 176 177 case NORMGOD: 178 if (testbit(location[position].objects, BATHGOD) && 179 (testbit(wear, AMULET) || testbit(inven, AMULET))) { 180 printf("She offers a delicate hand, and you "); 181 puts("help her out of the sparkling springs."); 182 printf("Water droplets like liquid silver "); 183 printf("bedew her golden skin, but when "); 184 puts("they part"); 185 printf("from her, they fall as teardrops. "); 186 puts("She wraps a single cloth around her and"); 187 printf("ties it at the waist. Around her "); 188 puts("neck hangs a golden amulet."); 189 printf("She bids you to follow her, and "); 190 puts("walks away."); 191 pleasure++; 192 followgod = ourtime; 193 clearbit(location[position].objects, BATHGOD); 194 } else 195 if (!testbit(location[position].objects, 196 BATHGOD)) { 197 printf("You're in no position to "); 198 puts("take her."); 199 } else 200 puts("She moves away from you."); 201 break; 202 203 default: 204 puts("It doesn't seem to work."); 205 } 206 else 207 puts("You've got to be kidding."); 208 return (firstnumber); 209} 210 211int 212throw(const char *name) 213{ 214 unsigned int n; 215 int deposit = 0; 216 int first, value; 217 218 first = wordnumber; 219 if (drop(name) != -1) { 220 switch (wordvalue[wordnumber]) { 221 222 case AHEAD: 223 deposit = ahead; 224 break; 225 226 case BACK: 227 deposit = back; 228 break; 229 230 case LEFT: 231 deposit = left; 232 break; 233 234 case RIGHT: 235 deposit = right; 236 break; 237 238 case UP: 239 deposit = location[position].up * 240 (location[position].access || position == FINAL); 241 break; 242 243 case DOWN: 244 deposit = location[position].down; 245 break; 246 } 247 wordnumber = first + 1; 248 while (wordnumber <= wordcount) { 249 value = wordvalue[wordnumber]; 250 if (deposit && 251 testbit(location[position].objects, value)) { 252 clearbit(location[position].objects, value); 253 if (value != GRENADE) 254 setbit(location[deposit].objects, 255 value); 256 else { 257 printf("A thundering explosion "); 258 printf("nearby sends up a cloud of "); 259 puts("smoke and shrapnel."); 260 for (n = 0; n < NUMOFWORDS; n++) 261 location[deposit].objects[n] = 262 0; 263 setbit(location[deposit].objects, CHAR); 264 } 265 if (value == ROPE && position == FINAL) 266 location[position].access = 1; 267 switch (deposit) { 268 case 189: 269 case 231: 270 puts("The stone door is unhinged."); 271 location[189].north = 231; 272 location[231].south = 189; 273 break; 274 case 30: 275 puts("The wooden door is blown open."); 276 location[30].west = 25; 277 break; 278 case 31: 279 puts("The door is not damaged."); 280 } 281 } else 282 if (value == GRENADE && 283 testbit(location[position].objects, 284 value)) { 285 printf("You are blown into shreds "); 286 puts("when your grenade explodes."); 287 die(); 288 } 289 if (wordnumber < wordcount - 1 && 290 wordvalue[++wordnumber] == AND) 291 wordnumber++; 292 else 293 return (first); 294 } 295 return (first); 296 } 297 return (first); 298} 299 300int 301drop(const char *name) 302{ 303 304 int firstnumber, value; 305 306 firstnumber = wordnumber; 307 wordnumber++; 308 while (wordnumber <= wordcount && 309 (wordtype[wordnumber] == OBJECT || wordtype[wordnumber] == NOUNS)) { 310 value = wordvalue[wordnumber]; 311 if (value == BODY) { /* special case */ 312 wordtype[wordnumber] = OBJECT; 313 if (testbit(inven, MAID) || 314 testbit(location[position].objects, MAID)) 315 value = MAID; 316 else if (testbit(inven, DEADWOOD) || 317 testbit(location[position].objects, DEADWOOD)) 318 value = DEADWOOD; 319 else if (testbit(inven, DEADGOD) || 320 testbit(location[position].objects, DEADGOD)) 321 value = DEADGOD; 322 else if (testbit(inven, DEADTIME) || 323 testbit(location[position].objects, DEADTIME)) 324 value = DEADTIME; 325 else if (testbit(inven, DEADNATIVE) || 326 testbit(location[position].objects, DEADNATIVE)) 327 value = DEADNATIVE; 328 } 329 if (wordtype[wordnumber] == NOUNS && value == DOOR) { 330 if (*name == 'K') 331 puts("You hurt your foot."); 332 else 333 puts("You're not holding a door."); 334 } else if (objsht[value] == NULL) { 335 if (*name == 'K') 336 puts("That's not for kicking!"); 337 else 338 puts("You don't have that."); 339 } else { 340 printf("%s:\n", objsht[value]); 341 if (testbit(inven, value)) { 342 clearbit(inven, value); 343 carrying -= objwt[value]; 344 encumber -= objcumber[value]; 345 if (value == BOMB) { 346 printf("The bomb explodes. A "); 347 printf("blinding white light and "); 348 printf("immense concussion "); 349 puts("obliterate us."); 350 die(); 351 } 352 if (value != AMULET && value != MEDALION && 353 value != TALISMAN) 354 setbit(location[position].objects, 355 value); 356 else 357 tempwiz = 0; 358 ourtime++; 359 if (*name == 'K') 360 puts("Drop kicked."); 361 else 362 printf("%s.\n", name); 363 } else { 364 if (*name != 'K') { 365 printf("You aren't holding the %s.\n", 366 objsht[value]); 367 if (testbit(location[position].objects, 368 value)) { 369 if (*name == 'T') 370 puts("Kicked instead."); 371 else if (*name == 'G') 372 puts("Given anyway."); 373 } 374 } else if (testbit(location[position].objects, 375 value)) 376 puts("Kicked."); 377 else if (testbit(wear, value)) 378 puts("Not while it's being worn."); 379 else 380 puts("Not found."); 381 } 382 } 383 if (wordnumber < wordcount - 1 && 384 wordvalue[++wordnumber] == AND) 385 wordnumber++; 386 else 387 return (firstnumber); 388 } 389 puts("Do what?"); 390 return (-1); 391} 392 393int 394takeoff(void) 395{ 396 wordnumber = take(wear); 397 return (drop("Dropped")); 398} 399 400int 401puton(void) 402{ 403 wordnumber = take(location[position].objects); 404 return (wearit()); 405} 406 407int 408eat(void) 409{ 410 int firstnumber, value; 411 412 firstnumber = wordnumber; 413 wordnumber++; 414 while (wordnumber <= wordcount) { 415 value = wordvalue[wordnumber]; 416 if (wordtype[wordnumber] != OBJECT || objsht[value] == NULL) 417 value = -2; 418 switch (value) { 419 420 case -2: 421 puts("You can't eat that!"); 422 return (firstnumber); 423 424 case -1: 425 puts("Eat what?"); 426 return (firstnumber); 427 428 default: 429 printf("You can't eat %s%s!\n", 430 A_OR_AN_OR_BLANK(value), objsht[value]); 431 return (firstnumber); 432 433 case PAPAYAS: 434 case PINEAPPLE: 435 case KIWI: 436 case COCONUTS: /* eatable things */ 437 case MANGO: 438 439 printf("%s:\n", objsht[value]); 440 if (testbit(inven, value) && 441 ourtime > ate - CYCLE && 442 testbit(inven, KNIFE)) { 443 clearbit(inven, value); 444 carrying -= objwt[value]; 445 encumber -= objcumber[value]; 446 ate = max(ourtime, ate) + CYCLE / 3; 447 snooze += CYCLE / 10; 448 ourtime++; 449 printf("Eaten. You can explore a little "); 450 puts("longer now."); 451 } else if (!testbit(inven, value)) { 452 printf("You aren't holding the %s.\n", 453 objsht[value]); 454 } else if (!testbit(inven, KNIFE)) 455 puts("You need a knife."); 456 else 457 puts("You're stuffed."); 458 if (wordnumber < wordcount - 1 && 459 wordvalue[++wordnumber] == AND) 460 wordnumber++; 461 else 462 return (firstnumber); 463 } /* end switch */ 464 } /* end while */ 465 return (firstnumber); 466} 467