Merge branch 'NetHack-3.7' of https://rodney.nethack.org:20040/git/NHsource into NetHack-3.7

This commit is contained in:
nhkeni
2022-03-16 21:27:22 -04:00
6 changed files with 186 additions and 102 deletions

View File

@@ -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

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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*/

View File

@@ -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;