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