menustyle:full's 'A' choice
Change how menu choice 'A' (auto-select everything) works. It will now auto-select all things that match any other choices (object class(es) or BUCX state(s) or possibly unpaid status). So it still skips the second menu of specific objects. And it still picks all objects when it is the only choice or if player uses '.' to select it along with all the rest of the first menu's possibilities. This change won't help anyone who picks 'A' without really meaning to. (Maybe add a paranoid_confirm setting to for full-menu-A?) Affects container apply/#loot and Drop-multiple. The invent.c part is just formatting.
This commit is contained in:
@@ -438,6 +438,10 @@ magic mapping performed while engulfed or underwater would display whole map
|
|||||||
but then not switch back to the engulfed or underwater restricted view
|
but then not switch back to the engulfed or underwater restricted view
|
||||||
#overview used hardcoded bold and inverse for highlighting; switch to the
|
#overview used hardcoded bold and inverse for highlighting; switch to the
|
||||||
'menu_headings' option value so player has some control
|
'menu_headings' option value so player has some control
|
||||||
|
for menustyle:full, the 'A' menu choice to auto-select everything now only
|
||||||
|
does so if no other choices have been picked; when any have (object
|
||||||
|
class or BUCX state or both), it auto-selects every item that matches
|
||||||
|
those choices (so still skips the second menu) rather than every item
|
||||||
|
|
||||||
|
|
||||||
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
||||||
|
|||||||
25
src/do.c
25
src/do.c
@@ -819,8 +819,7 @@ menu_drop(int retry)
|
|||||||
long cnt;
|
long cnt;
|
||||||
struct obj *otmp, *otmp2;
|
struct obj *otmp, *otmp2;
|
||||||
menu_item *pick_list;
|
menu_item *pick_list;
|
||||||
boolean all_categories = TRUE;
|
boolean all_categories = TRUE, drop_everything = FALSE, autopick = FALSE;
|
||||||
boolean drop_everything = FALSE;
|
|
||||||
|
|
||||||
if (retry) {
|
if (retry) {
|
||||||
all_categories = (retry == -2);
|
all_categories = (retry == -2);
|
||||||
@@ -834,12 +833,14 @@ menu_drop(int retry)
|
|||||||
if (!n)
|
if (!n)
|
||||||
goto drop_done;
|
goto drop_done;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
if (pick_list[i].item.a_int == ALL_TYPES_SELECTED)
|
if (pick_list[i].item.a_int == ALL_TYPES_SELECTED) {
|
||||||
all_categories = TRUE;
|
all_categories = TRUE;
|
||||||
else if (pick_list[i].item.a_int == 'A')
|
} else if (pick_list[i].item.a_int == 'A') {
|
||||||
drop_everything = TRUE;
|
drop_everything = autopick = TRUE;
|
||||||
else
|
} else {
|
||||||
add_valid_menu_class(pick_list[i].item.a_int);
|
add_valid_menu_class(pick_list[i].item.a_int);
|
||||||
|
drop_everything = FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free((genericptr_t) pick_list);
|
free((genericptr_t) pick_list);
|
||||||
} else if (flags.menu_style == MENU_COMBINATION) {
|
} else if (flags.menu_style == MENU_COMBINATION) {
|
||||||
@@ -856,7 +857,7 @@ menu_drop(int retry)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drop_everything) {
|
if (autopick) {
|
||||||
/*
|
/*
|
||||||
* Dropping a burning potion of oil while levitating can cause
|
* Dropping a burning potion of oil while levitating can cause
|
||||||
* an explosion which might destroy some of hero's inventory,
|
* an explosion which might destroy some of hero's inventory,
|
||||||
@@ -870,10 +871,16 @@ menu_drop(int retry)
|
|||||||
* Use the bypass bit to mark items already processed (hence
|
* Use the bypass bit to mark items already processed (hence
|
||||||
* not droppable) and rescan inventory until no unbypassed
|
* not droppable) and rescan inventory until no unbypassed
|
||||||
* items remain.
|
* items remain.
|
||||||
|
*
|
||||||
|
* FIXME? if something explodes, or even breaks, we probably
|
||||||
|
* ought to halt the traversal or perhaps ask player whether
|
||||||
|
* to halt it.
|
||||||
*/
|
*/
|
||||||
bypass_objlist(g.invent, FALSE); /* clear bypass bit for invent */
|
bypass_objlist(g.invent, FALSE); /* clear bypass bit for invent */
|
||||||
while ((otmp = nxt_unbypassed_obj(g.invent)) != 0)
|
while ((otmp = nxt_unbypassed_obj(g.invent)) != 0) {
|
||||||
n_dropped += drop(otmp);
|
if (drop_everything || all_categories || allow_category(otmp))
|
||||||
|
n_dropped += drop(otmp);
|
||||||
|
}
|
||||||
/* we might not have dropped everything (worn armor, welded weapon,
|
/* we might not have dropped everything (worn armor, welded weapon,
|
||||||
cursed loadstones), so reset any remaining inventory to normal */
|
cursed loadstones), so reset any remaining inventory to normal */
|
||||||
bypass_objlist(g.invent, FALSE);
|
bypass_objlist(g.invent, FALSE);
|
||||||
|
|||||||
29
src/invent.c
29
src/invent.c
@@ -289,14 +289,15 @@ loot_xname(struct obj *obj)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* '$'==1, 'a'-'z'==2..27, 'A'-'Z'==28..53, '#'==54, catchall 55 */
|
||||||
static int
|
static int
|
||||||
invletter_value(char c)
|
invletter_value(char c)
|
||||||
{
|
{
|
||||||
return ('a' <= c && c <= 'z') ? (c - 'a' + 2)
|
return ('a' <= c && c <= 'z') ? (c - 'a' + 2)
|
||||||
: ('A' <= c && c <= 'Z') ? (c - 'A' + 2 + 26)
|
: ('A' <= c && c <= 'Z') ? (c - 'A' + 2 + 26)
|
||||||
: (c == '$') ? 1
|
: (c == '$') ? 1
|
||||||
: (c == '#') ? 1 + 52 + 1
|
: (c == '#') ? 1 + 52 + 1
|
||||||
: 1 + 52 + 1 + 1; /* none of the above */
|
: 1 + 52 + 1 + 1; /* none of the above (shouldn't happen) */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* qsort comparison routine for sortloot() */
|
/* qsort comparison routine for sortloot() */
|
||||||
@@ -467,10 +468,11 @@ sortloot_cmp(const genericptr vptr1, const genericptr vptr2)
|
|||||||
* instead of simple 'struct obj *' entries.
|
* instead of simple 'struct obj *' entries.
|
||||||
*/
|
*/
|
||||||
Loot *
|
Loot *
|
||||||
sortloot(struct obj **olist, /* previous version might have changed *olist, we don't */
|
sortloot(
|
||||||
unsigned mode, /* flags for sortloot_cmp() */
|
struct obj **olist, /* old version might have changed *olist, we don't */
|
||||||
boolean by_nexthere, /* T: traverse via obj->nexthere, F: via obj->nobj */
|
unsigned mode, /* flags for sortloot_cmp() */
|
||||||
boolean (*filterfunc)(OBJ_P))
|
boolean by_nexthere, /* T: traverse via obj->nexthere, F: via obj->nobj */
|
||||||
|
boolean (*filterfunc)(struct obj *)) /* optional filter */
|
||||||
{
|
{
|
||||||
Loot *sliarray;
|
Loot *sliarray;
|
||||||
struct obj *o;
|
struct obj *o;
|
||||||
@@ -527,11 +529,12 @@ unsortloot(Loot **loot_array_p)
|
|||||||
free((genericptr_t) *loot_array_p), *loot_array_p = (Loot *) 0;
|
free((genericptr_t) *loot_array_p), *loot_array_p = (Loot *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* 3.6.0 'revamp' */
|
#if 0 /* 3.6.0 'revamp' -- simpler than current, but ultimately too simple */
|
||||||
void
|
void
|
||||||
sortloot(struct obj **olist, unsigned mode, /* flags for sortloot_cmp() */
|
sortloot(
|
||||||
boolean by_nexthere) /* T: traverse via obj->nexthere,
|
struct obj **olist,
|
||||||
F: via obj->nobj */
|
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 sortloot_item *sliarray, osli, nsli;
|
||||||
struct obj *o, **nxt_p;
|
struct obj *o, **nxt_p;
|
||||||
@@ -623,7 +626,7 @@ reorder_invent(void)
|
|||||||
* isn't nearly as inefficient as it may first appear.
|
* isn't nearly as inefficient as it may first appear.
|
||||||
*/
|
*/
|
||||||
need_more_sorting = FALSE;
|
need_more_sorting = FALSE;
|
||||||
for (otmp = g.invent, prev = 0; otmp;) {
|
for (otmp = g.invent, prev = 0; otmp; ) {
|
||||||
next = otmp->nobj;
|
next = otmp->nobj;
|
||||||
if (next && inv_rank(next) < inv_rank(otmp)) {
|
if (next && inv_rank(next) < inv_rank(otmp)) {
|
||||||
need_more_sorting = TRUE;
|
need_more_sorting = TRUE;
|
||||||
|
|||||||
45
src/pickup.c
45
src/pickup.c
@@ -1143,7 +1143,7 @@ query_category(const char *qstr, /* query string */
|
|||||||
itemflags = MENU_ITEMFLAGS_SKIPINVERT;
|
itemflags = MENU_ITEMFLAGS_SKIPINVERT;
|
||||||
add_menu(win, &nul_glyphinfo, &any, invlet, 0, ATR_NONE,
|
add_menu(win, &nul_glyphinfo, &any, invlet, 0, ATR_NONE,
|
||||||
(qflags & WORN_TYPES) ? "Auto-select every item being worn"
|
(qflags & WORN_TYPES) ? "Auto-select every item being worn"
|
||||||
: "Auto-select every item",
|
: "Auto-select every relevant item",
|
||||||
itemflags);
|
itemflags);
|
||||||
|
|
||||||
any = cg.zeroany;
|
any = cg.zeroany;
|
||||||
@@ -2899,7 +2899,7 @@ static int
|
|||||||
menu_loot(int retry, boolean put_in)
|
menu_loot(int retry, boolean put_in)
|
||||||
{
|
{
|
||||||
int n, i, n_looted = 0;
|
int n, i, n_looted = 0;
|
||||||
boolean all_categories = TRUE, loot_everything = FALSE;
|
boolean all_categories = TRUE, loot_everything = FALSE, autopick = FALSE;
|
||||||
char buf[BUFSZ];
|
char buf[BUFSZ];
|
||||||
const char *action = put_in ? "Put in" : "Take out";
|
const char *action = put_in ? "Put in" : "Take out";
|
||||||
struct obj *otmp, *otmp2;
|
struct obj *otmp, *otmp2;
|
||||||
@@ -2918,30 +2918,41 @@ menu_loot(int retry, boolean put_in)
|
|||||||
if (!n)
|
if (!n)
|
||||||
return 0;
|
return 0;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
if (pick_list[i].item.a_int == 'A')
|
if (pick_list[i].item.a_int == 'A') {
|
||||||
loot_everything = TRUE;
|
loot_everything = autopick = TRUE;
|
||||||
else if (pick_list[i].item.a_int == ALL_TYPES_SELECTED)
|
} else if (pick_list[i].item.a_int == ALL_TYPES_SELECTED) {
|
||||||
all_categories = TRUE;
|
all_categories = TRUE;
|
||||||
else
|
} else {
|
||||||
add_valid_menu_class(pick_list[i].item.a_int);
|
add_valid_menu_class(pick_list[i].item.a_int);
|
||||||
|
loot_everything = FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free((genericptr_t) pick_list);
|
free((genericptr_t) pick_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loot_everything) {
|
if (autopick) {
|
||||||
|
int (*inout_func)(struct obj *); /* in_container or out_container */
|
||||||
|
struct obj *firstobj;
|
||||||
|
|
||||||
if (!put_in) {
|
if (!put_in) {
|
||||||
g.current_container->cknown = 1;
|
g.current_container->cknown = 1;
|
||||||
for (otmp = g.current_container->cobj; otmp; otmp = otmp2) {
|
inout_func = out_container;
|
||||||
otmp2 = otmp->nobj;
|
firstobj = g.current_container->cobj;
|
||||||
res = out_container(otmp);
|
|
||||||
if (res < 0)
|
|
||||||
break;
|
|
||||||
n_looted += res;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (otmp = g.invent; otmp && g.current_container; otmp = otmp2) {
|
inout_func = in_container;
|
||||||
otmp2 = otmp->nobj;
|
firstobj = g.invent;
|
||||||
res = in_container(otmp);
|
}
|
||||||
|
/*
|
||||||
|
* Note: for put_in, current_container might be destroyed during
|
||||||
|
* mid-traversal by a magic bag explosion.
|
||||||
|
* Note too: items are processed in internal list order rather
|
||||||
|
* than menu display order ('sortpack') or 'sortloot' order;
|
||||||
|
* for put_in that should be item->invlet order so reasonable.
|
||||||
|
*/
|
||||||
|
for (otmp = firstobj; otmp && g.current_container; otmp = otmp2) {
|
||||||
|
otmp2 = otmp->nobj;
|
||||||
|
if (loot_everything || all_categories || allow_category(otmp)) {
|
||||||
|
res = (*inout_func)(otmp);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
break;
|
break;
|
||||||
n_looted += res;
|
n_looted += res;
|
||||||
|
|||||||
Reference in New Issue
Block a user