Mercurial > hg > early-roguelike
diff arogue5/pack.c @ 63:0ed67132cf10
Import Advanced Rogue 5.8 from the Roguelike Restoration Project (r1490)
| author | elwin |
|---|---|
| date | Thu, 09 Aug 2012 22:58:48 +0000 |
| parents | |
| children | 56e748983fa8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arogue5/pack.c Thu Aug 09 22:58:48 2012 +0000 @@ -0,0 +1,1143 @@ +/* + * Routines to deal with the pack + * + * Advanced Rogue + * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T + * All rights reserved. + * + * Based on "Rogue: Exploring the Dungeons of Doom" + * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman + * All rights reserved. + * + * See the file LICENSE.TXT for full copyright and licensing information. + */ + +#include "curses.h" +#include <ctype.h> +#include "rogue.h" + +char outstring[512]; /* ridiculously long string for use with msg */ + +/* + * add_pack: + * Pick up an object and add it to the pack. If the argument is non-null + * use it as the linked_list pointer instead of gettting it off the ground. + */ +bool +add_pack(item, silent, packret) +register struct linked_list *item, **packret; +bool silent; +{ + register struct linked_list *ip, *lp = NULL, *ap; + register struct object *obj, *op = NULL; + register bool exact, from_floor; + + if (packret != NULL) + *packret = NULL; + + if (item == NULL) + { + from_floor = TRUE; + if ((item = find_obj(hero.y, hero.x)) == NULL) + return(FALSE); + } + else + from_floor = FALSE; + obj = OBJPTR(item); + /* + * If it is gold, just add its value to rogue's purse and get rid + * of it. + */ + if (obj->o_type == GOLD) { + register struct linked_list *mitem; + register struct thing *tp; + + if (!silent) { + if (!terse) addmsg("You found "); + msg("%d gold pieces.", obj->o_count); + } + + /* First make sure no greedy monster is after this gold. + * If so, make the monster run after the rogue instead. + */ + for (mitem = mlist; mitem != NULL; mitem = next(mitem)) { + tp = THINGPTR(mitem); + if (tp->t_dest == &obj->o_pos) tp->t_dest = &hero; + } + + purse += obj->o_count; + if (from_floor) { + detach(lvl_obj, item); + if ((ap = find_obj(hero.y, hero.x)) == NULL) + mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR)); + else + mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type); + } + o_discard(item); + return(TRUE); + } + + /* + * see if he can carry any more weight + */ + if (itemweight(obj) + pstats.s_pack > pstats.s_carry) { + msg("Too much for you to carry."); + return FALSE; + } + /* + * Link it into the pack. Search the pack for a object of similar type + * if there isn't one, stuff it at the beginning, if there is, look for one + * that is exactly the same and just increment the count if there is. + * it that. Food is always put at the beginning for ease of access, but + * is not ordered so that you can't tell good food from bad. First check + * to see if there is something in thr same group and if there is then + * increment the count. + */ + if (obj->o_group) + { + for (ip = pack; ip != NULL; ip = next(ip)) + { + op = OBJPTR(ip); + if (op->o_group == obj->o_group) + { + /* + * Put it in the pack and notify the user + */ + op->o_count += obj->o_count; + if (from_floor) + { + detach(lvl_obj, item); + if ((ap = find_obj(hero.y, hero.x)) == NULL) + mvaddch(hero.y,hero.x, + (roomin(&hero)==NULL ? PASSAGE : FLOOR)); + else + mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type); + } + o_discard(item); + item = ip; + goto picked_up; + } + } + } + + /* + * Check for and deal with scare monster scrolls + */ + if (obj->o_type == SCROLL && obj->o_which == S_SCARE) + if (obj->o_flags & ISCURSED) + { + msg("The scroll turns to dust as you pick it up."); + detach(lvl_obj, item); + if ((ap = find_obj(hero.y, hero.x)) == NULL) + mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR)); + else + mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type); + return(TRUE); + } + + /* + * Search for an object of the same type + */ + exact = FALSE; + for (ip = pack; ip != NULL; ip = next(ip)) + { + op = OBJPTR(ip); + if (obj->o_type == op->o_type) + break; + } + if (ip == NULL) + { + /* + * Put it at the end of the pack since it is a new type + */ + for (ip = pack; ip != NULL; ip = next(ip)) + { + op = OBJPTR(ip); + if (op->o_type != FOOD) + break; + lp = ip; + } + } + else + { + /* + * Search for an object which is exactly the same + */ + while (ip != NULL && op->o_type == obj->o_type) + { + if (op->o_which == obj->o_which) + { + exact = TRUE; + break; + } + lp = ip; + if ((ip = next(ip)) == NULL) + break; + op = OBJPTR(ip); + } + } + /* + * Check if there is room + */ + if (ip == NULL || !exact || !ISMULT(obj->o_type)) { + if (inpack == MAXPACK-1) { + msg(terse ? "No room." : "You can't carry anything else."); + return(FALSE); + } + } + inpack++; + if (from_floor) + { + detach(lvl_obj, item); + if ((ap = find_obj(hero.y, hero.x)) == NULL) + mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR)); + else + mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type); + } + if (ip == NULL) + { + /* + * Didn't find an exact match, just stick it here + */ + if (pack == NULL) + pack = item; + else + { + lp->l_next = item; + item->l_prev = lp; + item->l_next = NULL; + } + } + else + { + /* + * If we found an exact match. If it is food, + * increase the count, otherwise put it with its clones. + */ + if (exact && ISMULT(obj->o_type)) + { + op->o_count += obj->o_count; + inpack--; /* adjust for previous addition */ + o_discard(item); + item = ip; + goto picked_up; + } + if ((item->l_prev = prev(ip)) != NULL) + item->l_prev->l_next = item; + else + pack = item; + item->l_next = ip; + ip->l_prev = item; + } +picked_up: + /* + * Notify the user + */ + obj = OBJPTR(item); + if (!silent) + { + if (!terse) + addmsg("You now have "); + sprintf(outstring,"%s (%c)", inv_name(obj, !terse), pack_char(pack, obj)); + msg(outstring); + } + + /* Relics can do strange things when you pick them up */ + if (obj->o_type == RELIC) { + cur_relic[obj->o_which]++; /* Note that we have it */ + switch (obj->o_which) { + case HEIL_ANKH: + msg("The ankh welds itself into your hand."); + + /* A cloak must be worn. */ + when EMORI_CLOAK: + if (cur_armor != NULL || cur_misc[WEAR_CLOAK]) { + msg("The cloak insists you remove your current garments."); + if (!dropcheck(cur_armor != NULL ? cur_armor + : cur_misc[WEAR_CLOAK])) { + pstats.s_hpt = -1; + msg("The cloak constricts around you."); + msg("It draws your life force from you!!! -- More --"); + wait_for(cw,' '); + death(D_RELIC); + } + } + + /* The amulet must be worn. */ + when YENDOR_AMULET: + if (cur_misc[WEAR_JEWEL]) { + msg("You have an urge to remove your current amulet."); + if (!dropcheck(cur_misc[WEAR_JEWEL])) { + pstats.s_hpt = -1; + msg("The Amulet of Yendor begins pulsing."); + msg("It fades away.... -- More --"); + wait_for(cw,' '); + death(D_RELIC); + } + } + msg("The amulet welds itself into your chest."); + + /* Weapons will insist on being wielded. */ + when MUSTY_DAGGER: + case HRUGGEK_MSTAR: + case YEENOGHU_FLAIL: + if (cur_weapon != NULL) { + msg("The artifact insists you release your current weapon."); + if (!dropcheck(cur_weapon)) { + pstats.s_hpt = -1; + msg("The artifact forces your weapon into your heart."); + msg("It hums with satisfaction. -- More --"); + wait_for(cw,' '); + death(D_RELIC); + } + } + cur_weapon = obj; + } + } + + updpack(FALSE); + if (packret != NULL) + *packret = item; + return(TRUE); +} + +/* + * inventory: + * list what is in the pack + */ +inventory(list, type) +register struct linked_list *list; +register int type; +{ + register struct object *obj; + register char ch; + register int n_objs; + register int cnt; + char inv_temp[LINELEN];
