|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Timothy C. Stoehr. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted ! 9: * provided that: (1) source distributions retain this entire copyright ! 10: * notice and comment, and (2) distributions including binaries display ! 11: * the following acknowledgement: ``This product includes software ! 12: * developed by the University of California, Berkeley and its contributors'' ! 13: * in the documentation or other materials provided with the distribution ! 14: * and in all advertising materials mentioning features or use of this ! 15: * software. Neither the name of the University nor the names of its ! 16: * contributors may be used to endorse or promote products derived ! 17: * from this software without specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: static char sccsid[] = "@(#)pack.c 5.3 (Berkeley) 6/1/90"; ! 25: #endif /* not lint */ ! 26: ! 27: /* ! 28: * pack.c ! 29: * ! 30: * This source herein may be modified and/or distributed by anybody who ! 31: * so desires, with the following restrictions: ! 32: * 1.) No portion of this notice shall be removed. ! 33: * 2.) Credit shall not be taken for the creation of this source. ! 34: * 3.) This code is not to be traded, sold, or used for personal ! 35: * gain or profit. ! 36: * ! 37: */ ! 38: ! 39: #include "rogue.h" ! 40: ! 41: char *curse_message = "you can't, it appears to be cursed"; ! 42: ! 43: extern short levitate; ! 44: ! 45: object * ! 46: add_to_pack(obj, pack, condense) ! 47: object *obj, *pack; ! 48: { ! 49: object *op; ! 50: ! 51: if (condense) { ! 52: if (op = check_duplicate(obj, pack)) { ! 53: free_object(obj); ! 54: return(op); ! 55: } else { ! 56: obj->ichar = next_avail_ichar(); ! 57: } ! 58: } ! 59: if (pack->next_object == 0) { ! 60: pack->next_object = obj; ! 61: } else { ! 62: op = pack->next_object; ! 63: ! 64: while (op->next_object) { ! 65: op = op->next_object; ! 66: } ! 67: op->next_object = obj; ! 68: } ! 69: obj->next_object = 0; ! 70: return(obj); ! 71: } ! 72: ! 73: take_from_pack(obj, pack) ! 74: object *obj, *pack; ! 75: { ! 76: while (pack->next_object != obj) { ! 77: pack = pack->next_object; ! 78: } ! 79: pack->next_object = pack->next_object->next_object; ! 80: } ! 81: ! 82: /* Note: *status is set to 0 if the rogue attempts to pick up a scroll ! 83: * of scare-monster and it turns to dust. *status is otherwise set to 1. ! 84: */ ! 85: ! 86: object * ! 87: pick_up(row, col, status) ! 88: short *status; ! 89: { ! 90: object *obj; ! 91: ! 92: *status = 1; ! 93: ! 94: if (levitate) { ! 95: message("you're floating in the air!", 0); ! 96: return((object *) 0); ! 97: } ! 98: obj = object_at(&level_objects, row, col); ! 99: if (!obj) { ! 100: message("pick_up(): inconsistent", 1); ! 101: return(obj); ! 102: } ! 103: if ( (obj->what_is == SCROL) && ! 104: (obj->which_kind == SCARE_MONSTER) && ! 105: obj->picked_up) { ! 106: message("the scroll turns to dust as you pick it up", 0); ! 107: dungeon[row][col] &= (~OBJECT); ! 108: vanish(obj, 0, &level_objects); ! 109: *status = 0; ! 110: if (id_scrolls[SCARE_MONSTER].id_status == UNIDENTIFIED) { ! 111: id_scrolls[SCARE_MONSTER].id_status = IDENTIFIED; ! 112: } ! 113: return((object *) 0); ! 114: } ! 115: if (obj->what_is == GOLD) { ! 116: rogue.gold += obj->quantity; ! 117: dungeon[row][col] &= ~(OBJECT); ! 118: take_from_pack(obj, &level_objects); ! 119: print_stats(STAT_GOLD); ! 120: return(obj); /* obj will be free_object()ed in caller */ ! 121: } ! 122: if (pack_count(obj) >= MAX_PACK_COUNT) { ! 123: message("pack too full", 1); ! 124: return((object *) 0); ! 125: } ! 126: dungeon[row][col] &= ~(OBJECT); ! 127: take_from_pack(obj, &level_objects); ! 128: obj = add_to_pack(obj, &rogue.pack, 1); ! 129: obj->picked_up = 1; ! 130: return(obj); ! 131: } ! 132: ! 133: drop() ! 134: { ! 135: object *obj, *new; ! 136: short ch; ! 137: char desc[DCOLS]; ! 138: ! 139: if (dungeon[rogue.row][rogue.col] & (OBJECT | STAIRS | TRAP)) { ! 140: message("there's already something there", 0); ! 141: return; ! 142: } ! 143: if (!rogue.pack.next_object) { ! 144: message("you have nothing to drop", 0); ! 145: return; ! 146: } ! 147: if ((ch = pack_letter("drop what?", ALL_OBJECTS)) == CANCEL) { ! 148: return; ! 149: } ! 150: if (!(obj = get_letter_object(ch))) { ! 151: message("no such item.", 0); ! 152: return; ! 153: } ! 154: if (obj->in_use_flags & BEING_WIELDED) { ! 155: if (obj->is_cursed) { ! 156: message(curse_message, 0); ! 157: return; ! 158: } ! 159: unwield(rogue.weapon); ! 160: } else if (obj->in_use_flags & BEING_WORN) { ! 161: if (obj->is_cursed) { ! 162: message(curse_message, 0); ! 163: return; ! 164: } ! 165: mv_aquatars(); ! 166: unwear(rogue.armor); ! 167: print_stats(STAT_ARMOR); ! 168: } else if (obj->in_use_flags & ON_EITHER_HAND) { ! 169: if (obj->is_cursed) { ! 170: message(curse_message, 0); ! 171: return; ! 172: } ! 173: un_put_on(obj); ! 174: } ! 175: obj->row = rogue.row; ! 176: obj->col = rogue.col; ! 177: ! 178: if ((obj->quantity > 1) && (obj->what_is != WEAPON)) { ! 179: obj->quantity--; ! 180: new = alloc_object(); ! 181: *new = *obj; ! 182: new->quantity = 1; ! 183: obj = new; ! 184: } else { ! 185: obj->ichar = 'L'; ! 186: take_from_pack(obj, &rogue.pack); ! 187: } ! 188: place_at(obj, rogue.row, rogue.col); ! 189: (void) strcpy(desc, "dropped "); ! 190: get_desc(obj, desc+8); ! 191: message(desc, 0); ! 192: (void) reg_move(); ! 193: } ! 194: ! 195: object * ! 196: check_duplicate(obj, pack) ! 197: object *obj, *pack; ! 198: { ! 199: object *op; ! 200: ! 201: if (!(obj->what_is & (WEAPON | FOOD | SCROL | POTION))) { ! 202: return(0); ! 203: } ! 204: if ((obj->what_is == FOOD) && (obj->which_kind == FRUIT)) { ! 205: return(0); ! 206: } ! 207: op = pack->next_object; ! 208: ! 209: while (op) { ! 210: if ((op->what_is == obj->what_is) && ! 211: (op->which_kind == obj->which_kind)) { ! 212: ! 213: if ((obj->what_is != WEAPON) || ! 214: ((obj->what_is == WEAPON) && ! 215: ((obj->which_kind == ARROW) || ! 216: (obj->which_kind == DAGGER) || ! 217: (obj->which_kind == DART) || ! 218: (obj->which_kind == SHURIKEN)) && ! 219: (obj->quiver == op->quiver))) { ! 220: op->quantity += obj->quantity; ! 221: return(op); ! 222: } ! 223: } ! 224: op = op->next_object; ! 225: } ! 226: return(0); ! 227: } ! 228: ! 229: next_avail_ichar() ! 230: { ! 231: register object *obj; ! 232: register i; ! 233: boolean ichars[26]; ! 234: ! 235: for (i = 0; i < 26; i++) { ! 236: ichars[i] = 0; ! 237: } ! 238: obj = rogue.pack.next_object; ! 239: while (obj) { ! 240: ichars[(obj->ichar - 'a')] = 1; ! 241: obj = obj->next_object; ! 242: } ! 243: for (i = 0; i < 26; i++) { ! 244: if (!ichars[i]) { ! 245: return(i + 'a'); ! 246: } ! 247: } ! 248: return('?'); ! 249: } ! 250: ! 251: wait_for_ack() ! 252: { ! 253: while (rgetchar() != ' ') ; ! 254: } ! 255: ! 256: pack_letter(prompt, mask) ! 257: char *prompt; ! 258: unsigned short mask; ! 259: { ! 260: short ch; ! 261: unsigned short tmask = mask; ! 262: ! 263: if (!mask_pack(&rogue.pack, mask)) { ! 264: message("nothing appropriate", 0); ! 265: return(CANCEL); ! 266: } ! 267: for (;;) { ! 268: ! 269: message(prompt, 0); ! 270: ! 271: for (;;) { ! 272: ch = rgetchar(); ! 273: if (!is_pack_letter(&ch, &mask)) { ! 274: sound_bell(); ! 275: } else { ! 276: break; ! 277: } ! 278: } ! 279: ! 280: if (ch == LIST) { ! 281: check_message(); ! 282: inventory(&rogue.pack, mask); ! 283: } else { ! 284: break; ! 285: } ! 286: mask = tmask; ! 287: } ! 288: check_message(); ! 289: return(ch); ! 290: } ! 291: ! 292: take_off() ! 293: { ! 294: char desc[DCOLS]; ! 295: object *obj; ! 296: ! 297: if (rogue.armor) { ! 298: if (rogue.armor->is_cursed) { ! 299: message(curse_message, 0); ! 300: } else { ! 301: mv_aquatars(); ! 302: obj = rogue.armor; ! 303: unwear(rogue.armor); ! 304: (void) strcpy(desc, "was wearing "); ! 305: get_desc(obj, desc+12); ! 306: message(desc, 0); ! 307: print_stats(STAT_ARMOR); ! 308: (void) reg_move(); ! 309: } ! 310: } else { ! 311: message("not wearing any", 0); ! 312: } ! 313: } ! 314: ! 315: wear() ! 316: { ! 317: short ch; ! 318: register object *obj; ! 319: char desc[DCOLS]; ! 320: ! 321: if (rogue.armor) { ! 322: message("your already wearing some", 0); ! 323: return; ! 324: } ! 325: ch = pack_letter("wear what?", ARMOR); ! 326: ! 327: if (ch == CANCEL) { ! 328: return; ! 329: } ! 330: if (!(obj = get_letter_object(ch))) { ! 331: message("no such item.", 0); ! 332: return; ! 333: } ! 334: if (obj->what_is != ARMOR) { ! 335: message("you can't wear that", 0); ! 336: return; ! 337: } ! 338: obj->identified = 1; ! 339: (void) strcpy(desc, "wearing "); ! 340: get_desc(obj, desc + 8); ! 341: message(desc, 0); ! 342: do_wear(obj); ! 343: print_stats(STAT_ARMOR); ! 344: (void) reg_move(); ! 345: } ! 346: ! 347: unwear(obj) ! 348: object *obj; ! 349: { ! 350: if (obj) { ! 351: obj->in_use_flags &= (~BEING_WORN); ! 352: } ! 353: rogue.armor = (object *) 0; ! 354: } ! 355: ! 356: do_wear(obj) ! 357: object *obj; ! 358: { ! 359: rogue.armor = obj; ! 360: obj->in_use_flags |= BEING_WORN; ! 361: obj->identified = 1; ! 362: } ! 363: ! 364: wield() ! 365: { ! 366: short ch; ! 367: register object *obj; ! 368: char desc[DCOLS]; ! 369: ! 370: if (rogue.weapon && rogue.weapon->is_cursed) { ! 371: message(curse_message, 0); ! 372: return; ! 373: } ! 374: ch = pack_letter("wield what?", WEAPON); ! 375: ! 376: if (ch == CANCEL) { ! 377: return; ! 378: } ! 379: if (!(obj = get_letter_object(ch))) { ! 380: message("No such item.", 0); ! 381: return; ! 382: } ! 383: if (obj->what_is & (ARMOR | RING)) { ! 384: sprintf(desc, "you can't wield %s", ! 385: ((obj->what_is == ARMOR) ? "armor" : "rings")); ! 386: message(desc, 0); ! 387: return; ! 388: } ! 389: if (obj->in_use_flags & BEING_WIELDED) { ! 390: message("in use", 0); ! 391: } else { ! 392: unwield(rogue.weapon); ! 393: (void) strcpy(desc, "wielding "); ! 394: get_desc(obj, desc + 9); ! 395: message(desc, 0); ! 396: do_wield(obj); ! 397: (void) reg_move(); ! 398: } ! 399: } ! 400: ! 401: do_wield(obj) ! 402: object *obj; ! 403: { ! 404: rogue.weapon = obj; ! 405: obj->in_use_flags |= BEING_WIELDED; ! 406: } ! 407: ! 408: unwield(obj) ! 409: object *obj; ! 410: { ! 411: if (obj) { ! 412: obj->in_use_flags &= (~BEING_WIELDED); ! 413: } ! 414: rogue.weapon = (object *) 0; ! 415: } ! 416: ! 417: call_it() ! 418: { ! 419: short ch; ! 420: register object *obj; ! 421: struct id *id_table; ! 422: char buf[MAX_TITLE_LENGTH+2]; ! 423: ! 424: ch = pack_letter("call what?", (SCROL | POTION | WAND | RING)); ! 425: ! 426: if (ch == CANCEL) { ! 427: return; ! 428: } ! 429: if (!(obj = get_letter_object(ch))) { ! 430: message("no such item.", 0); ! 431: return; ! 432: } ! 433: if (!(obj->what_is & (SCROL | POTION | WAND | RING))) { ! 434: message("surely you already know what that's called", 0); ! 435: return; ! 436: } ! 437: id_table = get_id_table(obj); ! 438: ! 439: if (get_input_line("call it:","",buf,id_table[obj->which_kind].title,1,1)) { ! 440: id_table[obj->which_kind].id_status = CALLED; ! 441: (void) strcpy(id_table[obj->which_kind].title, buf); ! 442: } ! 443: } ! 444: ! 445: pack_count(new_obj) ! 446: object *new_obj; ! 447: { ! 448: object *obj; ! 449: short count = 0; ! 450: ! 451: obj = rogue.pack.next_object; ! 452: ! 453: while (obj) { ! 454: if (obj->what_is != WEAPON) { ! 455: count += obj->quantity; ! 456: } else if (!new_obj) { ! 457: count++; ! 458: } else if ((new_obj->what_is != WEAPON) || ! 459: ((obj->which_kind != ARROW) && ! 460: (obj->which_kind != DAGGER) && ! 461: (obj->which_kind != DART) && ! 462: (obj->which_kind != SHURIKEN)) || ! 463: (new_obj->which_kind != obj->which_kind) || ! 464: (obj->quiver != new_obj->quiver)) { ! 465: count++; ! 466: } ! 467: obj = obj->next_object; ! 468: } ! 469: return(count); ! 470: } ! 471: ! 472: boolean ! 473: mask_pack(pack, mask) ! 474: object *pack; ! 475: unsigned short mask; ! 476: { ! 477: while (pack->next_object) { ! 478: pack = pack->next_object; ! 479: if (pack->what_is & mask) { ! 480: return(1); ! 481: } ! 482: } ! 483: return(0); ! 484: } ! 485: ! 486: is_pack_letter(c, mask) ! 487: short *c; ! 488: unsigned short *mask; ! 489: { ! 490: if (((*c == '?') || (*c == '!') || (*c == ':') || (*c == '=') || ! 491: (*c == ')') || (*c == ']') || (*c == '/') || (*c == ','))) { ! 492: switch(*c) { ! 493: case '?': ! 494: *mask = SCROL; ! 495: break; ! 496: case '!': ! 497: *mask = POTION; ! 498: break; ! 499: case ':': ! 500: *mask = FOOD; ! 501: break; ! 502: case ')': ! 503: *mask = WEAPON; ! 504: break; ! 505: case ']': ! 506: *mask = ARMOR; ! 507: break; ! 508: case '/': ! 509: *mask = WAND; ! 510: break; ! 511: case '=': ! 512: *mask = RING; ! 513: break; ! 514: case ',': ! 515: *mask = AMULET; ! 516: break; ! 517: } ! 518: *c = LIST; ! 519: return(1); ! 520: } ! 521: return(((*c >= 'a') && (*c <= 'z')) || (*c == CANCEL) || (*c == LIST)); ! 522: } ! 523: ! 524: has_amulet() ! 525: { ! 526: return(mask_pack(&rogue.pack, AMULET)); ! 527: } ! 528: ! 529: kick_into_pack() ! 530: { ! 531: object *obj; ! 532: char desc[DCOLS]; ! 533: short n, stat; ! 534: ! 535: if (!(dungeon[rogue.row][rogue.col] & OBJECT)) { ! 536: message("nothing here", 0); ! 537: } else { ! 538: if (obj = pick_up(rogue.row, rogue.col, &stat)) { ! 539: get_desc(obj, desc); ! 540: if (obj->what_is == GOLD) { ! 541: message(desc, 0); ! 542: free_object(obj); ! 543: } else { ! 544: n = strlen(desc); ! 545: desc[n] = '('; ! 546: desc[n+1] = obj->ichar; ! 547: desc[n+2] = ')'; ! 548: desc[n+3] = 0; ! 549: message(desc, 0); ! 550: } ! 551: } ! 552: if (obj || (!stat)) { ! 553: (void) reg_move(); ! 554: } ! 555: } ! 556: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.