From 9eefeef5d252c95e1a4df7b439b2667cbddd4046 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 9 Jul 2019 17:42:32 -0700 Subject: [PATCH 1/5] fix github issue #200 - docs for 'strange object' Fixes #200 The Guidebook claims that there's no symbol for 'S_strange_object' which is literally true, but there is one for S_strange_obj. It has been in place longer than the paragraph claiming that there's no way to customize that symbol. I'm not sure why variant spelling was used. Also, files.c doesn't use loadsyms[], it calls a routine which returns a pointer to a specific element in that array. --- doc/Guidebook.mn | 12 ++---------- doc/Guidebook.tex | 13 +------------ src/files.c | 5 ++--- 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 7a4ffd8d6..9b215d2fb 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.310 $ $NHDT-Date: 1562114349 2019/07/03 00:39:09 $ +.\" $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.311 $ $NHDT-Date: 1562719337 2019/07/10 00:42:17 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" NetHack's Guidebook.mn currently does *not* adhere to these guidelines. @@ -24,7 +24,7 @@ .ds vr "NetHack 3.6 .ds f0 "\*(vr .ds f1 -.ds f2 "May 7, 2019 +.ds f2 "July 9, 2019 . .\" A note on some special characters: .\" \(lq = left double quote @@ -4555,14 +4555,6 @@ z S_zruty (zruty) .\"TABLE_END Do not delete this line. .TE .pg -There is one additional class of object, described as \(lqstrange object\(rq, -which will occasionally be the shape taken on by mimics and shown -as \(oq]\(cq for maps displayed as text characters. -Although the displayed character is the same as the default value for -\(lqS_mimic_def\(rq, it is a different symbol and there is no corresponding -\(lqS_strange_object\(rq symbol nor any way to assign an alternate value -for it. -.pg .hn 2 Configuring NetHack for Play by the Blind .pg diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index bc9b5e00f..d642cfed5 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.6 by Mike Stephenson and others)} -\date{May 7, 2019} +\date{July 9, 2019} \maketitle @@ -5048,17 +5048,6 @@ Default & Symbol Name & Description\\ \end{longtable}% } -%.pg -There is one additional class of object, described as ``strange object'', -which will occasionally be the shape taken on by mimics and shown as -`{\tt \verb+]+}' -for maps displayed as text characters. -Although the displayed character is the same as the default value for -`S\verb+_+mimic\verb+_+def', it is a different symbol and there is no -corresponding -`S\verb+_+strange\verb+_+object' symbol nor any way to assign an -alternate value for it. - %.pg %.hn 2 \subsection*{Configuring {\it NetHack\/} for Play by the Blind} diff --git a/src/files.c b/src/files.c index 29ad2f1a8..930d36ea2 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 files.c $NHDT-Date: 1559670605 2019/06/04 17:50:05 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.250 $ */ +/* NetHack 3.6 files.c $NHDT-Date: 1562719337 2019/07/10 00:42:17 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.252 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3140,7 +3140,6 @@ boolean FDECL((*proc), (char *)); } extern struct symsetentry *symset_list; /* options.c */ -extern struct symparse loadsyms[]; /* drawing.c */ extern const char *known_handling[]; /* drawing.c */ extern const char *known_restrictions[]; /* drawing.c */ static int symset_count = 0; /* for pick-list building only */ @@ -3213,7 +3212,7 @@ char *buf; int which_set; { int val, i; - struct symparse *symp = (struct symparse *) 0; + struct symparse *symp; char *bufp, *commentp, *altp; /* convert each instance of whitespace (tabs, consecutive spaces) From 0e8163e341694172ce1aa3dec38679c086161fe6 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 9 Jul 2019 18:55:10 -0700 Subject: [PATCH 2/5] curses: ncurses vs Ctrl+Click Asking curses to report whether the Ctrl key was being pressed during a mouse click was sending mouse position reports--even those aren't being requested--and actual Ctrl+Left_click was reporting a pair of duplicate Ctrl+Mouse_position_report events when a click was actually performed. So turn off Ctrl key reporting. Mac with one-button mouse can be configured to send "secondary click" for Ctrl+Click. A laptop trackpad handles that differently (press the button while two fingers are on the touchpad to send secondary click) and doesn't support Ctrl+Click as an alternate way to do that. If this would work within curses then they could operate the same regardless of how the user set the mouse or trackpad configuraiton. But I wasn't able to make it work right. --- doc/fixes36.3 | 6 +++++- win/curses/cursmisc.c | 21 ++++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index b7f2c43bb..751b2a4d0 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.89 $ $NHDT-Date: 1562632673 2019/07/09 00:37:53 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.90 $ $NHDT-Date: 1562723693 2019/07/10 01:54:53 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -174,6 +174,10 @@ curses: when map window was clipped, the 'scrollbars' shown to indicate which curses: support users's setting for erase char and kill char when getting a line of input with 'popup_dialog' Off (already supported for popup On) curses: attempting to use ^H to rush left actually executed ^G (#wizgenesis) +curses: disable the attempt to support Ctrl+Left_click as an alternate way + to generate Right_click for systems with one-button mouse or trackpad; + the mouse data passed to nethack didn't match the curses (ncurses on + OSX 10.11) documentation and things didn't work as intended curses+'perm_invent': entries were wrapping without any control; usually not noticeable because next entry overwrote, but visible for final entry when whole inventory fit within the available height; looked ok with diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 4ac85c0a3..3768e53bd 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -877,13 +877,20 @@ curses_convert_keys(int key) return ret; } -/* we treat buttons 2 and 3 as equivalent so that it doesn't matter which - one is for right-click and which for middle-click; the core uses CLICK_2 - for right-click ("not left" click) even though 2 might be middle button; - we also support Ctrl+left-click as another way to get "not left" click - since Mac is traditionally saddled with a one button mouse or trackpad */ -#define MOUSEBUTTONS ((BUTTON1_CLICKED | BUTTON2_CLICKED | BUTTON3_CLICKED) \ - | BUTTON_CTRL) +/* + * We treat buttons 2 and 3 as equivalent so that it doesn't matter which + * one is for right-click and which for middle-click. The core uses CLICK_2 + * for right-click ("not left"-click) even though 2 might be middle button. + * + * BUTTON_CTRL was enabled at one point but was not working as intended. + * Ctrl+left_click was generating pairs of duplicated events with Ctrl and + * Report_mouse_position bits set (even though Report_mouse_position wasn't + * enabled) but no button click bit set. (It sort of worked because Ctrl+ + * Report_mouse_position wasn't a left click so passed along CLICK_2, but + * the duplication made that too annoying to use. Attempting to immediately + * drain the second one wasn't working as intended either.) + */ +#define MOUSEBUTTONS (BUTTON1_CLICKED | BUTTON2_CLICKED | BUTTON3_CLICKED) /* Process mouse events. Mouse movement is processed until no further mouse movement events are available. Returns 0 for a mouse click From bc65112ce07c6e2056ed28b5e93954679fb36acd Mon Sep 17 00:00:00 2001 From: Bart House Date: Tue, 9 Jul 2019 22:30:34 -0700 Subject: [PATCH 3/5] Added experimental feature NEW_KEYBOARD_HIT. --- include/config.h | 8 +++- include/extern.h | 15 +++++++ include/ntconf.h | 3 ++ include/unixconf.h | 2 + include/winprocs.h | 12 ++++++ include/wintty.h | 4 ++ src/allmain.c | 4 ++ src/windows.c | 14 +++++++ sys/winnt/nttty.c | 10 +++++ sys/winnt/winnt.c | 7 +++- win/share/safeproc.c | 11 +++++ win/tty/wintty.c | 97 ++++++++++++++++++++++++++++++++++++++++++++ win/win32/mswproc.c | 12 ++++++ win/win32/winMS.h | 3 ++ 14 files changed, 199 insertions(+), 3 deletions(-) diff --git a/include/config.h b/include/config.h index d12576f9d..f054de5c4 100644 --- a/include/config.h +++ b/include/config.h @@ -564,9 +564,13 @@ typedef unsigned char uchar; %N first character of player name DUMPLOG_FILE is not used if SYSCF is defined */ -#endif +#endif /* DUMPLOG_FILE */ -#endif +#endif /* DUMPLOG */ + +/* NEW_KEYBOARD_HIT adds new window proc to return whether keyboard has been hit + and character input is available */ +/* #define NEW_KEYBOARD_HIT */ #define USE_ISAAC64 /* Use cross-plattform, bundled RNG */ diff --git a/include/extern.h b/include/extern.h index 90548cf37..0761d224e 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1147,6 +1147,9 @@ E void NDECL(gettty); E void NDECL(setftty); E void FDECL(settty, (const char *)); E int NDECL(tgetch); +#ifdef NEW_KEYBOARD_HIT +E boolean NDECL(tkbhit); +#endif E void FDECL(cmov, (int x, int y)); E void FDECL(nocmov, (int x, int y)); @@ -1552,6 +1555,9 @@ E void FDECL(mplayer_talk, (struct monst *)); #ifndef WIN32 E int NDECL(tgetch); +#ifdef NEW_KEYBOARD_HIT +E boolean NDECL(tkbhit); +#endif #endif #ifndef TOS E char NDECL(switchar); @@ -1582,7 +1588,9 @@ E void FDECL(gotoxy, (int, int)); #endif #ifdef TOS E int FDECL(_copyfile, (char *, char *)); +#ifndef NEW_KEYBOARD_HIT E int NDECL(kbhit); +#endif E void NDECL(set_colors); E void NDECL(restore_colors); #ifdef SUSPEND @@ -1592,7 +1600,9 @@ E int NDECL(dosuspend); #ifdef WIN32 E char *FDECL(get_username, (int *)); E void FDECL(nt_regularize, (char *)); +#ifndef NEW_KEYBOARD_HIT E int NDECL((*nt_kbhit)); +#endif E void FDECL(Delay, (int)); #endif /* WIN32 */ #endif /* MICRO || WIN32 */ @@ -1660,10 +1670,15 @@ E void FDECL(regex_free, (struct nhregex *)); #ifdef WIN32 E void NDECL(get_scr_size); +#ifndef NEW_KEYBOARD_HIT E int NDECL(nttty_kbhit); +#endif E void FDECL(nttty_open, (int)); E void NDECL(nttty_rubout); E int NDECL(tgetch); +#ifdef NEW_KEYBOARD_HIT +E boolean NDECL(tkbhit); +#endif E int FDECL(ntposkey, (int *, int *, int *)); E void FDECL(set_output_mode, (int)); E void NDECL(synch_cursor); diff --git a/include/ntconf.h b/include/ntconf.h index eb106090f..994615c2d 100644 --- a/include/ntconf.h +++ b/include/ntconf.h @@ -252,8 +252,11 @@ int _RTLENTRY _EXPFUNC read(int __handle, void _FAR *__buf, unsigned __len); #ifndef CURSES_GRAPHICS #include /* conflicting definitions with curses.h */ #endif + +#ifndef NEW_KEYBOARD_HIT #undef kbhit /* Use our special NT kbhit */ #define kbhit (*nt_kbhit) +#endif #ifdef LAN_FEATURES #define MAX_LAN_USERNAME 20 diff --git a/include/unixconf.h b/include/unixconf.h index c126d6839..f9ac16f0c 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -311,7 +311,9 @@ #define HLOCK "perm" /* an empty file used for locking purposes */ +#ifndef NEW_KEYBOARD_HIT #define tgetch getchar +#endif #ifndef NOSHELL #define SHELL /* do not delete the '!' command */ diff --git a/include/winprocs.h b/include/winprocs.h index 36962750e..d1cea9a3c 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -79,6 +79,9 @@ struct window_procs { (int, const char *, const char *, BOOLEAN_P)); void FDECL((*win_status_update), (int, genericptr_t, int, int, int, unsigned long *)); boolean NDECL((*win_can_suspend)); +#ifdef NEW_KEYBOARD_HIT + boolean NDECL((*win_keyboard_hit)); +#endif }; extern @@ -160,6 +163,9 @@ extern */ #define status_enablefield (*windowprocs.win_status_enablefield) #define status_update (*windowprocs.win_status_update) +#ifdef NEW_KEYBOARD_HIT +#define keyboard_hit (*windowprocs.win_keyboard_hit) +#endif /* * WINCAP @@ -379,6 +385,9 @@ struct chain_procs { (CARGS, int, const char *, const char *, BOOLEAN_P)); void FDECL((*win_status_update), (CARGS, int, genericptr_t, int, int, int, unsigned long *)); boolean FDECL((*win_can_suspend), (CARGS)); +#ifdef NEW_KEYBOARD_HIT + boolean FDECL((*keyboard_hit), (CARGS)); +#endif }; #endif /* WINCHAIN */ @@ -449,6 +458,9 @@ extern void FDECL(safe_status_enablefield, (int, const char *, const char *, BOOLEAN_P)); extern void FDECL(safe_status_update, (int, genericptr_t, int, int, int, unsigned long *)); extern boolean NDECL(safe_can_suspend); +#ifdef NEW_KEYBOARD_HIT +extern boolean NDECL(safe_keyboard_hit); +#endif extern void FDECL(stdio_raw_print, (const char *)); extern void FDECL(stdio_raw_print_bold, (const char *)); extern void NDECL(stdio_wait_synch); diff --git a/include/wintty.h b/include/wintty.h index 4863d6e10..6994fc93f 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -247,6 +247,10 @@ E void FDECL(genl_outrip, (winid, int, time_t)); E char *FDECL(tty_getmsghistory, (BOOLEAN_P)); E void FDECL(tty_putmsghistory, (const char *, BOOLEAN_P)); +#ifdef NEW_KEYBOARD_HIT +E boolean NDECL(tty_keyboard_hit); +#endif + #ifdef NO_TERMS #ifdef MAC #ifdef putchar diff --git a/src/allmain.c b/src/allmain.c index b0bb0f3a2..1ce8cad08 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -374,7 +374,11 @@ boolean resuming; if (multi >= 0 && occupation) { #if defined(MICRO) || defined(WIN32) abort_lev = 0; +#ifdef NEW_KEYBOARD_HIT + if (keyboard_hit()) { +#else if (kbhit()) { +#endif if ((ch = pgetchar()) == ABORT) abort_lev++; else diff --git a/src/windows.c b/src/windows.c index ad7b91b0d..0d2ce514d 100644 --- a/src/windows.c +++ b/src/windows.c @@ -523,6 +523,9 @@ static void NDECL(hup_void_ndecl); static void FDECL(hup_void_fdecl_int, (int)); static void FDECL(hup_void_fdecl_winid, (winid)); static void FDECL(hup_void_fdecl_constchar_p, (const char *)); +#ifdef NEW_KEYBOARD_HIT +static boolean NDECL(hup_keyboard_hit); +#endif static struct window_procs hup_procs = { "hup", 0L, 0L, hup_init_nhwindows, @@ -570,6 +573,9 @@ static struct window_procs hup_procs = { hup_void_ndecl, /* status_finish */ genl_status_enablefield, hup_status_update, genl_can_suspend_no, +#ifdef NEW_KEYBOARD_HIT + hup_keyboard_hit +#endif }; static void FDECL((*previnterface_exit_nhwindows), (const char *)) = 0; @@ -624,6 +630,14 @@ hup_nhgetch(VOID_ARGS) return '\033'; /* ESC */ } +#ifdef NEW_KEYBOARD_HIT +static boolean +hup_keyboard_hit(VOID_ARGS) +{ + return FALSE; +} +#endif + /*ARGSUSED*/ static char hup_yn_function(prompt, resp, deflt) diff --git a/sys/winnt/nttty.c b/sys/winnt/nttty.c index 3233dc9cb..a8000bc05 100644 --- a/sys/winnt/nttty.c +++ b/sys/winnt/nttty.c @@ -398,10 +398,12 @@ int mode; // unused { DWORD cmode; +#ifndef NEW_KEYBOARD_HIT /* Initialize the function pointer that points to * the kbhit() equivalent, in this TTY case nttty_kbhit() */ nt_kbhit = nttty_kbhit; +#endif if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE)) { /* Unable to set control handler */ @@ -436,11 +438,19 @@ int portdebug; return ch; } +#ifndef NEW_KEYBOARD_HIT int nttty_kbhit() { return keyboard_handler.pNHkbhit(console.hConIn, &ir); } +#else +boolean +tkbhit() +{ + return keyboard_handler.pNHkbhit(console.hConIn, &ir) != 0; +} +#endif int tgetch() diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index f6a9aa791..e9041262d 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -56,6 +56,7 @@ extern void NDECL(backsp); int NDECL(windows_console_custom_nhgetch); extern void NDECL(safe_routines); +#ifndef NEW_KEYBOARD_HIT /* The function pointer nt_kbhit contains a kbhit() equivalent * which varies depending on which window port is active. * For the tty port it is tty_kbhit() [from nttty.c] @@ -65,6 +66,7 @@ extern void NDECL(safe_routines); int def_kbhit(void); int (*nt_kbhit)() = def_kbhit; +#endif char switchar() @@ -158,11 +160,13 @@ max_filename() return 0; } +#ifndef NEW_KEYBOARD_HIT int def_kbhit() { return 0; } +#endif /* * Strip out troublesome file system characters. @@ -510,7 +514,9 @@ int code; exit(code); } +#ifndef NEW_KEYBOARD_HIT #undef kbhit +#endif #include int @@ -719,7 +725,6 @@ sys_random_seed(VOID_ARGS) } return ourseed; } - #endif /* WIN32 */ /*winnt.c*/ diff --git a/win/share/safeproc.c b/win/share/safeproc.c index ab5cb1c5a..9f3e0ce2f 100644 --- a/win/share/safeproc.c +++ b/win/share/safeproc.c @@ -101,6 +101,9 @@ struct window_procs safe_procs = { safe_status_update, #endif safe_can_suspend, +#ifdef NEW_KEYBOARD_HIT + safe_keyboard_hit +#endif }; struct window_procs * @@ -386,6 +389,14 @@ safe_can_suspend() return FALSE; } +#ifdef NEW_KEYBOARD_HIT +boolean +safe_keyboard_hit() +{ + return FALSE; +} +#endif + void safe_nhbell() { diff --git a/win/tty/wintty.c b/win/tty/wintty.c index ac0d61880..1411839da 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -36,6 +36,12 @@ extern void msmsg(const char *, ...); #endif #endif +#ifdef NEW_KEYBOARD_HIT +#if defined(UNIX) +#include +#endif +#endif + #ifdef TTY_TILES_ESCCODES extern short glyph2tile[]; #define TILE_ANSI_COMMAND 'z' @@ -133,6 +139,9 @@ struct window_procs tty_procs = { genl_status_update, #endif genl_can_suspend_yes, +#ifdef NEW_KEYBOARD_HIT + tty_keyboard_hit +#endif }; static int maxwin = 0; /* number of windows in use */ @@ -3479,6 +3488,7 @@ const char *str; #endif } +#ifndef NEW_KEYBOARD_HIT int tty_nhgetch() { @@ -3533,6 +3543,93 @@ tty_nhgetch() #endif /* TTY_TILES_ESCCODES */ return i; } +#else /* NEW_KEYBOARD_HIT */ +#ifdef UNIX +static boolean stdin_non_blocking = FALSE; + +int +tgetch() +{ + static volatile int nesting = 0; + int i; + char nestbuf; + + if (stdin_non_blocking) { + fcntl(0, F_SETFL, fcntl(0, F_GETFL) & ~O_NONBLOCK); + stdin_non_blocking = FALSE; + } + + /* kludge alert: Some Unix variants return funny values if getc() + * is called, interrupted, and then called again. There + * is non-reentrant code in the internal _filbuf() routine, called by + * getc(). + */ + i = (++nesting == 1) + ? getchar() + : (read(fileno(stdin), (genericptr_t) &nestbuf, 1) == 1) + ? (int) nestbuf : EOF; + --nesting; + + return i; +} + +boolean +tkbhit() +{ + int i; + if (!stdin_non_blocking) { + fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK); + stdin_non_blocking = TRUE; + } + i = getchar(); + if (i != EOF) ungetc(i, stdin); + return (i != EOF); + } +#endif + +int +tty_nhgetch() +{ + int i; + HUPSKIP_RESULT('\033'); + print_vt_code1(AVTC_INLINE_SYNC); + (void) fflush(stdout); + /* Note: if raw_print() and wait_synch() get called to report terminal + * initialization problems, then wins[] and ttyDisplay might not be + * available yet. Such problems will probably be fatal before we get + * here, but validate those pointers just in case... + */ + if (WIN_MESSAGE != WIN_ERR && wins[WIN_MESSAGE]) + wins[WIN_MESSAGE]->flags &= ~WIN_STOP; + if (iflags.debug_fuzzer) { + i = randomkey(); + } else { + i = tgetch(); + } + if (!i) + i = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */ + else if (i == EOF) + i = '\033'; /* same for EOF */ + if (ttyDisplay && ttyDisplay->toplin == 1) + ttyDisplay->toplin = 2; +#ifdef TTY_TILES_ESCCODES + { + /* hack to force output of the window select code */ + int tmp = vt_tile_current_window; + + vt_tile_current_window++; + print_vt_code2(AVTC_SELECT_WINDOW, tmp); + } +#endif /* TTY_TILES_ESCCODES */ + return i; +} + +boolean tty_keyboard_hit() +{ + /* tgetch provider needs to also provide tkbhit() */ + return tkbhit(); +} +#endif /* NEW_KEYBOARD_HIT */ /* * return a key, or 0, in which case a mouse button was pressed diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index b637c463f..a5aa02bb4 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -116,6 +116,9 @@ struct window_procs mswin_procs = { mswin_status_init, mswin_status_finish, mswin_status_enablefield, mswin_status_update, genl_can_suspend_yes, +#ifdef NEW_KEYBOARD_HIT + mswin_keyboard_hit +#endif }; /* @@ -1402,6 +1405,15 @@ mswin_nhgetch() return (key); } +#ifdef NEW_KEYBOARD_HIT +/* boolean keyboard_hit() -- returns TRUE if input is available */ +boolean +mswin_keyboard_hit() +{ + return mswin_have_input() != 0; +} +#endif + /* int nh_poskey(int *x, int *y, int *mod) -- Returns a single character input from the user or a diff --git a/win/win32/winMS.h b/win/win32/winMS.h index c5ee77368..c649917dc 100644 --- a/win/win32/winMS.h +++ b/win/win32/winMS.h @@ -167,6 +167,9 @@ void mswin_raw_print(const char *str); void mswin_raw_print_bold(const char *str); void mswin_raw_print_flush(); int mswin_nhgetch(void); +#ifdef NEW_KEYBOARD_HIT +boolean mswin_keyboard_hit(void); +#endif int mswin_nh_poskey(int *x, int *y, int *mod); void mswin_nhbell(void); int mswin_doprev_message(void); From 094a9d81619b22218b7401dd5825132b12389561 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 10 Jul 2019 16:15:11 -0700 Subject: [PATCH 4/5] fix github issue #204 - theft while in nymph form Fixes #204 3.6.2's attempts to fix turning off SEDUCE in 'sysconf' introduced an unintentional change in behavior for hero poly'd into nymph form: theft attack always angered the target. The actual change was intentional but its ramifications were unexpected. --- doc/fixes36.3 | 3 ++- src/mhitu.c | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 751b2a4d0..80002d745 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.90 $ $NHDT-Date: 1562723693 2019/07/10 01:54:53 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.91 $ $NHDT-Date: 1562800503 2019/07/10 23:15:03 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -102,6 +102,7 @@ kicking an altar ignored god's wrath if hero injured himself during the kick detect unseen/secret door detection/^E failed to find monsters hiding under objects and failed to find monsters hiding at trap locations when farlook describes a monster at a visible spot as trapped, reveal the trap +fix theft when poly'd into nymph form; 3.6.2 change made that anger the victim Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/mhitu.c b/src/mhitu.c index a175daeab..664955fb9 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mhitu.c $NHDT-Date: 1556649298 2019/04/30 18:34:58 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.164 $ */ +/* NetHack 3.6 mhitu.c $NHDT-Date: 1562800504 2019/07/10 23:15:04 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.166 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2408,9 +2408,13 @@ struct attack *mattk; /* non-Null: current attack; Null: general capability */ if (agrinvis && !defperc && adtyp == AD_SEDU) return 0; + /* nymphs have two attacks, one for steal-item damage and the other + for seduction, both pass the could_seduce() test; + incubi/succubi have three attacks, their claw attacks for damage + don't pass the test */ if ((pagr->mlet != S_NYMPH && pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS]) - || (adtyp != AD_SEDU && adtyp != AD_SSEX)) + || (adtyp != AD_SEDU && adtyp != AD_SSEX && adtyp != AD_SITM)) return 0; return (genagr == 1 - gendef) ? 1 : (pagr->mlet == S_NYMPH) ? 2 : 0; From 58583cacf8511625fd805ecbb050481f28de9411 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 10 Jul 2019 17:56:33 -0700 Subject: [PATCH 5/5] hero-as-nymph: steal items vs steal gold Nymphs won't steal gold from the hero (so that their steal-item damage isn't a superset of lerprechaun's steal-gold damage; straightforward back when gold wasn't kept in inventory), but hero poly'd into a nymph would steal gold from monsters. --- doc/fixes36.3 | 3 ++- src/steal.c | 11 ++++++++--- src/uhitm.c | 37 +++++++++++++++++++++++++++++++------ 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 80002d745..3d8a5ed9e 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.91 $ $NHDT-Date: 1562800503 2019/07/10 23:15:03 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.92 $ $NHDT-Date: 1562806584 2019/07/11 00:56:24 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -103,6 +103,7 @@ detect unseen/secret door detection/^E failed to find monsters hiding under objects and failed to find monsters hiding at trap locations when farlook describes a monster at a visible spot as trapped, reveal the trap fix theft when poly'd into nymph form; 3.6.2 change made that anger the victim +hero poly'd into nymph would steal gold along with other items Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/steal.c b/src/steal.c index 59421e372..2686a5392 100644 --- a/src/steal.c +++ b/src/steal.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 steal.c $NHDT-Date: 1561588404 2019/06/26 22:33:24 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.73 $ */ +/* NetHack 3.6 steal.c $NHDT-Date: 1562806584 2019/07/11 00:56:24 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.74 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -247,7 +247,8 @@ struct monst *mtmp; char *objnambuf; { struct obj *otmp; - int tmp, could_petrify, armordelay, olddelay, named = 0, retrycnt = 0; + int tmp, could_petrify, armordelay, olddelay, icnt, + named = 0, retrycnt = 0; boolean monkey_business, /* true iff an animal is doing the thievery */ was_doffing, was_punished = Punished; @@ -263,11 +264,15 @@ char *objnambuf; if (occupation) (void) maybe_finished_meal(FALSE); - if (!invent || (inv_cnt(FALSE) == 1 && uskin)) { + icnt = inv_cnt(FALSE); /* don't include gold */ + if (!icnt || (icnt == 1 && uskin)) { nothing_to_steal: /* Not even a thousand men in armor can strip a naked man. */ if (Blind) pline("Somebody tries to rob you, but finds nothing to steal."); + else if (inv_cnt(TRUE) > inv_cnt(FALSE)) /* ('icnt' might be stale) */ + pline("%s tries to rob you, but isn't interested in gold.", + Monnam(mtmp)); else pline("%s tries to rob you, but there is nothing to steal!", Monnam(mtmp)); diff --git a/src/uhitm.c b/src/uhitm.c index f478d0289..c6fc30c2a 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 uhitm.c $NHDT-Date: 1555720104 2019/04/20 00:28:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.207 $ */ +/* NetHack 3.6 uhitm.c $NHDT-Date: 1562806586 2019/07/11 00:56:26 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.210 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1498,10 +1498,11 @@ steal_it(mdef, mattk) struct monst *mdef; struct attack *mattk; { - struct obj *otmp, *stealoid, **minvent_ptr; + struct obj *otmp, *gold = 0, *stealoid, **minvent_ptr; long unwornmask; - if (!mdef->minvent) + otmp = mdef->minvent; + if (!otmp || (otmp->oclass == COIN_CLASS && !otmp->nobj)) return; /* nothing to take */ /* look for worn body armor */ @@ -1524,14 +1525,25 @@ struct attack *mattk; if (stealoid) { /* we will be taking everything */ if (gender(mdef) == (int) u.mfemale && youmonst.data->mlet == S_NYMPH) - You("charm %s. She gladly hands over her possessions.", - mon_nam(mdef)); + You("charm %s. She gladly hands over %sher possessions.", + mon_nam(mdef), !gold ? "" : "most of "); else You("seduce %s and %s starts to take off %s clothes.", mon_nam(mdef), mhe(mdef), mhis(mdef)); } + /* prevent gold from being stolen so that steal-item isn't a superset + of steal-gold; shuffling it out of minvent before selecting next + item, and then back in case hero or monster dies (hero touching + stolen c'trice corpse or monster wielding one and having gloves + stolen) is less bookkeeping than skipping it within the loop or + taking it out once and then trying to figure out how to put it back */ + if ((gold = findgold(mdef->minvent)) != 0) + obj_extract_self(gold); + while ((otmp = mdef->minvent) != 0) { + if (gold) /* put 'mdef's gold back */ + mpickobj(mdef, gold), gold = 0; if (!Upolyd) break; /* no longer have ability to steal */ /* take the object away from the monster */ @@ -1564,12 +1576,25 @@ struct attack *mattk; } else if (unwornmask & W_ARMG) { /* stole worn gloves */ mselftouch(mdef, (const char *) 0, TRUE); if (DEADMONSTER(mdef)) /* it's now a statue */ - return; /* can't continue stealing */ + break; /* can't continue stealing */ } if (!stealoid) break; /* only taking one item */ + + /* take gold out of minvent before making next selection; if it + is the only thing left, the loop will terminate and it will be + put back below */ + if ((gold = findgold(mdef->minvent)) != 0) + obj_extract_self(gold); } + + /* put gold back; won't happen if either hero or 'mdef' dies because + gold will be back in monster's inventory at either of those times + (so will be present in mdef's minvent for bones, or in its statue + now if it has just been turned into one) */ + if (gold) + mpickobj(mdef, gold); } int