Annotation of early-roguelike/rogue3/pack.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * Routines to deal with the pack
! 3: *
! 4: * @(#)pack.c 3.6 (Berkeley) 6/15/81
! 5: *
! 6: * Rogue: Exploring the Dungeons of Doom
! 7: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 8: * All rights reserved.
! 9: *
! 10: * See the file LICENSE.TXT for full copyright and licensing information.
! 11: */
! 12:
! 13: #include "curses.h"
! 14: #include <ctype.h>
! 15: #include "rogue.h"
! 16:
! 17: /*
! 18: * add_pack:
! 19: * Pick up an object and add it to the pack. If the argument is non-null
! 20: * use it as the linked_list pointer instead of gettting it off the ground.
! 21: */
! 22: void
! 23: add_pack(struct linked_list *item, int silent)
! 24: {
! 25: struct linked_list *ip, *lp = NULL;
! 26: struct object *obj, *op = NULL;
! 27: int exact, from_floor;
! 28:
! 29: if (item == NULL)
! 30: {
! 31: from_floor = TRUE;
! 32: if ((item = find_obj(hero.y, hero.x)) == NULL)
! 33: return;
! 34: }
! 35: else
! 36: from_floor = FALSE;
! 37: obj = (struct object *) ldata(item);
! 38: /*
! 39: * Link it into the pack. Search the pack for a object of similar type
! 40: * if there isn't one, stuff it at the beginning, if there is, look for one
! 41: * that is exactly the same and just increment the count if there is.
! 42: * it that. Food is always put at the beginning for ease of access, but
! 43: * is not ordered so that you can't tell good food from bad. First check
! 44: * to see if there is something in thr same group and if there is then
! 45: * increment the count.
! 46: */
! 47: if (obj->o_group)
! 48: {
! 49: for (ip = pack; ip != NULL; ip = next(ip))
! 50: {
! 51: op = (struct object *) ldata(ip);
! 52: if (op->o_group == obj->o_group)
! 53: {
! 54: /*
! 55: * Put it in the pack and notify the user
! 56: */
! 57: op->o_count++;
! 58: if (from_floor)
! 59: {
! 60: detach(lvl_obj, item);
! 61: mvaddch(hero.y, hero.x,
! 62: (roomin(&hero) == NULL ? PASSAGE : FLOOR));
! 63: }
! 64: discard(item);
! 65: item = ip;
! 66: goto picked_up;
! 67: }
! 68: }
! 69: }
! 70: /*
! 71: * Check if there is room
! 72: */
! 73: if (inpack == MAXPACK-1)
! 74: {
! 75: msg("You can't carry anything else.");
! 76: return;
! 77: }
! 78: /*
! 79: * Check for and deal with scare monster scrolls
! 80: */
! 81: if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
! 82: if (obj->o_flags & ISFOUND)
! 83: {
! 84: msg("The scroll turns to dust as you pick it up.");
! 85: detach(lvl_obj, item);
! 86: mvaddch(hero.y, hero.x, FLOOR);
! 87: return;
! 88: }
! 89: else
! 90: obj->o_flags |= ISFOUND;
! 91:
! 92: inpack++;
! 93: if (from_floor)
! 94: {
! 95: detach(lvl_obj, item);
! 96: mvaddch(hero.y, hero.x, (roomin(&hero) == NULL ? PASSAGE : FLOOR));
! 97: }
! 98: /*
! 99: * Search for an object of the same type
! 100: */
! 101: exact = FALSE;
! 102: for (ip = pack; ip != NULL; ip = next(ip))
! 103: {
! 104: op = (struct object *) ldata(ip);
! 105: if (obj->o_type == op->o_type)
! 106: break;
! 107: }
! 108: if (ip == NULL)
! 109: {
! 110: /*
! 111: * Put it at the end of the pack since it is a new type
! 112: */
! 113: for (ip = pack; ip != NULL; ip = next(ip))
! 114: {
! 115: op = (struct object *) ldata(ip);
! 116: if (op->o_type != FOOD)
! 117: break;
! 118: lp = ip;
! 119: }
! 120: }
! 121: else
! 122: {
! 123: /*
! 124: * Search for an object which is exactly the same
! 125: */
! 126: while (ip != NULL && op->o_type == obj->o_type)
! 127: {
! 128: if (op->o_which == obj->o_which)
! 129: {
! 130: exact = TRUE;
! 131: break;
! 132: }
! 133: lp = ip;
! 134: if ((ip = next(ip)) == NULL)
! 135: break;
! 136: op = (struct object *) ldata(ip);
! 137: }
! 138: }
! 139: if (ip == NULL)
! 140: {
! 141: /*
! 142: * Didn't find an exact match, just stick it here
! 143: */
! 144: if (pack == NULL)
! 145: pack = item;
! 146: else
! 147: {
! 148: lp->l_next = item;
! 149: item->l_prev = lp;
! 150: item->l_next = NULL;
! 151: }
! 152: }
! 153: else
! 154: {
! 155: /*
! 156: * If we found an exact match. If it is a potion, food, or a
! 157: * scroll, increase the count, otherwise put it with its clones.
! 158: */
! 159: if (exact && ISMULT(obj->o_type))
! 160: {
! 161: op->o_count++;
! 162: discard(item);
! 163: item = ip;
! 164: goto picked_up;
! 165: }
! 166: if ((item->l_prev = prev(ip)) != NULL)
! 167: item->l_prev->l_next = item;
! 168: else
! 169: pack = item;
! 170: item->l_next = ip;
! 171: ip->l_prev = item;
! 172: }
! 173: picked_up:
! 174: /*
! 175: * Notify the user
! 176: */
! 177: obj = (struct object *) ldata(item);
! 178: if (notify && !silent)
! 179: {
! 180: if (!terse)
! 181: addmsg("You now have ");
! 182: msg("%s (%c)", inv_name(obj, !terse), pack_char(obj));
! 183: }
! 184: if (obj->o_type == AMULET)
! 185: amulet = TRUE;
! 186: }
! 187:
! 188: /*
! 189: * inventory:
! 190: * list what is in the pack
! 191: */
! 192: int
! 193: inventory(struct linked_list *list, int type)
! 194: {
! 195: struct object *obj;
! 196: int ch;
! 197: int n_objs;
! 198: char inv_temp[80];
! 199:
! 200: n_objs = 0;
! 201: for (ch = 'a'; list != NULL; ch++, list = next(list))
! 202: {
! 203: obj = (struct object *) ldata(list);
! 204: if (type && type != obj->o_type && !(type == CALLABLE &&
! 205: (obj->o_type == SCROLL || obj->o_type == POTION ||
! 206: obj->o_type == RING || obj->o_type == STICK)))
! 207: continue;
! 208: switch (n_objs++)
! 209: {
! 210: /*
! 211: * For the first thing in the inventory, just save the string
! 212: * in case there is only one.
! 213: */
! 214: case 0:
! 215: sprintf(inv_temp, "%c) %s", ch, inv_name(obj, FALSE));
! 216: break;
! 217: /*
! 218: * If there is more than one, clear the screen, print the
! 219: * saved message and fall through to ...
! 220: */
! 221: case 1:
! 222: if (slow_invent)
! 223: msg(inv_temp);
! 224: else
! 225: {
! 226: wclear(hw);
! 227: waddstr(hw, inv_temp);
! 228: waddch(hw, '\n');
! 229: }
! 230: /*
! 231: * Print the line for this object
! 232: */
! 233: default:
! 234: if (slow_invent)
! 235: msg("%c) %s", ch, inv_name(obj, FALSE));
! 236: else
! 237: wprintw(hw, "%c) %s\n", ch, inv_name(obj, FALSE));
! 238: }
! 239: }
! 240: if (n_objs == 0)
! 241: {
! 242: if (terse)
! 243: msg(type == 0 ? "Empty handed." :
! 244: "Nothing appropriate");
! 245: else
! 246: msg(type == 0 ? "You are empty handed." :
! 247: "You don't have anything appropriate");
! 248: return FALSE;
! 249: }
! 250: if (n_objs == 1)
! 251: {
! 252: msg(inv_temp);
! 253: return TRUE;
! 254: }
! 255: if (!slow_invent)
! 256: {
! 257: mvwaddstr(hw, LINES-1, 0, "--Press space to continue--");
! 258: draw(hw);
! 259: wait_for(hw,' ');
! 260: clearok(cw, TRUE);
! 261: touchwin(cw);
! 262: }
! 263: return TRUE;
! 264: }
! 265:
! 266: /*
! 267: * pick_up:
! 268: * Add something to characters pack.
! 269: */
! 270: void
! 271: pick_up(int ch)
! 272: {
! 273: switch(ch)
! 274: {
! 275: case GOLD:
! 276: money();
! 277: break;
! 278: default:
! 279: debug("Where did you pick that up???");
! 280: case ARMOR:
! 281: case POTION:
! 282: case FOOD:
! 283: case WEAPON:
! 284: case SCROLL:
! 285: case AMULET:
! 286: case RING:
! 287: case STICK:
! 288: add_pack(NULL, FALSE);
! 289: break;
! 290: }
! 291: }
! 292:
! 293: /*
! 294: * picky_inven:
! 295: * Allow player to inventory a single item
! 296: */
! 297: void
! 298: picky_inven()
! 299: {
! 300: struct linked_list *item;
! 301: int ch, mch;
! 302:
! 303: if (pack == NULL)
! 304: msg("You aren't carrying anything");
! 305: else if (next(pack) == NULL)
! 306: msg("a) %s", inv_name((struct object *) ldata(pack), FALSE));
! 307: else
! 308: {
! 309: msg(terse ? "Item: " : "Which item do you wish to inventory: ");
! 310: mpos = 0;
! 311: if ((mch = readchar(cw)) == ESCAPE)
! 312: {
! 313: msg("");
! 314: return;
! 315: }
! 316: for (ch = 'a', item = pack; item != NULL; item = next(item), ch++)
! 317: if (ch == mch)
! 318: {
! 319: msg("%c) %s",ch,inv_name((struct object *) ldata(item), FALSE));
! 320: return;
! 321: }
! 322: if (!terse)
! 323: msg("'%s' not in pack", unctrl(mch));
! 324: msg("Range is 'a' to '%c'", --ch);
! 325: }
! 326: }
! 327:
! 328: /*
! 329: * get_item:
! 330: * pick something out of a pack for a purpose
! 331: */
! 332: struct linked_list *
! 333: get_item(char *purpose, int type)
! 334: {
! 335: struct linked_list *obj;
! 336: int ch, och;
! 337:
! 338: if (pack == NULL)
! 339: msg("You aren't carrying anything.");
! 340: else
! 341: {
! 342: for (;;)
! 343: {
! 344: if (!terse)
! 345: addmsg("Which object do you want to ");
! 346: addmsg(purpose);
! 347: if (terse)
! 348: addmsg(" what");
! 349: msg("? (* for list): ");
! 350: ch = readchar(cw);
! 351: mpos = 0;
! 352: /*
! 353: * Give the poor player a chance to abort the command
! 354: */
! 355: if (ch == ESCAPE || ch == CTRL('G'))
! 356: {
! 357: after = FALSE;
! 358: msg("");
! 359: return NULL;
! 360: }
! 361: if (ch == '*')
! 362: {
! 363: mpos = 0;
! 364: if (inventory(pack, type) == 0)
! 365: {
! 366: after = FALSE;
! 367: return NULL;
! 368: }
! 369: continue;
! 370: }
! 371: for (obj = pack, och = 'a'; obj != NULL; obj = next(obj), och++)
! 372: if (ch == och)
! 373: break;
! 374: if (obj == NULL)
! 375: {
! 376: msg("Please specify a letter between 'a' and '%c'", och-1);
! 377: continue;
! 378: }
! 379: else
! 380: return obj;
! 381: }
! 382: }
! 383: return NULL;
! 384: }
! 385:
! 386: int
! 387: pack_char(struct object *obj)
! 388: {
! 389: struct linked_list *item;
! 390: int c;
! 391:
! 392: c = 'a';
! 393: for (item = pack; item != NULL; item = next(item))
! 394: if ((struct object *) ldata(item) == obj)
! 395: return c;
! 396: else
! 397: c++;
! 398: return 'z';
! 399: }
CVSweb