Merge branch 'NetHack-3.7' of https://rodney.nethack.org:20040/git/NHsource into NetHack-3.7
This commit is contained in:
@@ -1084,6 +1084,7 @@ counting "just picked up" items when deciding what pseudo-classes should be
|
||||
changes to stair internals resulted in summoned Kops blockcading the stairs up
|
||||
rather than intended stairs down
|
||||
dumplog's list of "major events" showed all logged events, not just major ones
|
||||
pickup via menu ignored player-specified count when picking up gold
|
||||
|
||||
curses: 'msg_window' option wasn't functional for curses unless the binary
|
||||
also included tty support
|
||||
|
||||
@@ -313,7 +313,7 @@ opt_##a,
|
||||
NHOPTO("menu colors", o_menu_colors, BUFSZ, opt_in, set_in_game,
|
||||
No, Yes, No, NoAlias, "edit menu colors")
|
||||
NHOPTC(menuinvertmode, 5, opt_in, set_in_game, No, Yes, No, No, NoAlias,
|
||||
"behaviour of menu iverts")
|
||||
"experimental behaviour of menu inverts")
|
||||
NHOPTC(menustyle, MENUTYPELEN, opt_in, set_in_game, Yes, Yes, No, Yes,
|
||||
NoAlias, "user interface for object selection")
|
||||
NHOPTO("message types", o_message_types, BUFSZ, opt_in, set_in_game,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 invent.c $NHDT-Date: 1629409876 2021/08/19 21:51:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.339 $ */
|
||||
/* NetHack 3.7 invent.c $NHDT-Date: 1647472704 2022/03/16 23:18:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.355 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -2674,7 +2674,7 @@ display_pickinv(
|
||||
Sprintf(eos(prompt), " (%s for all)",
|
||||
visctrl(iflags.override_ID));
|
||||
add_menu(win, &nul_glyphinfo, &any, '_', iflags.override_ID,
|
||||
ATR_NONE, prompt, MENU_ITEMFLAGS_NONE);
|
||||
ATR_NONE, prompt, MENU_ITEMFLAGS_SKIPINVERT);
|
||||
gotsomething = TRUE;
|
||||
}
|
||||
} else if (xtra_choice) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 options.c $NHDT-Date: 1645000577 2022/02/16 08:36:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.540 $ */
|
||||
/* NetHack 3.7 options.c $NHDT-Date: 1647472681 2022/03/16 23:18:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.542 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Michael Allison, 2008. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -5838,6 +5838,19 @@ initoptions_init(void)
|
||||
/* only used by curses */
|
||||
iflags.wc2_windowborders = 2; /* 'Auto' */
|
||||
|
||||
/*
|
||||
* A few menus have certain items (typically operate-on-everything or
|
||||
* change-subset or sort or help entries) flagged as 'skip-invert' to
|
||||
* control how whole-page and whole-menu operations affect them.
|
||||
* 'menuinvertmode' controls how that functions:
|
||||
* 0: ignore 'skip-invert' flag on menu items (used to be the default);
|
||||
* 1: don't toggle 'skip-invert' items On for set-all/set-page/invert-
|
||||
* all/invert-page but do toggle Off if already set (default);
|
||||
* 2: don't toggle 'skip-invert' items either On of Off for set-all/
|
||||
* set-page/unset-all/unset-page/invert-all/invert-page.
|
||||
*/
|
||||
iflags.menuinvertmode = 1;
|
||||
|
||||
/* since this is done before init_objects(), do partial init here */
|
||||
objects[SLIME_MOLD].oc_name_idx = SLIME_MOLD;
|
||||
nmcpy(g.pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 windows.c $NHDT-Date: 1612127121 2021/01/31 21:05:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.82 $ */
|
||||
/* NetHack 3.7 windows.c $NHDT-Date: 1647472699 2022/03/16 23:18:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.86 $ */
|
||||
/* Copyright (c) D. Cohrs, 1993. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1493,21 +1493,32 @@ genl_putmixed(winid window, int attr, const char *str)
|
||||
* logic into one place instead of 7 different window-port routines.
|
||||
*/
|
||||
boolean
|
||||
menuitem_invert_test(int mode,
|
||||
unsigned itemflags, /* The itemflags for the item */
|
||||
boolean is_selected) /* The current selection status
|
||||
of the item */
|
||||
menuitem_invert_test(
|
||||
int mode UNUSED, /* 0: invert; 1: set; 2: unset */
|
||||
unsigned itemflags, /* itemflags for the item */
|
||||
boolean is_selected) /* current selection status of the item */
|
||||
{
|
||||
boolean skipinvert = (itemflags & MENU_ITEMFLAGS_SKIPINVERT) != 0;
|
||||
|
||||
if ((iflags.menuinvertmode == 1 || iflags.menuinvertmode == 2)
|
||||
&& !mode && skipinvert && !is_selected)
|
||||
if (!skipinvert) /* if not flagged SKIPINVERT, always pass test */
|
||||
return TRUE;
|
||||
/*
|
||||
* mode 0: inverting current on/off state;
|
||||
* 1: unconditionally setting on;
|
||||
* 2: unconditionally setting off.
|
||||
* menuinvertmode 0: treat entries flagged with skipinvert as ordinary
|
||||
* (same as if not flagged);
|
||||
* menuinvertmode 1: don't toggle bulk invert or bulk set entries On
|
||||
* (allow such toggling or setting to change to Off);
|
||||
* menuinvertmode 2: don't toggle skipinvert entries either On or Off
|
||||
* when a bulk change is performed.
|
||||
*/
|
||||
if (iflags.menuinvertmode == 2) {
|
||||
return FALSE;
|
||||
else if (iflags.menuinvertmode == 2
|
||||
&& !mode && skipinvert && is_selected)
|
||||
return TRUE;
|
||||
else
|
||||
return TRUE;
|
||||
} else if (iflags.menuinvertmode == 1) {
|
||||
return is_selected ? TRUE : FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*windows.c*/
|
||||
|
||||
231
win/tty/wintty.c
231
win/tty/wintty.c
@@ -204,8 +204,8 @@ static void set_item_state(winid, int, tty_menu_item *);
|
||||
static void set_all_on_page(winid, tty_menu_item *, tty_menu_item *);
|
||||
static void unset_all_on_page(winid, tty_menu_item *, tty_menu_item *);
|
||||
static void invert_all_on_page(winid, tty_menu_item *, tty_menu_item *,
|
||||
char);
|
||||
static void invert_all(winid, tty_menu_item *, tty_menu_item *, char);
|
||||
char, long);
|
||||
static void invert_all(winid, tty_menu_item *, tty_menu_item *, char, long);
|
||||
static void toggle_menu_attr(boolean, int, int);
|
||||
static void process_menu_window(winid, struct WinDesc *);
|
||||
static void process_text_window(winid, struct WinDesc *);
|
||||
@@ -1108,10 +1108,11 @@ reset_role_filtering(void)
|
||||
|
||||
/* add entries a-Archeologist, b-Barbarian, &c to menu being built in 'win' */
|
||||
static void
|
||||
setup_rolemenu(winid win,
|
||||
boolean filtering, /* True => exclude filtered roles;
|
||||
False => filter reset */
|
||||
int race, int gend, int algn) /* all ROLE_NONE for !filtering case */
|
||||
setup_rolemenu(
|
||||
winid win,
|
||||
boolean filtering, /* True => exclude filtered roles;
|
||||
* False => filter reset */
|
||||
int race, int gend, int algn) /* all ROLE_NONE for !filtering case */
|
||||
{
|
||||
anything any;
|
||||
int i;
|
||||
@@ -1685,9 +1686,15 @@ tty_clear_nhwindow(winid window)
|
||||
|
||||
RESTORE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
/* toggle a specific entry */
|
||||
static boolean
|
||||
toggle_menu_curr(winid window, tty_menu_item *curr, int lineno,
|
||||
boolean in_view, boolean counting, long count)
|
||||
toggle_menu_curr(
|
||||
winid window,
|
||||
tty_menu_item *curr,
|
||||
int lineno,
|
||||
boolean in_view,
|
||||
boolean counting,
|
||||
long count)
|
||||
{
|
||||
if (curr->selected) {
|
||||
if (counting && count > 0) {
|
||||
@@ -1721,8 +1728,9 @@ toggle_menu_curr(winid window, tty_menu_item *curr, int lineno,
|
||||
}
|
||||
|
||||
static void
|
||||
dmore(register struct WinDesc *cw,
|
||||
const char *s) /* valid responses */
|
||||
dmore(
|
||||
struct WinDesc *cw,
|
||||
const char *s) /* valid responses */
|
||||
{
|
||||
const char *prompt = cw->morestr ? cw->morestr : defmorestr;
|
||||
int offset = (cw->type == NHW_TEXT) ? 1 : 2;
|
||||
@@ -1740,8 +1748,13 @@ dmore(register struct WinDesc *cw,
|
||||
xwaitforspace(s);
|
||||
}
|
||||
|
||||
/* change screen display for selection state of an item;
|
||||
not used or wanted for items that aren't shown by the current page */
|
||||
static void
|
||||
set_item_state(winid window, int lineno, tty_menu_item *item)
|
||||
set_item_state(
|
||||
winid window,
|
||||
int lineno,
|
||||
tty_menu_item *item)
|
||||
{
|
||||
char ch = item->selected ? (item->count == -1L ? '+' : '#') : '-';
|
||||
|
||||
@@ -1753,88 +1766,118 @@ set_item_state(winid window, int lineno, tty_menu_item *item)
|
||||
term_end_attr(item->attr);
|
||||
}
|
||||
|
||||
/* select all [ignores pending count, if any] */
|
||||
static void
|
||||
set_all_on_page(winid window, tty_menu_item *page_start,
|
||||
tty_menu_item *page_end)
|
||||
{
|
||||
tty_menu_item *curr;
|
||||
int n;
|
||||
|
||||
for (n = 0, curr = page_start; curr != page_end; n++, curr = curr->next)
|
||||
if (curr->identifier.a_void && !curr->selected) {
|
||||
curr->selected = TRUE;
|
||||
set_item_state(window, n, curr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unset_all_on_page(winid window, tty_menu_item *page_start,
|
||||
tty_menu_item *page_end)
|
||||
{
|
||||
tty_menu_item *curr;
|
||||
int n;
|
||||
|
||||
for (n = 0, curr = page_start; curr != page_end; n++, curr = curr->next)
|
||||
if (curr->identifier.a_void && curr->selected) {
|
||||
curr->selected = FALSE;
|
||||
curr->count = -1L;
|
||||
set_item_state(window, n, curr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
invert_all_on_page(winid window, tty_menu_item *page_start,
|
||||
tty_menu_item *page_end,
|
||||
char acc) /* group accelerator, 0 => all */
|
||||
set_all_on_page(
|
||||
winid window,
|
||||
tty_menu_item *page_start,
|
||||
tty_menu_item *page_end)
|
||||
{
|
||||
tty_menu_item *curr;
|
||||
int n;
|
||||
|
||||
for (n = 0, curr = page_start; curr != page_end; n++, curr = curr->next) {
|
||||
if (!menuitem_invert_test(0, curr->itemflags, curr->selected))
|
||||
if (!curr->identifier.a_void /* not selectable */
|
||||
|| curr->selected /* already selected */
|
||||
|| !menuitem_invert_test(1, curr->itemflags, FALSE))
|
||||
continue;
|
||||
|
||||
if (curr->identifier.a_void && (acc == 0 || curr->gselector == acc)) {
|
||||
if (curr->selected) {
|
||||
curr->selected = FALSE;
|
||||
curr->count = -1L;
|
||||
} else
|
||||
curr->selected = TRUE;
|
||||
set_item_state(window, n, curr);
|
||||
}
|
||||
curr->selected = TRUE;
|
||||
set_item_state(window, n, curr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Invert all entries that match the give group accelerator (or all if zero).
|
||||
*/
|
||||
/* unselect all */
|
||||
static void
|
||||
invert_all(winid window, tty_menu_item *page_start,
|
||||
tty_menu_item *page_end,
|
||||
char acc) /* group accelerator, 0 => all */
|
||||
unset_all_on_page(
|
||||
winid window,
|
||||
tty_menu_item *page_start,
|
||||
tty_menu_item *page_end)
|
||||
{
|
||||
tty_menu_item *curr;
|
||||
int n;
|
||||
|
||||
for (n = 0, curr = page_start; curr != page_end; n++, curr = curr->next) {
|
||||
if (!curr->identifier.a_void /* skip if not selectable */
|
||||
|| !curr->selected /* skip if already de-selected */
|
||||
|| !menuitem_invert_test(2, curr->itemflags, TRUE))
|
||||
continue;
|
||||
curr->selected = FALSE;
|
||||
curr->count = -1L;
|
||||
set_item_state(window, n, curr);
|
||||
}
|
||||
}
|
||||
|
||||
/* invert current page */
|
||||
static void
|
||||
invert_all_on_page(
|
||||
winid window,
|
||||
tty_menu_item *page_start,
|
||||
tty_menu_item *page_end,
|
||||
char acc, /* group accelerator, 0 => all */
|
||||
long count) /* pending count; -1L for non-group toggling */
|
||||
{
|
||||
tty_menu_item *curr;
|
||||
int n;
|
||||
|
||||
for (n = 0, curr = page_start; curr != page_end; n++, curr = curr->next) {
|
||||
if (!curr->identifier.a_void /* not selectable */
|
||||
|| (acc != 0 && curr->gselector != acc) /* not group 'acc' */
|
||||
|| !menuitem_invert_test(0, curr->itemflags, curr->selected))
|
||||
continue;
|
||||
|
||||
if (curr->selected) {
|
||||
curr->selected = FALSE;
|
||||
curr->count = -1L;
|
||||
} else {
|
||||
curr->selected = TRUE;
|
||||
if (count > 0)
|
||||
curr->count = count;
|
||||
}
|
||||
set_item_state(window, n, curr);
|
||||
}
|
||||
}
|
||||
|
||||
/* invert all entries that match given group accelerator (or all if zero) */
|
||||
static void
|
||||
invert_all(
|
||||
winid window,
|
||||
tty_menu_item *page_start,
|
||||
tty_menu_item *page_end,
|
||||
char acc, /* group accelerator, 0 => all */
|
||||
long count) /* pending count; -1L for non-group toggling */
|
||||
{
|
||||
tty_menu_item *curr;
|
||||
boolean on_curr_page;
|
||||
struct WinDesc *cw = wins[window];
|
||||
|
||||
invert_all_on_page(window, page_start, page_end, acc);
|
||||
/* handle current page separately (it will need screen updating) */
|
||||
invert_all_on_page(window, page_start, page_end, acc, count);
|
||||
|
||||
/* invert the rest */
|
||||
/* invert the rest (no screen updating for them) */
|
||||
for (on_curr_page = FALSE, curr = cw->mlist; curr; curr = curr->next) {
|
||||
if (curr == page_start)
|
||||
on_curr_page = TRUE;
|
||||
else if (curr == page_end)
|
||||
on_curr_page = FALSE;
|
||||
|
||||
if (!on_curr_page && curr->identifier.a_void
|
||||
&& (acc == 0 || curr->gselector == acc)) {
|
||||
if (menuitem_invert_test(0, curr->itemflags, curr->selected)) {
|
||||
if (curr->selected) {
|
||||
curr->selected = FALSE;
|
||||
curr->count = -1;
|
||||
} else
|
||||
curr->selected = TRUE;
|
||||
}
|
||||
/* skip if on current page (already handled above) or not
|
||||
selectable (header line or similar) or if group toggling
|
||||
is taking place and this item isn't in specified group or
|
||||
group toggling is not taking place and this item is off
|
||||
limits to bulk toggling (assumes that an item won't be
|
||||
both in a group and also subject to bulk restrictions) */
|
||||
if (on_curr_page || !curr->identifier.a_void
|
||||
|| (acc != 0 && curr->gselector != acc)
|
||||
|| !menuitem_invert_test(0, curr->itemflags, curr->selected))
|
||||
continue;
|
||||
|
||||
if (curr->selected) {
|
||||
curr->selected = FALSE;
|
||||
curr->count = -1;
|
||||
} else {
|
||||
curr->selected = TRUE;
|
||||
if (count > 0)
|
||||
curr->count = count;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1919,7 +1962,7 @@ process_menu_window(winid window, struct WinDesc *cw)
|
||||
HUPSKIP();
|
||||
if (reset_count) {
|
||||
counting = FALSE;
|
||||
count = 0;
|
||||
count = 0L;
|
||||
} else
|
||||
reset_count = TRUE;
|
||||
|
||||
@@ -2045,7 +2088,7 @@ process_menu_window(winid window, struct WinDesc *cw)
|
||||
xwaitforspace(resp);
|
||||
}
|
||||
|
||||
really_morc = morc; /* (only used with MENU_EXPLICIT_CHOICE */
|
||||
really_morc = morc; /* (only used with MENU_EXPLICIT_CHOICE) */
|
||||
if ((rp = index(resp, morc)) != 0 && rp < resp + resp_len)
|
||||
/* explicit menu selection; don't override it if it also
|
||||
happens to match a mapped menu command (such as ':' to
|
||||
@@ -2142,29 +2185,44 @@ process_menu_window(winid window, struct WinDesc *cw)
|
||||
break;
|
||||
case MENU_INVERT_PAGE:
|
||||
if (cw->how == PICK_ANY)
|
||||
invert_all_on_page(window, page_start, page_end, 0);
|
||||
invert_all_on_page(window, page_start, page_end, 0, -1L);
|
||||
break;
|
||||
case MENU_SELECT_ALL:
|
||||
if (cw->how == PICK_ANY) {
|
||||
/* entries on the current page need screen updating */
|
||||
set_all_on_page(window, page_start, page_end);
|
||||
/* set the rest */
|
||||
for (curr = cw->mlist; curr; curr = curr->next)
|
||||
if (curr->identifier.a_void && !curr->selected)
|
||||
curr->selected = TRUE;
|
||||
}
|
||||
/* set the rest; entries on current page will be skipped
|
||||
because all of those will be 'already selected' now
|
||||
(some won't be if they failed menuitem_invert_test()
|
||||
in set_all_on_page() but those will fail it again here) */
|
||||
for (curr = cw->mlist; curr; curr = curr->next) {
|
||||
if (!curr->identifier.a_void /* not selectable */
|
||||
|| curr->selected /* already selected */
|
||||
|| !menuitem_invert_test(1, curr->itemflags, TRUE))
|
||||
continue;
|
||||
curr->selected = TRUE;
|
||||
}
|
||||
} /* if PICK_ANY */
|
||||
break;
|
||||
case MENU_UNSELECT_ALL:
|
||||
/* entries on the current page need screen updating */
|
||||
unset_all_on_page(window, page_start, page_end);
|
||||
/* unset the rest */
|
||||
for (curr = cw->mlist; curr; curr = curr->next)
|
||||
if (curr->identifier.a_void && curr->selected) {
|
||||
curr->selected = FALSE;
|
||||
curr->count = -1;
|
||||
}
|
||||
/* unset the rest; entries on current page will be skipped
|
||||
because none of those will still be in 'selected' state
|
||||
(unless they failed the menuitem_invert_test() in
|
||||
unset_all_on_page() but those will fail it again here) */
|
||||
for (curr = cw->mlist; curr; curr = curr->next) {
|
||||
if (!curr->identifier.a_void /* not selectable */
|
||||
|| !curr->selected /* already de-selected */
|
||||
|| !menuitem_invert_test(2, curr->itemflags, FALSE))
|
||||
continue;
|
||||
curr->selected = FALSE;
|
||||
curr->count = -1;
|
||||
}
|
||||
break;
|
||||
case MENU_INVERT_ALL:
|
||||
if (cw->how == PICK_ANY)
|
||||
invert_all(window, page_start, page_end, 0);
|
||||
invert_all(window, page_start, page_end, 0, -1L);
|
||||
break;
|
||||
case MENU_SEARCH:
|
||||
if (cw->how == PICK_NONE) {
|
||||
@@ -2211,7 +2269,8 @@ process_menu_window(winid window, struct WinDesc *cw)
|
||||
group_accel:
|
||||
/* group accelerator; for the PICK_ONE case, we know that
|
||||
it matches exactly one item in order to be in gacc[] */
|
||||
invert_all(window, page_start, page_end, morc);
|
||||
invert_all(window, page_start, page_end, morc,
|
||||
counting ? count : -1L);
|
||||
if (cw->how == PICK_ONE)
|
||||
finished = TRUE;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user