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