/* ### invent.c ### */
-E struct obj **FDECL(objarr_init, (int));
-E void FDECL(objarr_set, (struct obj *, int, struct obj **, BOOLEAN_P));
+E void FDECL(sortloot, (struct obj **, unsigned, BOOLEAN_P));
E void FDECL(assigninvlet, (struct obj *));
E struct obj *FDECL(merge_choice, (struct obj *, struct obj *));
E int FDECL(merged, (struct obj **, struct obj **));
#endif
E int FDECL(pickup, (int));
E int FDECL(pickup_object, (struct obj *, long, BOOLEAN_P));
-E int FDECL(query_category,
- (const char *, struct obj *, int, menu_item **, int));
-E int FDECL(query_objlist, (const char *, struct obj *, int, menu_item **,
- int, boolean (*)(OBJ_P)));
+E int FDECL(query_category, (const char *, struct obj *, int,
+ menu_item **, int));
+E int FDECL(query_objlist, (const char *, struct obj **, int,
+ menu_item **, int, boolean (*)(OBJ_P)));
E struct obj *FDECL(pick_obj, (struct obj *));
E int NDECL(encumber_msg);
E int NDECL(doloot);
#define BASICENLIGHTENMENT 1 /* show mundane stuff */
#define MAGICENLIGHTENMENT 2 /* show intrinsics and such */
#define ENL_GAMEINPROGRESS 0
-#define ENL_GAMEOVERALIVE 1 /* ascension, escape, quit, trickery */
-#define ENL_GAMEOVERDEAD 2
+#define ENL_GAMEOVERALIVE 1 /* ascension, escape, quit, trickery */
+#define ENL_GAMEOVERDEAD 2
+
+/* control flags for sortloot() */
+#define SORTLOOT_PACK 0x01
+#define SORTLOOT_INVLET 0x02
+#define SORTLOOT_LOOT 0x04
/* Macros for messages referring to hands, eyes, feet, etc... */
#define ARM 0
unsigned owt;
long quan; /* number of items */
- schar spe; /* quality of weapon, armor or ring (+ or -)
- number of charges for wand ( >= -1 )
- marks your eggs, tin variety and spinach tins
- royal coffers for a court ( == 2)
- tells which fruit a fruit is
- special for uball and amulet
+ schar spe; /* quality of weapon, armor or ring (+ or -);
+ number of charges for wand or charged tool ( >= -1 );
+ marks your eggs, tin variety and spinach tins;
+ Schroedinger's Box (1) or royal coffers for a court (2);
+ tells which fruit a fruit is;
+ special for uball and amulet;
+ scroll of mail (normal==0, bones or wishing==1, written==2);
historic and gender for statues */
#define STATUE_HISTORIC 0x01
#define STATUE_MALE 0x02
bypass_objlist(invent, FALSE);
} else {
/* should coordinate with perm invent, maybe not show worn items */
- n = query_objlist("What would you like to drop?", invent,
- USE_INVLET | INVORDER_SORT, &pick_list, PICK_ANY,
+ n = query_objlist("What would you like to drop?", &invent,
+ (USE_INVLET | INVORDER_SORT), &pick_list, PICK_ANY,
all_categories ? allow_all : allow_category);
if (n > 0) {
/*
all_worn_categories = TRUE;
}
- n = query_objlist("What do you want to take off?", invent,
- SIGNAL_NOMENU | USE_INVLET | INVORDER_SORT, &pick_list,
- PICK_ANY,
+ n = query_objlist("What do you want to take off?", &invent,
+ (SIGNAL_NOMENU | USE_INVLET | INVORDER_SORT),
+ &pick_list, PICK_ANY,
all_worn_categories ? is_worn : is_worn_by_type);
if (n > 0) {
for (i = 0; i < n; i++)
boolean identified, all_containers, reportempty;
{
register struct obj *box, *obj;
- struct obj **oarray;
- int i, n;
- char *invlet;
char buf[BUFSZ];
boolean cat, deadcat;
} else if (box->cobj) {
winid tmpwin = create_nhwindow(NHW_MENU);
- /* count the number of items */
- for (n = 0, obj = box->cobj; obj; obj = obj->nobj)
- n++;
- /* Make a temporary array to store the objects sorted */
- oarray = objarr_init(n);
-
- /* Add objects to the array */
- i = 0;
- invlet = flags.inv_order;
- nextclass:
- for (obj = box->cobj; obj; obj = obj->nobj) {
- if (!flags.sortpack || obj->oclass == *invlet) {
- objarr_set(
- obj, i++, oarray,
- (flags.sortloot == 'f' || flags.sortloot == 'l'));
- }
- } /* for loop */
- if (flags.sortpack) {
- if (*++invlet)
- goto nextclass;
- }
-
+ sortloot(&box->cobj,
+ (((flags.sortloot == 'l' || flags.sortloot == 'f')
+ ? SORTLOOT_LOOT : 0)
+ | (flags.sortpack ? SORTLOOT_PACK : 0)),
+ FALSE);
Sprintf(buf, "Contents of %s:", the(xname(box)));
putstr(tmpwin, 0, buf);
putstr(tmpwin, 0, "");
- for (i = 0; i < n; i++) {
- obj = oarray[i];
+ for (obj = box->cobj; obj; obj = obj->nobj) {
if (identified) {
makeknown(obj->otyp);
- obj->known = obj->bknown = obj->dknown = obj->rknown =
- 1;
+ obj->known = obj->bknown = obj->dknown
+ = obj->rknown = 1;
if (Is_container(obj) || obj->otyp == STATUE)
obj->cknown = obj->lknown = 1;
}
putstr(tmpwin, 0, doname(obj));
}
- free(oarray);
if (cat)
putstr(tmpwin, 0, "Schroedinger's cat");
else if (deadcat)
#define CONTAINED_SYM '>' /* designator for inside a container */
#define HANDS_SYM '-'
-STATIC_DCL int FDECL(CFDECLSPEC sortloot_cmp, (struct obj *, struct obj *));
+STATIC_DCL int FDECL(CFDECLSPEC sortloot_cmp, (const genericptr,
+ const genericptr));
STATIC_DCL void NDECL(reorder_invent);
STATIC_DCL void FDECL(noarmor, (BOOLEAN_P));
STATIC_DCL void FDECL(invdisp_nothing, (const char *, const char *));
STATIC_DCL char FDECL(display_pickinv, (const char *, const char *,
BOOLEAN_P, long *));
STATIC_DCL char FDECL(display_used_invlets, (CHAR_P));
-STATIC_DCL void FDECL(tally_BUCX,
- (struct obj *, int *, int *, int *, int *, int *));
+STATIC_DCL void FDECL(tally_BUCX, (struct obj *,
+ int *, int *, int *, int *, int *));
STATIC_DCL boolean FDECL(this_type_only, (struct obj *));
STATIC_DCL void NDECL(dounpaid);
STATIC_DCL struct obj *FDECL(find_unpaid, (struct obj *, struct obj **));
*/
static char venom_inv[] = { VENOM_CLASS, 0 }; /* (constant) */
-STATIC_OVL int CFDECLSPEC
-sortloot_cmp(obj1, obj2)
-struct obj *obj1;
-struct obj *obj2;
-{
- int val1 = 0;
- int val2 = 0;
+struct sortloot_item {
+ struct obj *obj;
+ int indx;
+};
+unsigned sortlootmode = 0;
- /* Sort object names in lexicographical order, ignoring quantity. */
- int name_cmp = strcmpi(cxname_singular(obj1), cxname_singular(obj2));
+/* qsort comparison routine for sortloot() */
+STATIC_OVL int CFDECLSPEC
+sortloot_cmp(vptr1, vptr2)
+const genericptr vptr1;
+const genericptr vptr2;
+{
+ struct sortloot_item *sli1 = (struct sortloot_item *) vptr1,
+ *sli2 = (struct sortloot_item *) vptr2;
+ struct obj *obj1 = sli1->obj,
+ *obj2 = sli2->obj;
+ char *cls1, *cls2;
+ int val1, val2, c, namcmp;
+
+ /* order by object class like inventory display */
+ if ((sortlootmode & SORTLOOT_PACK) != 0) {
+ cls1 = index(flags.inv_order, obj1->oclass);
+ cls2 = index(flags.inv_order, obj2->oclass);
+ if (cls1 != cls2)
+ return (int) (cls1 - cls2);
+
+ /* for armor, group by sub-category */
+ if (obj1->oclass == ARMOR_CLASS) {
+ static int armcat[7 + 1];
+
+ if (!armcat[7]) {
+ /* one-time init; we want to control the order */
+ armcat[ARM_HELM] = 1; /* [2] */
+ armcat[ARM_GLOVES] = 2; /* [3] */
+ armcat[ARM_BOOTS] = 3; /* [4] */
+ armcat[ARM_SHIELD] = 4; /* [1] */
+ armcat[ARM_CLOAK] = 5; /* [5] */
+ armcat[ARM_SHIRT] = 6; /* [6] */
+ armcat[ARM_SUIT] = 7; /* [0] */
+ armcat[7] = 8;
+ }
+ val1 = armcat[objects[obj1->otyp].oc_armcat];
+ val2 = armcat[objects[obj2->otyp].oc_armcat];
+ if (val1 != val2)
+ return val1 - val2;
+
+ /* for weapons, group by ammo (arrows, bolts), launcher (bows),
+ missile (dart, boomerang), stackable (daggers, knives, spears),
+ 'other' (swords, axes, &c), polearm */
+ } else if (obj1->oclass == WEAPON_CLASS) {
+ val1 = objects[obj1->otyp].oc_skill;
+ val1 = (val1 < 0)
+ ? (val1 >= -P_CROSSBOW && val1 <= -P_BOW) ? 1 : 3
+ : (val1 >= P_BOW && val1 <= P_CROSSBOW) ? 2
+ : (val1 == P_SPEAR || val1 == P_DAGGER
+ || val1 == P_KNIFE) ? 4 : !is_pole(obj1) ? 5 : 6;
+ val2 = objects[obj2->otyp].oc_skill;
+ val2 = (val2 < 0)
+ ? (val2 >= -P_CROSSBOW && val2 <= -P_BOW) ? 1 : 3
+ : (val2 >= P_BOW && val2 <= P_CROSSBOW) ? 2
+ : (val2 == P_SPEAR || val2 == P_DAGGER
+ || val2 == P_KNIFE) ? 4 : !is_pole(obj2) ? 5 : 6;
+ if (val1 != val2)
+ return val1 - val2;
+ }
+ }
- if (name_cmp != 0) {
- return name_cmp;
+ /* order by assigned inventory letter */
+ if ((sortlootmode & SORTLOOT_INVLET) != 0) {
+ c = obj1->invlet;
+ val1 = ('a' <= c && c <= 'z') ? (c - 'a' + 2)
+ : ('A' <= c && c <= 'Z') ? (c - 'Z' + 2 + 26)
+ : (c == '$') ? 1
+ : (c == '#') ? 1 + 52 + 1
+ : 1 + 52 + 1 + 1; /* none of the above */
+ c = obj2->invlet;
+ val2 = ('a' <= c <= 'z') ? (c - 'a' + 2)
+ : ('A' <= c <= 'Z') ? (c - 'Z' + 2 + 26)
+ : (c == '$') ? 1
+ : (c == '#') ? 1 + 52 + 1
+ : 1 + 52 + 1 + 1; /* none of the above */
+ if (val1 != val2)
+ return val1 - val2;
}
- /* Sort by BUC. Map blessed to 4, uncursed to 2, cursed to 1, and unknown
- * to 0. */
+ if ((sortlootmode & SORTLOOT_LOOT) == 0)
+ goto tiebreak;
+
+ /* Sort object names in lexicographical order, ignoring quantity. */
+ if ((namcmp = strcmpi(cxname_singular(obj1), cxname_singular(obj2))) != 0)
+ return namcmp;
+
+ /* Sort by BUCX. Map blessed to 4, uncursed to 2, cursed to 1, and
+ unknown to 0. */
val1 = obj1->bknown
- ? (obj1->blessed << 2)
- + ((!obj1->blessed && !obj1->cursed) << 1) + obj1->cursed
- : 0;
+ ? (obj1->blessed << 2)
+ + ((!obj1->blessed && !obj1->cursed) << 1) + obj1->cursed
+ : 0;
val2 = obj2->bknown
- ? (obj2->blessed << 2)
- + ((!obj2->blessed && !obj2->cursed) << 1) + obj2->cursed
- : 0;
- if (val1 != val2) {
- return val2 - val1; /* Because bigger is better. */
- }
+ ? (obj2->blessed << 2)
+ + ((!obj2->blessed && !obj2->cursed) << 1) + obj2->cursed
+ : 0;
+ if (val1 != val2)
+ return val2 - val1; /* bigger is better */
- /* Sort by greasing. This will put the objects in degreasing order. */
+ /* Sort by greasing. This will put the objects in degreasing order. */
val1 = obj1->greased;
val2 = obj2->greased;
- if (val1 != val2) {
- return val2 - val1; /* Because bigger is better. */
- }
+ if (val1 != val2)
+ return val2 - val1; /* bigger is better */
- /* Sort by erosion. The effective amount is what matters. */
+ /* Sort by erosion. The effective amount is what matters. */
val1 = greatest_erosion(obj1);
val2 = greatest_erosion(obj2);
- if (val1 != val2) {
- return val1 - val2; /* Because bigger is WORSE. */
- }
+ if (val1 != val2)
+ return val1 - val2; /* bigger is WORSE */
- /* Sort by erodeproofing. Map known-invulnerable to 1, and both
- * known-vulnerable and unknown-vulnerability to 0, because that's how
- * they're displayed. */
+ /* Sort by erodeproofing. Map known-invulnerable to 1, and both
+ known-vulnerable and unknown-vulnerability to 0, because that's
+ how they're displayed. */
val1 = obj1->rknown && obj1->oerodeproof;
val2 = obj2->rknown && obj2->oerodeproof;
- if (val1 != val2) {
- return val2 - val1; /* Because bigger is better. */
- }
+ if (val1 != val2)
+ return val2 - val1; /* bigger is better */
- /* Sort by enchantment. Map unknown to -1000, which is comfortably below
- * the range of ->spe. */
- val1 = obj1->known ? obj1->spe : -1000;
- val2 = obj2->known ? obj2->spe : -1000;
- if (val1 != val2) {
- return val2 - val1; /* Because bigger is better. */
+ /* Sort by enchantment. Map unknown to -1000, which is comfortably
+ below the range of obj->spe. oc_uses_known means that obj->known
+ matters, which usually indirectly means that obj->spe is relevant.
+ Lots of objects use obj->spe for some other purpose (see obj.h). */
+ if (objects[obj1->otyp].oc_uses_known
+ /* exclude eggs (laid by you) and tins (homemade, pureed, &c) */
+ && obj1->oclass != FOOD_CLASS) {
+ val1 = obj1->known ? obj1->spe : -1000;
+ val2 = obj2->known ? obj2->spe : -1000;
+ if (val1 != val2)
+ return val2 - val1; /* bigger is better */
}
- /* They're identical, as far as we're concerned,
- but we want to force a determistic order between them. */
- return (obj1->o_id > obj2->o_id) ? 1 : -1;
-}
-
-struct obj **
-objarr_init(n)
-int n;
-{
- return (struct obj **) alloc(n * sizeof(struct obj *));
+tiebreak:
+ /* They're identical, as far as we're concerned. We want
+ to force a deterministic order, and do so by producing a
+ stable sort: maintain the original order of equal items. */
+ return (sli2->indx - sli1->indx);
}
void
-objarr_set(otmp, idx, oarray, dosort)
-struct obj *otmp;
-int idx;
-struct obj **oarray;
-boolean dosort;
-{
- if (dosort) {
- int j;
- for (j = idx; j; j--) {
- if (sortloot_cmp(otmp, oarray[j - 1]) > 0)
- break;
- oarray[j] = oarray[j - 1];
+sortloot(olist, mode, by_nexthere)
+struct obj **olist;
+unsigned mode; /* flags for sortloot_cmp() */
+boolean by_nexthere; /* T: traverse via obj->nexthere, F: via obj->nobj */
+{
+ struct sortloot_item *sliarray, osli, nsli;
+ struct obj *o, **nxt_p;
+ unsigned n, i;
+ boolean already_sorted = TRUE;
+
+ sortlootmode = mode; /* extra input for sortloot_cmp() */
+ for (n = osli.indx = 0, osli.obj = *olist; (o = osli.obj) != 0;
+ osli = nsli) {
+ nsli.obj = by_nexthere ? o->nexthere : o->nobj;
+ nsli.indx = (int) ++n;
+ if (nsli.obj && already_sorted
+ && sortloot_cmp((genericptr_t) &osli, (genericptr_t) &nsli) > 0)
+ already_sorted = FALSE;
+ }
+ if (n > 1 && !already_sorted) {
+ sliarray = (struct sortloot_item *) alloc(n * sizeof *sliarray);
+ for (i = 0, o = *olist; o;
+ ++i, o = by_nexthere ? o->nexthere : o->nobj)
+ sliarray[i].obj = o, sliarray[i].indx = (int) i;
+
+ qsort((genericptr_t) sliarray, n, sizeof *sliarray, sortloot_cmp);
+ for (i = 0; i < n; ++i) {
+ o = sliarray[i].obj;
+ nxt_p = by_nexthere ? &(o->nexthere) : &(o->nobj);
+ *nxt_p = (i < n - 1) ? sliarray[i + 1].obj : (struct obj *) 0;
}
- oarray[j] = otmp;
- } else {
- oarray[idx] = otmp;
+ *olist = sliarray[0].obj;
+ free((genericptr_t) sliarray);
}
+ sortlootmode = 0;
}
void
while (id_limit) {
Sprintf(buf, "What would you like to identify %s?",
first ? "first" : "next");
- n = query_objlist(buf, invent, SIGNAL_NOMENU | SIGNAL_ESCAPE
- | USE_INVLET | INVORDER_SORT,
+ n = query_objlist(buf, &invent, (SIGNAL_NOMENU | SIGNAL_ESCAPE
+ | USE_INVLET | INVORDER_SORT),
&pick_list, PICK_ANY, not_fully_identified);
if (n > 0) {
struct obj *otmp;
char ilet, ret;
char *invlet = flags.inv_order;
- int i, n, classcount;
+ int n, classcount;
winid win; /* windows being used */
anything any;
menu_item *selected;
- struct obj **oarray;
if (flags.perm_invent && ((lets && *lets) || xtra_choice)) {
/* partial inventory in perm_invent setting; don't operate on
return ret;
}
- /* count the number of items (preliminary count of 0,1,more was 'more'
- and is now obsolete); we have at least 2 items or want to behave as
- if we do (full invent and wiz_identify use this even for 1 item) */
- for (n = 0, otmp = invent; otmp; otmp = otmp->nobj)
- if (!lets || !*lets || index(lets, otmp->invlet))
- n++;
- oarray = objarr_init(n);
- /* Add objects to the array */
- i = 0;
- for (otmp = invent; otmp; otmp = otmp->nobj)
- if (!lets || !*lets || index(lets, otmp->invlet)) {
- objarr_set(otmp, i++, oarray, (flags.sortloot == 'f'));
- }
+ sortloot(&invent,
+ (((flags.sortloot == 'f') ? SORTLOOT_LOOT : SORTLOOT_INVLET)
+ | (flags.sortpack ? SORTLOOT_PACK : 0)),
+ FALSE);
start_menu(win);
any = zeroany;
}
nextclass:
classcount = 0;
- for (i = 0; i < n; i++) {
- otmp = oarray[i];
+ for (otmp = invent; otmp; otmp = otmp->nobj) {
if (!flags.sortpack || otmp->oclass == *invlet) {
any = zeroany; /* all bits zero */
ilet = otmp->invlet;
goto nextclass;
}
}
- free(oarray);
end_menu(win, (char *) 0);
n = select_menu(win, want_reply ? PICK_ONE : PICK_NONE, &selected);
}
this_type = oclass;
}
- if (query_objlist((char *) 0, invent,
- (flags.invlet_constant ? USE_INVLET : 0)
- | INVORDER_SORT,
+ if (query_objlist((char *) 0, &invent,
+ ((flags.invlet_constant ? USE_INVLET : 0)
+ | INVORDER_SORT),
&pick_list, PICK_NONE, this_type_only) > 0)
free((genericptr_t) pick_list);
return 0;
*/
youmonst.data = mon->data;
- n = query_objlist(title ? title : tmp, mon->minvent,
- INVORDER_SORT | (incl_hero ? INCLUDE_HERO : 0),
+ n = query_objlist(title ? title : tmp, &(mon->minvent),
+ (INVORDER_SORT | (incl_hero ? INCLUDE_HERO : 0)),
&selected,
(dflags & MINV_NOLET) ? PICK_NONE : PICK_ONE,
do_all ? allow_all : worn_wield_only);
"that");
if (obj->cobj) {
- n = query_objlist(qbuf, obj->cobj, INVORDER_SORT, &selected,
- PICK_NONE, allow_all);
+ n = query_objlist(qbuf, &(obj->cobj), INVORDER_SORT,
+ &selected, PICK_NONE, allow_all);
} else {
invdisp_nothing(qbuf, "(empty)");
n = 0;
if (n) {
only.x = x;
only.y = y;
- if (query_objlist("Things that are buried here:", level.buriedobjlist,
- INVORDER_SORT, &selected, PICK_NONE, only_here) > 0)
+ if (query_objlist("Things that are buried here:",
+ &level.buriedobjlist, INVORDER_SORT,
+ &selected, PICK_NONE, only_here) > 0)
free((genericptr_t) selected);
only.x = only.y = 0;
}
#define CONTAINED_SYM '>' /* from invent.c */
STATIC_DCL void FDECL(simple_look, (struct obj *, BOOLEAN_P));
-STATIC_DCL boolean
-FDECL(query_classes, (char *, boolean *, boolean *, const char *,
- struct obj *, BOOLEAN_P, int *));
+STATIC_DCL boolean FDECL(query_classes, (char *, boolean *, boolean *,
+ const char *, struct obj *,
+ BOOLEAN_P, int *));
STATIC_DCL boolean FDECL(fatal_corpse_mistake, (struct obj *, BOOLEAN_P));
STATIC_DCL void FDECL(check_here, (BOOLEAN_P));
STATIC_DCL boolean FDECL(n_or_more, (struct obj *));
/* define for query_objlist() and autopickup() */
#define FOLLOW(curr, flags) \
- (((flags) &BY_NEXTHERE) ? (curr)->nexthere : (curr)->nobj)
+ (((flags) & BY_NEXTHERE) ? (curr)->nexthere : (curr)->nobj)
/*
* How much the weight of the given container will change when the given
/* if you can figure this out, give yourself a hearty pat on the back... */
#define GOLD_CAPACITY(w, n) (((w) * -100L) - ((n) + 50L) - 1L)
-/* A variable set in use_container(), to be used by the callback routines */
-/* in_container() and out_container() from askchain() and use_container(). */
-/* Also used by menu_loot() and container_gone(). */
+/* A variable set in use_container(), to be used by the callback routines
+ in_container() and out_container() from askchain() and use_container().
+ Also used by menu_loot() and container_gone(). */
static NEARDATA struct obj *current_container;
static NEARDATA boolean abort_looting;
#define Icebox (current_container->otyp == ICE_BOX)
oclasses[oclassct] = '\0';
} else {
if (!where)
- where =
- !strcmp(action, "pick up")
- ? "here"
+ where = !strcmp(action, "pick up") ? "here"
: !strcmp(action, "take out") ? "inside" : "";
if (*where)
There("are no %c's %s.", sym, where);
if (Role_if(PM_PRIEST))
obj->bknown = TRUE;
+
/*
* There are three types of filters possible and the first and
* third can have more than one entry:
* in accepting all scrolls and potions regardless of bless/curse
* state plus all blessed non-scroll, non-potion objects.)
*/
+
/* if class is expected but obj's class is not in the list, reject */
if (class_filter && !index(valid_menu_classes, obj->oclass))
return FALSE;
count = 0;
if (!u.uswallow) {
- struct trap *ttmp = t_at(u.ux, u.uy);
+ struct trap *ttmp;
+
/* no auto-pick if no-pick move, nothing there, or in a pool */
if (autopickup && (context.nopick || !OBJ_AT(u.ux, u.uy)
|| (is_pool(u.ux, u.uy) && !Underwater)
read_engr_at(u.ux, u.uy);
return 0;
}
-
/* no pickup if levitating & not on air or water level */
if (!can_reach_floor(TRUE)) {
if ((multi && !context.run) || (autopickup && !flags.pickup)
- || (ttmp && uteetering_at_seen_pit(ttmp)))
+ || ((ttmp = t_at(u.ux, u.uy)) != 0
+ && uteetering_at_seen_pit(ttmp)))
read_engr_at(u.ux, u.uy);
return 0;
}
if (flags.menu_style != MENU_TRADITIONAL || iflags.menu_requested) {
/* use menus exclusively */
+ traverse_how |= AUTOSELECT_SINGLE | INVORDER_SORT;
if (count) { /* looking for N of something */
char qbuf[QBUFSZ];
Sprintf(qbuf, "Pick %d of what?", count);
val_for_n_or_more = count; /* set up callback selector */
- n = query_objlist(qbuf, objchain, traverse_how | AUTOSELECT_SINGLE
- | INVORDER_SORT,
+ n = query_objlist(qbuf, &objchain, traverse_how,
&pick_list, PICK_ONE, n_or_more);
/* correct counts, if any given */
for (i = 0; i < n; i++)
pick_list[i].count = count;
} else {
- n = query_objlist("Pick up what?", objchain,
- traverse_how | AUTOSELECT_SINGLE | INVORDER_SORT
- | FEEL_COCKATRICE,
+ n = query_objlist("Pick up what?", &objchain,
+ (traverse_how | FEEL_COCKATRICE),
&pick_list, PICK_ANY, all_but_uchain);
}
menu_pickup:
selective = FALSE; /* ask for each item */
/* check for more than one object */
- for (obj = objchain; obj;
- obj = (traverse_how == BY_NEXTHERE) ? obj->nexthere : obj->nobj)
+ for (obj = objchain; obj; obj = FOLLOW(obj, traverse_how))
ct++;
if (ct == 1 && count) {
There("are %s objects here.", (ct <= 10) ? "several" : "many");
if (!query_classes(oclasses, &selective, &all_of_a_type,
"pick up", objchain,
- traverse_how == BY_NEXTHERE, &via_menu)) {
+ (traverse_how & BY_NEXTHERE) ? TRUE : FALSE,
+ &via_menu)) {
if (!via_menu)
return 0;
- n = query_objlist("Pick up what?", objchain,
- traverse_how
- | (selective ? 0 : INVORDER_SORT),
+ if (selective)
+ traverse_how |= INVORDER_SORT;
+ n = query_objlist("Pick up what?", &objchain, traverse_how,
&pick_list, PICK_ANY,
(via_menu == -2) ? allow_all
: allow_category);
}
for (obj = objchain; obj; obj = obj2) {
- if (traverse_how == BY_NEXTHERE)
- obj2 = obj->nexthere; /* perhaps obj will be picked up */
- else
- obj2 = obj->nobj;
- lcount = -1L;
-
+ obj2 = FOLLOW(obj, traverse_how);
if (!selective && oclasses[0] && !index(oclasses, obj->oclass))
continue;
+ lcount = -1L;
if (!all_of_a_type) {
char qbuf[BUFSZ];
lcount = (long) yn_number;
if (lcount > obj->quan)
lcount = obj->quan;
- /* fall thru */
+ /*FALLTHRU*/
default: /* 'y' */
break;
}
* SIGNAL_NOMENU - Return -1 rather than 0 if nothing passes "allow".
* SIGNAL_ESCAPE - Return -1 rather than 0 if player uses ESC to
* pick nothing.
+ * FEEL_COCKATRICE - touch corpse.
*/
int
-query_objlist(qstr, olist, qflags, pick_list, how, allow)
+query_objlist(qstr, olist_p, qflags, pick_list, how, allow)
const char *qstr; /* query string */
-struct obj *olist; /* the list to pick from */
+struct obj **olist_p; /* the list to pick from */
int qflags; /* options to control the query */
menu_item **pick_list; /* return list of items picked */
int how; /* type of query */
{
int i, n, actualn;
winid win;
- struct obj *curr, *last, fake_hero_object;
- struct obj **oarray;
+ struct obj *curr, *last, fake_hero_object, *olist = *olist_p;
char *pack;
anything any;
- boolean printed_type_name, sorted = (qflags & INVORDER_SORT) != 0,
- engulfer = (qflags & INCLUDE_HERO) != 0;
+ boolean printed_type_name,
+ sorted = (qflags & INVORDER_SORT) != 0,
+ engulfer = (qflags & INCLUDE_HERO) != 0;
*pick_list = (menu_item *) 0;
if (!olist && !engulfer)
return (qflags & SIGNAL_NOMENU) ? -1 : 0;
if (n == 1 && (qflags & AUTOSELECT_SINGLE)) {
- *pick_list = (menu_item *) alloc(sizeof(menu_item));
+ *pick_list = (menu_item *) alloc(sizeof (menu_item));
(*pick_list)->item.a_obj = last;
(*pick_list)->count = last->quan;
return 1;
}
- oarray = objarr_init(actualn);
- /* Add objects to the array */
- i = 0;
- for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
- if ((*allow)(curr)) {
- objarr_set(curr, i++, oarray, (flags.sortloot == 'f'
- || (flags.sortloot == 'l'
- && !(qflags & USE_INVLET))));
- }
+ if (sorted) {
+ sortloot(&olist,
+ (((flags.sortloot == 'f'
+ || (flags.sortloot == 'l' && !(qflags & USE_INVLET)))
+ ? SORTLOOT_LOOT
+ : (qflags & USE_INVLET) ? SORTLOOT_INVLET : 0)
+ | (flags.sortpack ? SORTLOOT_PACK : 0)),
+ (qflags & BY_NEXTHERE) ? TRUE : FALSE);
+ *olist_p = olist;
}
win = create_nhwindow(NHW_MENU);
start_menu(win);
any = zeroany;
-
/*
* Run through the list and add the objects to the menu. If
* INVORDER_SORT is set, we'll run through the list once for
pack = flags.inv_order;
do {
printed_type_name = FALSE;
- for (i = 0; i < actualn; i++) {
- curr = oarray[i];
+ for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
+ if (sorted && curr->oclass != *pack)
+ continue;
if ((qflags & FEEL_COCKATRICE) && curr->otyp == CORPSE
&& will_feel_cockatrice(curr, FALSE)) {
destroy_nhwindow(win); /* stop the menu and revert */
(void) look_here(0, FALSE);
return 0;
}
- if ((!sorted || curr->oclass == *pack) && (*allow)(curr)) {
+ if ((*allow)(curr)) {
/* if sorting, print type name (once only) */
if (sorted && !printed_type_name) {
any = zeroany;
add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
let_to_name(*pack, FALSE,
- (how != PICK_NONE)
- && iflags.menu_head_objsym),
+ ((how != PICK_NONE)
+ && iflags.menu_head_objsym)),
MENU_UNSELECTED);
printed_type_name = TRUE;
}
}
pack++;
} while (sorted && *pack);
- free(oarray);
if (engulfer) {
char buf[BUFSZ];
cc.y = u.uy;
lootcont:
-
if ((num_conts = container_at(cc.x, cc.y, TRUE)) > 0) {
boolean anyfound = FALSE;
*/
if (mtmp && mtmp != u.usteed && (otmp = which_armor(mtmp, W_SADDLE))) {
long unwornmask;
+
if (passed_info)
*passed_info = 1;
- Sprintf(
- qbuf, "Do you want to remove the saddle from %s?",
- x_monnam(mtmp, ARTICLE_THE, (char *) 0, SUPPRESS_SADDLE, FALSE));
+ Sprintf(qbuf, "Do you want to remove the saddle from %s?",
+ x_monnam(mtmp, ARTICLE_THE, (char *) 0,
+ SUPPRESS_SADDLE, FALSE));
if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
if (nolimbs(youmonst.data)) {
You_cant("do that without limbs."); /* not body_part(HAND) */
}
if (otmp->cursed) {
You("can't. The saddle seems to be stuck to %s.",
- x_monnam(mtmp, ARTICLE_THE, (char *) 0, SUPPRESS_SADDLE,
- FALSE));
+ x_monnam(mtmp, ARTICLE_THE, (char *) 0,
+ SUPPRESS_SADDLE, FALSE));
/* the attempt costs you time */
return 1;
}
return 0;
}
}
- /* 3.4.0 introduced the ability to pick things up from within
- swallower's stomach */
+ /* 3.4.0 introduced ability to pick things up from swallower's stomach */
if (u.uswallow) {
int count = passed_info ? *passed_info : 0;
ck_bag(obj)
struct obj *obj;
{
- return current_container && obj != current_container;
+ return (current_container && obj != current_container);
}
/* Returns: -1 to stop, 1 item was removed, 0 item was not removed. */
pline("%s inside the box is still alive!", Monnam(livecat));
(void) christen_monst(livecat, sc);
} else {
- deadcat =
- mk_named_object(CORPSE, &mons[PM_HOUSECAT], box->ox, box->oy, sc);
+ deadcat = mk_named_object(CORPSE, &mons[PM_HOUSECAT],
+ box->ox, box->oy, sc);
if (deadcat) {
obj_extract_self(deadcat);
(void) add_to_container(box, deadcat);
}
pline_The("%s inside the box is dead!",
- Hallucination ? rndmonnam(NULL) : "housecat");
+ Hallucination ? rndmonnam((char *) 0) : "housecat");
}
box->owt = weight(box);
return;
(boolean) (used != 0), more_containers);
}
} else { /* TRADITIONAL or COMBINATION */
- xbuf[0] = '\0'; /* list of extra acceptable responses */
- Strcpy(pbuf, ":"); /* look inside */
+ xbuf[0] = '\0'; /* list of extra acceptable responses */
+ Strcpy(pbuf, ":"); /* look inside */
Strcat(outmaybe ? pbuf : xbuf, "o"); /* take out */
Strcat(inokay ? pbuf : xbuf, "i"); /* put in */
Strcat(outmaybe ? pbuf : xbuf, "b"); /* both */
Strcat(inokay ? pbuf : xbuf, "rs"); /* reversed, stash */
- Strcat(pbuf, " ");
- Strcat(more_containers ? pbuf : xbuf, "n");
+ Strcat(pbuf, " "); /* separator */
+ Strcat(more_containers ? pbuf : xbuf, "n"); /* next container */
Strcat(pbuf, "q"); /* quit */
if (iflags.cmdassist)
/* this unintentionally allows user to answer with 'o' or
if (!put_in)
current_container->cknown = 1;
Sprintf(buf, "%s what?", action);
- n = query_objlist(buf, put_in ? invent : current_container->cobj,
+ n = query_objlist(buf, put_in ? &invent : &(current_container->cobj),
mflags, &pick_list, PICK_ANY,
all_categories ? allow_all : allow_category);
if (n) {