Annotation of early-roguelike/srogue/pack.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * Routines to deal with the pack
! 3: *
! 4: * @(#)pack.c 9.0 (rdk) 7/17/84
! 5: *
! 6: * Super-Rogue
! 7: * Copyright (C) 1984 Robert D. Kindelberger
! 8: * All rights reserved.
! 9: *
! 10: * Based on "Rogue: Exploring the Dungeons of Doom"
! 11: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 12: * All rights reserved.
! 13: *
! 14: * See the file LICENSE.TXT for full copyright and licensing information.
! 15: */
! 16:
! 17: #include <ctype.h>
! 18: #include "rogue.h"
! 19: #include "rogue.ext"
! 20:
! 21: /*
! 22: * add_pack:
! 23: * Pick up an object and add it to the pack. If the argument
! 24: * is non-null use it as the linked_list pointer instead of
! 25: * getting it off the ground.
! 26: */
! 27: bool
! 28: add_pack(struct linked_list *item, bool silent)
! 29: {
! 30: reg struct linked_list *ip, *lp;
! 31: reg struct object *obj, *op = NULL;
! 32: bool from_floor;
! 33: char delchar;
! 34:
! 35: if (player.t_room == NULL)
! 36: delchar = PASSAGE;
! 37: else
! 38: delchar = FLOOR;
! 39: if (item == NULL) {
! 40: from_floor = TRUE;
! 41: if ((item = find_obj(hero.y, hero.x)) == NULL) {
! 42: mpos = 0;
! 43: msg("That object must have been an illusion.");
! 44: mvaddch(hero.y, hero.x, delchar);
! 45: return FALSE;
! 46: }
! 47: /*
! 48: * Check for scare monster scrolls
! 49: */
! 50: obj = OBJPTR(item);
! 51: if (obj->o_type == SCROLL && obj->o_which == S_SCARE) {
! 52: if (o_on(obj,ISFOUND)) {
! 53: msg("The scroll turns to dust as you pick it up.");
! 54: detach(lvl_obj, item);
! 55: discard(item);
! 56: mvaddch(hero.y, hero.x, delchar);
! 57: return FALSE;
! 58: }
! 59: }
! 60: }
! 61: else
! 62: from_floor = FALSE;
! 63: obj = OBJPTR(item);
! 64: /*
! 65: * See if this guy can carry any more weight
! 66: */
! 67: if (itemweight(obj) + him->s_pack > him->s_carry) {
! 68: msg("You can't carry that %s.", obj->o_typname);
! 69: return FALSE;
! 70: }
! 71: /*
! 72: * Check if there is room
! 73: */
! 74: if (packvol + obj->o_vol > V_PACK) {
! 75: msg("That %s won't fit in your pack.", obj->o_typname);
! 76: return FALSE;
! 77: }
! 78: if (from_floor) {
! 79: detach(lvl_obj, item);
! 80: mvaddch(hero.y, hero.x, delchar);
! 81: }
! 82: item->l_prev = NULL;
! 83: item->l_next = NULL;
! 84: setoflg(obj, ISFOUND);
! 85: /*
! 86: * start looking thru pack to find the start of items
! 87: * with the same type.
! 88: */
! 89: lp = pack;
! 90: for (ip = pack; ip != NULL; ip = next(ip)) {
! 91: op = OBJPTR(ip);
! 92: /*
! 93: * If we find a matching type then quit.
! 94: */
! 95: if (op->o_type == obj->o_type)
! 96: break;
! 97: if (next(ip) != NULL)
! 98: lp = next(lp); /* update "previous" entry */
! 99: }
! 100: /*
! 101: * If the pack was empty, just stick the item in it.
! 102: */
! 103: if (pack == NULL) {
! 104: pack = item;
! 105: item->l_prev = NULL;
! 106: }
! 107: /*
! 108: * If we looked thru the pack, but could not find an
! 109: * item of the same type, then stick it at the end,
! 110: * unless it was food, then put it in front.
! 111: */
! 112: else if (ip == NULL) {
! 113: if (obj->o_type == FOOD) { /* insert food at front */
! 114: item->l_next = pack;
! 115: pack->l_prev = item;
! 116: pack = item;
! 117: item->l_prev = NULL;
! 118: }
! 119: else { /* insert other stuff at back */
! 120: lp->l_next = item;
! 121: item->l_prev = lp;
! 122: }
! 123: }
! 124: /*
! 125: * Here, we found at least one item of the same type.
! 126: * Look thru these items to see if there is one of the
! 127: * same group. If so, increment the count and throw the
! 128: * new item away. If not, stick it at the end of the
! 129: * items with the same type. Also keep all similar
! 130: * objects near each other, like all identify scrolls, etc.
! 131: */
! 132: else {
! 133: struct linked_list **save;
! 134:
! 135: while (ip != NULL && op->o_type == obj->o_type) {
! 136: if (op->o_group == obj->o_group) {
! 137: if (op->o_flags == obj->o_flags) {
! 138: op->o_count++;
! 139: discard(item);
! 140: item = ip;
! 141: goto picked_up;
! 142: }
! 143: else {
! 144: goto around;
! 145: }
! 146: }
! 147: if (op->o_which == obj->o_which) {
! 148: if (obj->o_type == FOOD)
! 149: ip = next(ip);
! 150: break;
! 151: }
! 152: around:
! 153: ip = next(ip);
! 154: if (ip != NULL) {
! 155: op = OBJPTR(ip);
! 156: lp = next(lp);
! 157: }
! 158: }
! 159: /*
! 160: * If inserting into last of group at end of pack,
! 161: * just tack on the end.
! 162: */
! 163: if (ip == NULL) {
! 164: lp->l_next = item;
! 165: item->l_prev = lp;
! 166: }
! 167: /*
! 168: * Insert into the last of a group of objects
! 169: * not at the end of the pack.
! 170: */
! 171: else {
! 172: save = &((ip->l_prev)->l_next);
! 173: item->l_next = ip;
! 174: item->l_prev = ip->l_prev;
! 175: ip->l_prev = item;
! 176: *save = item;
! 177: }
! 178: }
! 179: picked_up:
! 180: obj = OBJPTR(item);
! 181: if (!silent)
! 182: msg("%s (%c)",inv_name(obj,FALSE),pack_char(obj));
! 183: if (obj->o_type == AMULET)
! 184: amulet = TRUE;
! 185: updpack(); /* new pack weight & volume */
! 186: return TRUE;
! 187: }
! 188:
! 189: /*
! 190: * inventory:
! 191: * Show what items are in a specific list
! 192: */
! 193: bool
! 194: inventory(struct linked_list *list, int type)
! 195: {
! 196: reg struct linked_list *pc;
! 197: reg struct object *obj;
! 198: reg char ch;
! 199: reg int cnt;
! 200:
! 201: if (list == NULL) { /* empty list */
! 202: msg(type == 0 ? "Empty handed." : "Nothing appropriate.");
! 203: return FALSE;
! 204: }
! 205: else if (next(list) == NULL) { /* only 1 item in list */
! 206: obj = OBJPTR(list);
! 207: msg("a) %s", inv_name(obj, FALSE));
! 208: return TRUE;
! 209: }
! 210: cnt = 0;
! 211: wclear(hw);
! 212: for (ch = 'a', pc = list; pc != NULL; pc = next(pc), ch = npch(ch)) {
! 213: obj = OBJPTR(pc);
! 214: wprintw(hw,"%c) %s\n\r",ch,inv_name(obj, FALSE));
! 215: if (++cnt > LINES - 2 && next(pc) != NULL) {
! 216: dbotline(hw, morestr);
! 217: cnt = 0;
! 218: wclear(hw);
! 219: }
! 220: }
! 221: dbotline(hw,spacemsg);
! 222: restscr(cw);
! 223: return TRUE;
! 224: }
! 225:
! 226: /*
! 227: * pick_up:
! 228: * Add something to characters pack.
! 229: */
! 230: void
! 231: pick_up(char ch)
! 232: {
! 233: nochange = FALSE;
! 234: switch(ch) {
! 235: case GOLD:
! 236: money();
! 237: when ARMOR:
! 238: case POTION:
! 239: case FOOD:
! 240: case WEAPON:
! 241: case SCROLL:
! 242: case AMULET:
! 243: case RING:
! 244: case STICK:
! 245: add_pack(NULL, FALSE);
! 246: otherwise:
! 247: msg("That item is ethereal !!!");
! 248: }
! 249: }
! 250:
! 251: /*
! 252: * picky_inven:
! 253: * Allow player to inventory a single item
! 254: */
! 255: void
! 256: picky_inven(void)
! 257: {
! 258: reg struct linked_list *item;
! 259: reg char ch, mch;
! 260:
! 261: if (pack == NULL)
! 262: msg("You aren't carrying anything.");
! 263: else if (next(pack) == NULL)
! 264: msg("a) %s", inv_name(OBJPTR(pack), FALSE));
! 265: else {
! 266: msg("Item: ");
! 267: mpos = 0;
! 268: if ((mch = readchar()) == ESCAPE) {
! 269: msg("");
! 270: return;
! 271: }
! 272: for (ch='a',item=pack; item != NULL; item=next(item),ch=npch(ch))
! 273: if (ch == mch) {
! 274: msg("%c) %s",ch,inv_name(OBJPTR(item), FALSE));
! 275: return;
! 276: }
! 277: if (ch == 'A')
! 278: ch = 'z';
! 279: else
! 280: ch -= 1;
! 281: msg("Range is 'a' to '%c'", ch);
! 282: }
! 283: }
! 284:
! 285: /*
! 286: * get_item:
! 287: * pick something out of a pack for a purpose
! 288: */
! 289: struct linked_list *
! 290: get_item(char *purpose, int type)
! 291: {
! 292: reg struct linked_list *obj, *pit, *savepit = NULL;
! 293: struct object *pob;
! 294: int ch, och, anr, cnt;
! 295:
! 296: if (pack == NULL) {
! 297: msg("You aren't carrying anything.");
! 298: return NULL;
! 299: }
! 300: if (type != WEAPON && (type != 0 || next(pack) == NULL)) {
! 301: /*
! 302: * see if we have any of the type requested
! 303: */
! 304: pit = pack;
! 305: anr = 0;
! 306: for (ch = 'a'; pit != NULL; pit = next(pit), ch = npch(ch)) {
! 307: pob = OBJPTR(pit);
! 308: if (type == pob->o_type || type == 0) {
! 309: ++anr;
! 310: savepit = pit; /* save in case of only 1 */
! 311: }
! 312: }
! 313: if (anr == 0) {
! 314: msg("Nothing to %s",purpose);
! 315: after = FALSE;
! 316: return NULL;
! 317: }
! 318: else if (anr == 1) { /* only found one of 'em */
! 319: do {
! 320: struct object *opb;
! 321:
! 322: opb = OBJPTR(savepit);
! 323: msg("%s what (* for the item)?",purpose);
! 324: och = readchar();
! 325: if (och == '*') {
! 326: mpos = 0;
! 327: msg("%c) %s",pack_char(opb),inv_name(opb,FALSE));
! 328: continue;
! 329: }
! 330: if (och == ESCAPE) {
! 331: msg("");
! 332: after = FALSE;
! 333: return NULL;
! 334: }
! 335: if (isalpha(och) && och != pack_char(opb)) {
! 336: mpos = 0;
! 337: msg("You can't %s that !!", purpose);
! 338: after = FALSE;
! 339: return NULL;
! 340: }
! 341: } while(!isalpha(och));
! 342: mpos = 0;
! 343: return savepit; /* return this item */
! 344: }
! 345: }
! 346: for (;;) {
! 347: msg("%s what? (* for list): ",purpose);
! 348: ch = readchar();
! 349: mpos = 0;
! 350: if (ch == ESCAPE) { /* abort if escape hit */
! 351: after = FALSE;
! 352: msg(""); /* clear display */
! 353: return NULL;
! 354: }
! 355: if (ch == '*') {
! 356: wclear(hw);
! 357: pit = pack; /* point to pack */
! 358: cnt = 0;
! 359: for (ch='a'; pit != NULL; pit=next(pit), ch=npch(ch)) {
! 360: pob = OBJPTR(pit);
! 361: if (type == 0 || type == pob->o_type) {
! 362: wprintw(hw,"%c) %s\n\r",ch,inv_name(pob,FALSE));
! 363: if (++cnt > LINES - 2 && next(pit) != NULL) {
! 364: cnt = 0;
! 365: dbotline(hw, morestr);
! 366: wclear(hw);
! 367: }
! 368: }
! 369: }
! 370: wmove(hw, LINES - 1,0);
! 371: wprintw(hw,"%s what? ",purpose);
! 372: draw(hw); /* write screen */
! 373: anr = FALSE;
! 374: do {
! 375: ch = readchar();
! 376: if (isalpha(ch) || ch == ESCAPE)
! 377: anr = TRUE;
! 378: } while(!anr); /* do till we got it right */
! 379: restscr(cw); /* redraw orig screen */
! 380: if (ch == ESCAPE) {
! 381: after = FALSE;
! 382: msg(""); /* clear top line */
! 383: return NULL; /* all done if abort */
! 384: }
! 385: /* ch has item to get from pack */
! 386: }
! 387: for (obj=pack,och='a';obj!=NULL;obj=next(obj),och=npch(och))
! 388: if (ch == och)
! 389: break;
! 390: if (obj == NULL) {
! 391: if (och == 'A')
! 392: och = 'z';
! 393: else
! 394: och -= 1;
! 395: msg("Please specify a letter between 'a' and '%c'",och);
! 396: continue;
! 397: }
! 398: else
! 399: return obj;
! 400: }
! 401: }
! 402:
! 403: /*
! 404: * pack_char:
! 405: * Get the character of a particular item in the pack
! 406: */
! 407: char
! 408: pack_char(struct object *obj)
! 409: {
! 410: reg struct linked_list *item;
! 411: reg char c;
! 412:
! 413: c = 'a';
! 414: for (item = pack; item != NULL; item = next(item))
! 415: if (OBJPTR(item) == obj)
! 416: return c;
! 417: else
! 418: c = npch(c);
! 419: return '%';
! 420: }
! 421:
! 422: /*
! 423: * idenpack:
! 424: * Identify all the items in the pack
! 425: */
! 426: void
! 427: idenpack(void)
! 428: {
! 429: reg struct linked_list *pc;
! 430:
! 431: for (pc = pack ; pc != NULL ; pc = next(pc))
! 432: whatis(pc);
! 433: }
! 434:
! 435:
! 436: /*
! 437: * del_pack:
! 438: * Take something out of the hero's pack
! 439: */
! 440: void
! 441: del_pack(struct linked_list *what)
! 442: {
! 443: reg struct object *op;
! 444:
! 445: op = OBJPTR(what);
! 446: cur_null(op); /* check for current stuff */
! 447: if (op->o_count > 1) {
! 448: op->o_count--;
! 449: }
! 450: else {
! 451: detach(pack,what);
! 452: discard(what);
! 453: }
! 454: updpack();
! 455: }
! 456:
! 457: /*
! 458: * cur_null:
! 459: * This updates cur_weapon etc for dropping things
! 460: */
! 461: void
! 462: cur_null(struct object *op)
! 463: {
! 464: if (op == cur_weapon)
! 465: cur_weapon = NULL;
! 466: else if (op == cur_armor)
! 467: cur_armor = NULL;
! 468: else if (op == cur_ring[LEFT])
! 469: cur_ring[LEFT] = NULL;
! 470: else if (op == cur_ring[RIGHT])
! 471: cur_ring[RIGHT] = NULL;
! 472: }
CVSweb