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