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: }

Defined functions

call_it defined in line 395; used 1 times
check_duplicate defined in line 173; used 2 times
do_wear defined in line 334; used 3 times
do_wield defined in line 379; used 3 times
drop defined in line 111; used 1 times
has_amulet defined in line 502; used 3 times
is_pack_letter defined in line 464; used 1 times
kick_into_pack defined in line 507; used 1 times
mask_pack defined in line 450; used 3 times
next_avail_ichar defined in line 207; used 1 times
  • in line 34
pack_count defined in line 423; used 2 times
pick_up defined in line 64; used 3 times
take_off defined in line 270; used 1 times
unwear defined in line 325; used 5 times
unwield defined in line 386; used 5 times
wear defined in line 293; used 1 times
wield defined in line 342; used 1 times

Defined variables

curse_message defined in line 19; used 7 times
sccsid defined in line 14; never used
Last modified: 1987-11-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4272
Valid CSS Valid XHTML 1.0 Strict