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