From 587a51bee772445eda9c666442a82bdbfd389ecf Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 24 Feb 2019 14:35:49 -0500 Subject: [PATCH 1/6] include isaac64 in xcode build --- src/end.c | 5 +++-- sys/unix/NetHack.xcodeproj/project.pbxproj | 10 ++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/end.c b/src/end.c index b1f5e39a3..3d316a5db 100644 --- a/src/end.c +++ b/src/end.c @@ -135,8 +135,9 @@ panictrace_handler(sig_unused) int sig_unused UNUSED; { #define SIG_MSG "\nSignal received.\n" - int f2 = (int) write(2, SIG_MSG, sizeof SIG_MSG - 1); - + int f2; + + f2 = (int) write(2, SIG_MSG, sizeof SIG_MSG - 1); nhUse(f2); /* what could we do if write to fd#2 (stderr) fails */ NH_abort(); /* ... and we're already in the process of quitting? */ } diff --git a/sys/unix/NetHack.xcodeproj/project.pbxproj b/sys/unix/NetHack.xcodeproj/project.pbxproj index 4a0d53ae5..78b618ce9 100644 --- a/sys/unix/NetHack.xcodeproj/project.pbxproj +++ b/sys/unix/NetHack.xcodeproj/project.pbxproj @@ -158,6 +158,7 @@ 31B8A46221A26B020055BD01 /* alloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 31B8A36521A238040055BD01 /* alloc.c */; }; 31B8A46621A2820F0055BD01 /* dgn_comp.y in Sources */ = {isa = PBXBuildFile; fileRef = 31B8A46421A278AC0055BD01 /* dgn_comp.y */; }; 31B8A46921A288770055BD01 /* dgn_comp.l in Sources */ = {isa = PBXBuildFile; fileRef = 31B8A46821A288770055BD01 /* dgn_comp.l */; }; + 54FCE8292223261F00F393C8 /* isaac64.c in Sources */ = {isa = PBXBuildFile; fileRef = 54FCE8282223261F00F393C8 /* isaac64.c */; }; /* End PBXBuildFile section */ /* Begin PBXBuildRule section */ @@ -586,6 +587,7 @@ 31B8A45F21A26AE70055BD01 /* dlb_main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dlb_main.c; path = ../../util/dlb_main.c; sourceTree = ""; }; 31B8A46421A278AC0055BD01 /* dgn_comp.y */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.yacc; name = dgn_comp.y; path = ../../util/dgn_comp.y; sourceTree = ""; }; 31B8A46821A288770055BD01 /* dgn_comp.l */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.lex; name = dgn_comp.l; path = ../../util/dgn_comp.l; sourceTree = ""; }; + 54FCE8282223261F00F393C8 /* isaac64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = isaac64.c; path = ../../src/isaac64.c; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -700,6 +702,7 @@ 31B8A35821A238040055BD01 /* hack.c */, 31B8A36421A238040055BD01 /* hacklib.c */, 31B8A33121A238010055BD01 /* invent.c */, + 54FCE8282223261F00F393C8 /* isaac64.c */, 31B8A32B21A238010055BD01 /* light.c */, 31B8A34921A238030055BD01 /* lock.c */, 31B8A33221A238010055BD01 /* mail.c */, @@ -1729,6 +1732,7 @@ 31B8A3DE21A238060055BD01 /* sys.c in Sources */, 31B8A38021A238060055BD01 /* sit.c in Sources */, 31B8A3AF21A238060055BD01 /* lock.c in Sources */, + 54FCE8292223261F00F393C8 /* isaac64.c in Sources */, 31B8A38C21A238060055BD01 /* trap.c in Sources */, 31B8A3AE21A238060055BD01 /* worn.c in Sources */, 31B8A3B821A238060055BD01 /* dokick.c in Sources */, @@ -1984,7 +1988,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = ansi; + GCC_C_LANGUAGE_STANDARD = c99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -2066,7 +2070,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = ansi; + GCC_C_LANGUAGE_STANDARD = c99; GCC_NO_COMMON_BLOCKS = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -2107,6 +2111,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = c99; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -2115,6 +2120,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = c99; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; From 2b2106743ed2d661d63ee6d98f9ff0ba8f57408a Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 25 Feb 2019 15:33:43 -0800 Subject: [PATCH 2/6] fix #H8271 - wearing armor vs perm_invent window A relatively recent change moved 'obj->known = 1' when wearing armor from before setworn(), which issues an update_inventory() call, to afterwards. There wasn't any particular update then, so observing the enchantment of armor by wearing it wasn't being reflected in the persistent inventory window if that was enabled. --- doc/fixes36.2 | 4 +++- src/hack.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 7a8595c78..c9b5c83cd 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.262 $ $NHDT-Date: 1550868876 2019/02/22 20:54:36 $ +$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.263 $ $NHDT-Date: 1551137618 2019/02/25 23:33:38 $ This fixes36.2 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.1 in April 2018. Please note, however, @@ -441,6 +441,8 @@ after 'when donning armor, enchanment becomes known even if interrupted' fix, worn in a slot which usually has one) didn't make +/- become known having an artifact wish be refused ("for a moment you feel in your hands, but it disappears") would immediately segfault +when persistent inventory window is enabled, wearing armor doesn't immediately + update it with armor's newly observed +/- value tty: turn off an optimization that is the suspected cause of Windows reported partial status lines following level changes tty: ensure that current status fields are always copied to prior status diff --git a/src/hack.c b/src/hack.c index ed9f6c8ee..ddb4a5f05 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 hack.c $NHDT-Date: 1549231692 2019/02/03 22:08:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.207 $ */ +/* NetHack 3.6 hack.c $NHDT-Date: 1551137618 2019/02/25 23:33:38 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.208 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2886,6 +2886,8 @@ const char *msg_override; encumbrance hack for levitation--see weight_cap()) */ afternmv = (int NDECL((*))) 0; (void) (*f)(); + /* for finishing Armor/Boots/&c_on() */ + update_inventory(); } } From 4df491e47d757cb04288d6d3d1afc4f0d6bb2530 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 25 Feb 2019 15:44:21 -0800 Subject: [PATCH 3/6] more wearing armor vs perm_invent window Realized while fixing #H8271: if persistent inventory got an update while wearing or taking off was in progress (not within user's control since hero is busy) the item in question was flagged as "(being worn)" even though it wouldn't be worn if putting on got interrupted. Update doname() to show "(being donned)" or "(being doffed)" instead of "(being worn)" when corresponding operation is in progress. (During testing, I was able to observe "being doffed" but never managed to see "being donned".) --- doc/fixes36.2 | 5 ++++- src/do_wear.c | 5 +++-- src/objnam.c | 9 +++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index c9b5c83cd..e9d671467 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.263 $ $NHDT-Date: 1551137618 2019/02/25 23:33:38 $ +$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.264 $ $NHDT-Date: 1551138255 2019/02/25 23:44:15 $ This fixes36.2 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.1 in April 2018. Please note, however, @@ -380,6 +380,9 @@ when using 'f' to fire/throw--and possibly some ^A's to repeat--then running was already worn or wielded) and then ask for a direction to fire it early rolling boulder trap lacking any boulder might still have the corpse of a dead adventurer +persistent inventory window would show "(being worn)" for armor that was in + the midst of being put on or taken off; it is 'partly worn' in such + circumstances so "being worn" could be misleading Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/src/do_wear.c b/src/do_wear.c index 793abfab5..9132e7535 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_wear.c $NHDT-Date: 1550014802 2019/02/12 23:40:02 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.107 $ */ +/* NetHack 3.6 do_wear.c $NHDT-Date: 1551138255 2019/02/25 23:44:15 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.108 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1231,7 +1231,8 @@ struct obj *otmp; } /* check whether the target object is currently being taken off, - so that stop_donning() and steal() can vary messages */ + so that stop_donning() and steal() can vary messages and doname() + can vary "(being worn)" suffix */ boolean doffing(otmp) struct obj *otmp; diff --git a/src/objnam.c b/src/objnam.c index cfb1a3e15..af2365f55 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1548695445 2019/01/28 17:10:45 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.234 $ */ +/* NetHack 3.6 objnam.c $NHDT-Date: 1551138256 2019/02/25 23:44:16 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.235 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1034,7 +1034,12 @@ unsigned doname_flags; case ARMOR_CLASS: if (obj->owornmask & W_ARMOR) Strcat(bp, (obj == uskin) ? " (embedded in your skin)" - : " (being worn)"); + /* in case of perm_invent update while Wear/Takeoff + is in progress; check doffing() before donning() + because donning() returns True for both cases */ + : doffing(obj) ? " (being doffed)" + : donning(obj) ? " (being donned)" + : " (being worn)"); /*FALLTHRU*/ case WEAPON_CLASS: if (ispoisoned) From 5a432d0c97c6868b5968e35ac4999e5149eca6d8 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 25 Feb 2019 15:48:29 -0800 Subject: [PATCH 4/6] toggling persistent inventory window Something else noticed while testing #H8271: toggling perm_invent on with 'O' didn't show anything (at least with curses) until some later action caused it to be updated. Make updating persistent inventory be included with full redraw and set the need_redraw flag when toggling perm_invent. --- doc/fixes36.2 | 3 ++- src/display.c | 5 ++++- src/options.c | 17 ++++++++++------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index e9d671467..e7524f32a 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.264 $ $NHDT-Date: 1551138255 2019/02/25 23:44:15 $ +$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.265 $ $NHDT-Date: 1551138503 2019/02/25 23:48:23 $ This fixes36.2 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.1 in April 2018. Please note, however, @@ -383,6 +383,7 @@ early rolling boulder trap lacking any boulder might still have the corpse persistent inventory window would show "(being worn)" for armor that was in the midst of being put on or taken off; it is 'partly worn' in such circumstances so "being worn" could be misleading +toggling perm_invent on didn't immediately show persistent inventory window Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/src/display.c b/src/display.c index b5bdac208..281b5f57e 100644 --- a/src/display.c +++ b/src/display.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 display.c $NHDT-Date: 1540502147 2018/10/25 21:15:47 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.94 $ */ +/* NetHack 3.6 display.c $NHDT-Date: 1551138503 2019/02/25 23:48:23 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.97 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1374,6 +1374,9 @@ docrt() /* overlay with monsters */ see_monsters(); + /* perm_invent */ + update_inventory(); + context.botlx = 1; /* force a redraw of the bottom line */ } diff --git a/src/options.c b/src/options.c index b7ec363a2..64d8d9dea 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 options.c $NHDT-Date: 1546657409 2019/01/05 03:03:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.351 $ */ +/* NetHack 3.6 options.c $NHDT-Date: 1551138503 2019/02/25 23:48:23 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.355 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -440,7 +440,7 @@ static struct Comp_Opt { { "DECgraphics", "load DECGraphics display symbols", 70, SET_IN_FILE }, { "IBMgraphics", "load IBMGraphics display symbols", 70, SET_IN_FILE }, #ifdef CURSES_GRAPHICS - {"cursesgraphics", "load curses display symbols", 70, SET_IN_FILE}, + { "cursesgraphics", "load curses display symbols", 70, SET_IN_FILE }, #endif #ifdef MAC_GRAPHICS_ENV { "Macgraphics", "load MACGraphics display symbols", 70, SET_IN_FILE }, @@ -3987,8 +3987,11 @@ boolean tinitial, tfrom_file; #endif context.botl = TRUE; } else if (boolopt[i].addr == &flags.invlet_constant) { - if (flags.invlet_constant) + if (flags.invlet_constant) { reassign(); + if (iflags.perm_invent) + need_redraw = TRUE; + } } else if (boolopt[i].addr == &flags.lit_corridor || boolopt[i].addr == &flags.dark_room) { /* @@ -4006,6 +4009,10 @@ boolean tinitial, tfrom_file; || boolopt[i].addr == &iflags.use_inverse || boolopt[i].addr == &iflags.hilite_pile || boolopt[i].addr == &iflags.hilite_pet + || boolopt[i].addr == &iflags.perm_invent +#ifdef CURSES_GRAPHICS + || boolopt[i].addr == &iflags.cursesgraphics +#endif || boolopt[i].addr == &iflags.wc_ascii_map || boolopt[i].addr == &iflags.wc_tiled_map) { need_redraw = TRUE; @@ -4014,10 +4021,6 @@ boolean tinitial, tfrom_file; status_initialize(REASSESS_ONLY); need_redraw = TRUE; #endif -#ifdef CURSES_GRAPHICS - } else if ((boolopt[i].addr) == &iflags.cursesgraphics) { - need_redraw = TRUE; -#endif #ifdef TEXTCOLOR } else if (boolopt[i].addr == &iflags.use_color) { need_redraw = TRUE; From 1a028d11975e7099a95e47ac0ef9235c0d881c24 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 26 Feb 2019 15:16:42 -0800 Subject: [PATCH 5/6] curses run-time options This started out as an attempt to document the curses options in the Guidebook, but I didn't actually get that far. Instead, integrate the curses options better via more consistent WC/WC2 usage. This prevents 'guicolor' from showing up as a boolean option for non-curses interface in curses+other binary. For curses itself, let 'petattr' be set/reset via 'O'. Also, accept 'Dim' as a possible pet highlight attribute since it already handles all the other ordinary attributes. I'm not sure what leftline and rightline highlighting are supposed to do. They were missing for ncurses (or maybe they're misspelled for PDcurses?) but adding them didn't produce any visible effect (using TERM=xterm-256color on OSX with default font/character set). Not addressed: 1) general confusion about compile-time vs run-time option filtering; 2) curses pet highlighting only works if 'color' option is enabled. --- include/wincurs.h | 7 +++ src/options.c | 142 ++++++++++++++++++++++++++---------------- win/curses/cursinit.c | 12 ++-- win/curses/cursmisc.c | 105 ++++++++++++++++++++++--------- win/curses/cursmisc.h | 1 + 5 files changed, 178 insertions(+), 89 deletions(-) diff --git a/include/wincurs.h b/include/wincurs.h index cb43f3729..ddf026483 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -45,6 +45,12 @@ extern WINDOW *mapwin, *statuswin, *messagewin; /* Main windows */ # endif #endif +#if !defined(A_LEFTLINE) && defined(A_LEFT) +#define A_LEFTLINE A_LEFT +#endif +#if !defined(A_RIGHTLINE) && defined(A_RIGHT) +#define A_RIGHTLINE A_RIGHT +#endif typedef enum orient_type { @@ -158,6 +164,7 @@ extern void curses_rtrim(char *str); extern int curses_get_count(int first_digit); extern int curses_convert_attr(int attr); extern int curses_read_attrs(char *attrs); +extern char *curses_fmt_attrs(char *); extern int curses_convert_keys(int key); extern int curses_get_mouse(int *mousex, int *mousey, int *mod); diff --git a/src/options.c b/src/options.c index 64d8d9dea..2c5e463ef 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 options.c $NHDT-Date: 1551138503 2019/02/25 23:48:23 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.355 $ */ +/* NetHack 3.6 options.c $NHDT-Date: 1551222973 2019/02/26 23:16:13 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.356 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -29,6 +29,7 @@ NEARDATA struct instance_flags iflags; /* provide linkage */ #ifdef CURSES_GRAPHICS extern int curses_read_attrs(char *attrs); +extern char *curses_fmt_attrs(char *); #endif enum window_option_types { @@ -131,9 +132,9 @@ static struct Bool_Opt { { "flush", (boolean *) 0, FALSE, SET_IN_FILE }, #endif { "force_invmenu", &iflags.force_invmenu, FALSE, SET_IN_GAME }, - { "fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE }, + { "fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE }, /*WC2*/ { "goldX", &iflags.goldX, FALSE, SET_IN_GAME }, - { "guicolor", &iflags.wc2_guicolor, TRUE, SET_IN_GAME}, + { "guicolor", &iflags.wc2_guicolor, TRUE, SET_IN_GAME}, /*WC2*/ { "help", &flags.help, TRUE, SET_IN_GAME }, { "herecmd_menu", &iflags.herecmd_menu, FALSE, SET_IN_GAME }, { "hilite_pet", &iflags.wc_hilite_pet, FALSE, SET_IN_GAME }, /*WC*/ @@ -209,7 +210,7 @@ static struct Bool_Opt { { "showscore", (boolean *) 0, FALSE, SET_IN_FILE }, #endif { "silent", &flags.silent, TRUE, SET_IN_GAME }, - { "softkeyboard", &iflags.wc2_softkeyboard, FALSE, SET_IN_FILE }, + { "softkeyboard", &iflags.wc2_softkeyboard, FALSE, SET_IN_FILE }, /*WC2*/ { "sortpack", &flags.sortpack, TRUE, SET_IN_GAME }, { "sparkle", &flags.sparkle, TRUE, SET_IN_GAME }, { "splash_screen", &iflags.wc_splash_screen, TRUE, DISP_IN_GAME }, /*WC*/ @@ -228,7 +229,7 @@ static struct Bool_Opt { #ifdef DEBUG { "travel_debug", &iflags.trav_debug, FALSE, SET_IN_WIZGAME }, /*hack.c*/ #endif - { "use_darkgray", &iflags.wc2_darkgray, TRUE, SET_IN_FILE }, + { "use_darkgray", &iflags.wc2_darkgray, TRUE, SET_IN_FILE }, /*WC2*/ #ifdef WIN32 { "use_inverse", &iflags.wc_inverse, TRUE, SET_IN_GAME }, /*WC*/ #else @@ -243,7 +244,7 @@ static struct Bool_Opt { { "whatis_menu", &iflags.getloc_usemenu, FALSE, SET_IN_GAME }, { "whatis_moveskip", &iflags.getloc_moveskip, FALSE, SET_IN_GAME }, { "wizweight", &iflags.wizweight, FALSE, SET_IN_WIZGAME }, - { "wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME }, + { "wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME }, /*WC2*/ #ifdef ZEROCOMP { "zerocomp", &iflags.zerocomp, #if defined(COMPRESS) || defined(ZLIB_COMP) @@ -344,19 +345,18 @@ static struct Comp_Opt { #ifdef CHANGE_COLOR { "palette", #ifndef WIN32 - "palette (00c/880/-fff is blue/yellow/reverse white)", 15, - SET_IN_GAME }, + "palette (00c/880/-fff is blue/yellow/reverse white)", 15, SET_IN_GAME #else - "palette (adjust an RGB color in palette (color-R-G-B)", 15, - SET_IN_FILE }, + "palette (adjust an RGB color in palette (color-R-G-B)", 15, SET_IN_FILE #endif + }, #if defined(MAC) { "hicolor", "same as palette, only order is reversed", 15, SET_IN_FILE }, #endif #endif { "paranoid_confirmation", "extra prompting in certain situations", 28, SET_IN_GAME }, - { "petattr", "attributes for highlighting pets", 12, SET_IN_FILE }, + { "petattr", "attributes for highlighting pets", 88, SET_IN_GAME }, { "pettype", "your preferred initial pet type", 4, DISP_IN_GAME }, { "pickup_burden", "maximum burden picked up before prompt", 20, SET_IN_GAME }, @@ -409,6 +409,9 @@ static struct Comp_Opt { #endif { "suppress_alert", "suppress alerts about version-specific features", 8, SET_IN_GAME }, + /* term_cols,term_rows -> WC2_TERM_SIZE (6: room to format 1..32767) */ + { "term_cols", "number of columns", 6, SET_IN_FILE }, /*WC2*/ + { "term_rows", "number of rows", 6, SET_IN_FILE }, /*WC2*/ { "tile_width", "width of tiles", 20, DISP_IN_GAME }, /*WC*/ { "tile_height", "height of tiles", 20, DISP_IN_GAME }, /*WC*/ { "tile_file", "name of tile file", 70, DISP_IN_GAME }, /*WC*/ @@ -430,6 +433,7 @@ static struct Comp_Opt { { "whatis_filter", "filter coordinate locations when targeting next or previous", 1, SET_IN_GAME }, + { "windowborders", "1 (on), 2 (off), 3 (auto)", 9, DISP_IN_GAME }, /*WC2*/ { "windowcolors", "the foreground/background colors of windows", /*WC*/ 80, DISP_IN_GAME }, { "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME }, @@ -3325,6 +3329,7 @@ boolean tinitial, tfrom_file; return retval; } #endif /* VIDEOSHADES */ + #ifdef MSDOS #ifdef NO_TERMS /* video:string -- must be after longer tests */ @@ -3447,8 +3452,8 @@ boolean tinitial, tfrom_file; if (negated) { bad_negation(fullname, FALSE); return FALSE; - } else { #if defined(WIN32) + } else { op = string_for_opt(opts, 0); if (!op) return FALSE; @@ -3593,29 +3598,34 @@ boolean tinitial, tfrom_file; } return retval; } + #ifdef CURSES_GRAPHICS /* WINCAP2 - * term_cols:amount */ + * term_cols:amount or term_rows:amount */ fullname = "term_cols"; - if (match_optname(opts, fullname, sizeof "term_cols" - 1, TRUE)) { - op = string_for_opt(opts, negated); - iflags.wc2_term_cols = atoi(op); - if (negated) { - bad_negation(fullname, FALSE); - return FALSE; - } - return retval; - } + if (match_optname(opts, fullname, 8, TRUE) + /* alternate spelling */ + || match_optname(opts, "term_columns", 9, TRUE) + /* different option but identical handlng */ + || (fullname = "term_rows", match_optname(opts, fullname, 8, TRUE))) { + long ltmp; - /* WINCAP2 - * term_rows:amount */ - fullname = "term_rows"; - if (match_optname(opts, fullname, sizeof "term_rows" - 1, TRUE)) { op = string_for_opt(opts, negated); - iflags.wc2_term_rows = atoi(op); + ltmp = atol(op); if (negated) { bad_negation(fullname, FALSE); - return FALSE; + retval = FALSE; + + /* this just checks atol() sanity, not logical window size sanity */ + } else if (ltmp <= 0L || ltmp >= (long) LARGEST_INT) { + config_error_add("Invalid %s: %ld", fullname, ltmp); + retval = FALSE; + + } else { + if (!strcmp(fullname, "term_rows")) + iflags.wc2_term_rows = (int) ltmp; + else /* !strcmp(fullname, "term_cols") */ + iflags.wc2_term_cols = (int) ltmp; } return retval; } @@ -3625,22 +3635,31 @@ boolean tinitial, tfrom_file; fullname = "petattr"; if (match_optname(opts, fullname, sizeof "petattr" - 1, TRUE)) { op = string_for_opt(opts, negated); - if (op && !negated) { + if (op && negated) { + bad_negation(fullname, TRUE); + retval = FALSE; + } else if (op) { #ifdef CURSES_GRAPHICS - iflags.wc2_petattr = curses_read_attrs(op); - if (!curses_read_attrs(op)) { + int itmp = curses_read_attrs(op); + + if (itmp == -1) { config_error_add("Unknown %s parameter '%s'", fullname, opts); - return FALSE; - } + retval = FALSE; + } else + iflags.wc2_petattr = itmp; #else /* non-curses windowports will not use this flag anyway * but the above will not compile if we don't have curses. * Just set it to a sensible default: */ - iflags.wc2_petattr = ATR_INVERSE + iflags.wc2_petattr = ATR_INVERSE; #endif } else if (negated) { - bad_negation(fullname, TRUE); - return FALSE; + iflags.wc2_petattr = ATR_NONE; + } + if (retval) { + iflags.hilite_pet = (iflags.wc2_petattr != ATR_NONE); + if (!initial) + need_redraw = TRUE; } return retval; } @@ -3648,28 +3667,31 @@ boolean tinitial, tfrom_file; /* WINCAP2 * windowborders:n */ fullname = "windowborders"; - if (match_optname(opts, fullname, sizeof "windowborders" - 1, TRUE)) { + if (match_optname(opts, fullname, 10, TRUE)) { op = string_for_opt(opts, negated); if (negated && op) { bad_negation(fullname, TRUE); - return FALSE; + retval = FALSE; } else { + int itmp; + if (negated) - iflags.wc2_windowborders = 2; /* Off */ + itmp = 2; /* Off */ else if (!op) - iflags.wc2_windowborders = 1; /* On */ - else /* Value supplied */ - iflags.wc2_windowborders = atoi(op); - if ((iflags.wc2_windowborders > 3) - || (iflags.wc2_windowborders < 1)) { - iflags.wc2_windowborders = 0; - config_error_add("Badoption - windowborders %s.", opts); - return FALSE; + itmp = 1; /* On */ + else /* Value supplied; expect 1 (on), 2 (off), or 3 (auto) */ + itmp = atoi(op); + + if (itmp < 1 || itmp > 3) { + config_error_add("Invalid %s: %s.", fullname, opts); + retval = FALSE; + } else { + iflags.wc2_windowborders = itmp; } } return retval; } -#endif +#endif /* CURSES_GRAPHICS */ /* menustyle:traditional or combination or full or partial */ fullname = "menustyle"; @@ -5592,6 +5614,18 @@ char *buf; if (flags.paranoia_bits & paranoia[i].flagmask) Sprintf(eos(tmpbuf), " %s", paranoia[i].argname); Strcpy(buf, tmpbuf[0] ? &tmpbuf[1] : "none"); + } else if (!strcmp(optname, "petattr")) { +#ifdef CURSES_GRAPHICS + if (WINDOWPORT("curses")) { + char tmpbuf[QBUFSZ]; + + Strcpy(buf, curses_fmt_attrs(tmpbuf)); + } else +#endif + if (iflags.wc2_petattr != 0) + Sprintf(buf, "0x%08x", iflags.wc2_petattr); + else + Strcpy(buf, defopt); } else if (!strcmp(optname, "pettype")) { Sprintf(buf, "%s", (preferred_pet == 'c') ? "cat" : (preferred_pet == 'd') ? "dog" @@ -5674,7 +5708,6 @@ char *buf; symset[PRIMARY].name ? symset[PRIMARY].name : "default"); if (currentgraphics == PRIMARY && symset[PRIMARY].name) Strcat(buf, ", active"); -#ifdef CURSES_GRAPHICS } else if (!strcmp(optname, "term_cols")) { if (iflags.wc2_term_cols) Sprintf(buf, "%d", iflags.wc2_term_cols); @@ -5682,10 +5715,9 @@ char *buf; Strcpy(buf, defopt); } else if (!strcmp(optname, "term_rows")) { if (iflags.wc2_term_rows) - Sprintf(buf, "%d",iflags.wc2_term_rows); + Sprintf(buf, "%d", iflags.wc2_term_rows); else Strcpy(buf, defopt); -#endif } else if (!strcmp(optname, "tile_file")) { Sprintf(buf, "%s", iflags.wc_tile_file ? iflags.wc_tile_file : defopt); @@ -6433,9 +6465,11 @@ static struct wc_Opt wc2_options[] = { { "status hilite rules", WC2_HILITE_STATUS }, /* statushilites doesn't have its own bit */ { "statushilites", WC2_HILITE_STATUS }, -#ifdef CURSES_GRAPHICS - {"windowborders", WC2_WINDOWBORDERS}, -#endif + { "term_cols", WC2_TERM_SIZE }, + { "term_rows", WC2_TERM_SIZE }, + { "petattr", WC2_PETATTR }, + { "guicolor", WC2_GUICOLOR }, + { "windowborders", WC2_WINDOWBORDERS }, { (char *) 0, 0L } }; diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 5f53df4ed..1cdc62a18 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -835,11 +835,15 @@ curses_init_options() iflags.wc2_windowborders = 3; /* Set to auto if not specified */ } - if (!iflags.wc2_petattr) { - iflags.wc2_petattr = A_REVERSE; - } else { /* Pet attribute specified, so hilite_pet should be true */ - + /* fix up pet highlighting */ + if (iflags.wc2_petattr == -1) /* shouldn't happen */ + iflags.wc2_petattr = A_NORMAL; + if (iflags.wc2_petattr != A_NORMAL) { + /* Pet attribute specified, so hilite_pet should be true */ iflags.hilite_pet = TRUE; + } else if (iflags.hilite_pet) { + /* pet highlighting specified, so don't leave petattr at A_NORMAL */ + iflags.wc2_petattr = A_REVERSE; } #ifdef NCURSES_MOUSE_VERSION diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index b4b3764d7..63bf2e03d 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -47,7 +47,7 @@ curses_read_char() ch = curses_convert_keys(ch); if (ch == 0) { - ch = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */ + ch = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */ } #if defined(ALT_0) && defined(ALT_9) /* PDCurses, maybe others */ if ((ch >= ALT_0) && (ch <= ALT_9)) { @@ -66,11 +66,11 @@ curses_read_char() #ifdef KEY_RESIZE /* Handle resize events via get_nh_event, not this code */ if (ch == KEY_RESIZE) { - ch = '\033'; /* NetHack doesn't know what to do with KEY_RESIZE */ + ch = '\033'; /* NetHack doesn't know what to do with KEY_RESIZE */ } #endif - if (counting && !isdigit(ch)) { /* Dismiss count window if necissary */ + if (counting && !isdigit(ch)) { /* Dismiss count window if necissary */ curses_count_window(NULL); curses_refresh_nethack_windows(); } @@ -249,7 +249,7 @@ curses_num_lines(const char *str, int width) if (last_space == 0) { /* No spaces found */ last_space = count - 1; } - for (count = (last_space + 1); (size_t) count < strlen(substr); count++) { + for (count = (last_space + 1); count < (int) strlen(substr); count++) { tmpstr[count - (last_space + 1)] = substr[count]; } tmpstr[count - (last_space + 1)] = '\0'; @@ -389,7 +389,7 @@ curses_str_remainder(const char *str, int width, int line_num) if (substr[count] == '\0') { break; } - for (count = (last_space + 1); (size_t) count < strlen(substr); count++) { + for (count = (last_space + 1); count < (int) strlen(substr); count++) { tmpstr[count - (last_space + 1)] = substr[count]; } tmpstr[count - (last_space + 1)] = '\0'; @@ -682,44 +682,87 @@ curses_convert_attr(int attr) /* Map letter attributes from a string to bitmask. Return mask on -success, or 0 if not found */ + success (might be 0), or -1 if not found. */ int curses_read_attrs(char *attrs) { int retattr = 0; - if (strchr(attrs, 'b') || strchr(attrs, 'B')) { - retattr = retattr | A_BOLD; - } - if (strchr(attrs, 'i') || strchr(attrs, 'I')) { - retattr = retattr | A_REVERSE; - } - if (strchr(attrs, 'u') || strchr(attrs, 'U')) { - retattr = retattr | A_UNDERLINE; - } - if (strchr(attrs, 'k') || strchr(attrs, 'K')) { - retattr = retattr | A_BLINK; - } + if (!attrs || !*attrs) + return A_NORMAL; + + if (strchr(attrs, 'b') || strchr(attrs, 'B')) + retattr |= A_BOLD; + if (strchr(attrs, 'i') || strchr(attrs, 'I')) /* inverse */ + retattr |= A_REVERSE; + if (strchr(attrs, 'u') || strchr(attrs, 'U')) + retattr |= A_UNDERLINE; + if (strchr(attrs, 'k') || strchr(attrs, 'K')) + retattr |= A_BLINK; + if (strchr(attrs, 'd') || strchr(attrs, 'D')) + retattr |= A_DIM; #ifdef A_ITALIC - if (strchr(attrs, 't') || strchr(attrs, 'T')) { - retattr = retattr | A_ITALIC; - } -#endif -#ifdef A_RIGHTLINE - if (strchr(attrs, 'r') || strchr(attrs, 'R')) { - retattr = retattr | A_RIGHTLINE; - } + if (strchr(attrs, 't') || strchr(attrs, 'T')) + retattr |= A_ITALIC; #endif #ifdef A_LEFTLINE - if (strchr(attrs, 'l') || strchr(attrs, 'L')) { - retattr = retattr | A_LEFTLINE; - } + if (strchr(attrs, 'l') || strchr(attrs, 'L')) + retattr |= A_LEFTLINE; #endif - +#ifdef A_RIGHTLINE + if (strchr(attrs, 'r') || strchr(attrs, 'R')) + retattr |= A_RIGHTLINE; +#endif + if (retattr == 0) { + /* still default; check for none/normal */ + if (strchr(attrs, 'n') || strchr(attrs, 'N')) + retattr = A_NORMAL; + else + retattr = -1; /* error */ + } return retattr; } +/* format iflags.wc2_petattr into "+a+b..." for set bits a, b, ... + (used by core's 'O' command; return value points past leading '+') */ +char * +curses_fmt_attrs(outbuf) +char *outbuf; +{ + int attr = iflags.wc2_petattr; + + outbuf[0] = '\0'; + if (attr == A_NORMAL) { + Strcpy(outbuf, "+N(None)"); + } else { + if (attr & A_BOLD) + Strcat(outbuf, "+B(Bold)"); + if (attr & A_REVERSE) + Strcat(outbuf, "+I(Inverse)"); + if (attr & A_UNDERLINE) + Strcat(outbuf, "+U(Underline)"); + if (attr & A_BLINK) + Strcat(outbuf, "+K(blinK)"); + if (attr & A_DIM) + Strcat(outbuf, "+D(Dim)"); +#ifdef A_ITALIC + if (attr & A_ITALIC) + Strcat(outbuf, "+T(iTalic)"); +#endif +#ifdef A_LEFTLINE + if (attr & A_LEFTLINE) + Strcat(outbuf, "+L(Left line)"); +#endif +#ifdef A_RIGHTLINE + if (attr & A_RIGHTLINE) + Strcat(outbuf, "+R(Right line)"); +#endif + } + if (!*outbuf) + Sprintf(outbuf, "+unknown [%d]", attr); + return &outbuf[1]; +} /* Convert special keys into values that NetHack can understand. Currently this is limited to arrow keys, but this may be expanded. */ @@ -827,7 +870,7 @@ curses_get_mouse(int *mousex, int *mousey, int *mod) #ifdef NCURSES_MOUSE_VERSION MEVENT event; - if (getmouse(&event) == OK) { /* When the user clicks left mouse button */ + if (getmouse(&event) == OK) { /* When the user clicks left mouse button */ if (event.bstate & BUTTON1_CLICKED) { /* See if coords are in map window & convert coords */ if (wmouse_trafo(mapwin, &event.y, &event.x, TRUE)) { diff --git a/win/curses/cursmisc.h b/win/curses/cursmisc.h index 364901267..392d67d11 100644 --- a/win/curses/cursmisc.h +++ b/win/curses/cursmisc.h @@ -27,6 +27,7 @@ void curses_rtrim(char *str); int curses_get_count(int first_digit); int curses_convert_attr(int attr); int curses_read_attrs(char *attrs); +char *curses_fmt_attrs(char *); int curses_convert_keys(int key); int curses_get_mouse(int *mousex, int *mousey, int *mod); From be3092bed480c600ee5c003914007359221fa0cb Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 26 Feb 2019 19:49:24 -0500 Subject: [PATCH 6/6] some fish should lay their eggs in the water rather than on land Generally, fish should lay their eggs in the water and not on land, but the game was only allowing the opposite. Eels are catadromous and lay their eggs in the Sargasso Sea, not in the dungeon. --- doc/fixes36.2 | 1 + include/mondata.h | 2 ++ src/polyself.c | 8 ++++++-- src/sit.c | 19 +++++++++++++++---- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index e7524f32a..846fc9c51 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -384,6 +384,7 @@ persistent inventory window would show "(being worn)" for armor that was in the midst of being put on or taken off; it is 'partly worn' in such circumstances so "being worn" could be misleading toggling perm_invent on didn't immediately show persistent inventory window +some fish should lay their eggs in the water rather than on land Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/include/mondata.h b/include/mondata.h index d8c3511b2..41b5f70f4 100644 --- a/include/mondata.h +++ b/include/mondata.h @@ -71,6 +71,8 @@ #define slimeproof(ptr) \ ((ptr) == &mons[PM_GREEN_SLIME] || flaming(ptr) || noncorporeal(ptr)) #define lays_eggs(ptr) (((ptr)->mflags1 & M1_OVIPAROUS) != 0L) +#define eggs_in_water(ptr) \ + (lays_eggs(ptr) && (ptr)->mlet == S_EEL && is_swimmer(ptr)) #define regenerates(ptr) (((ptr)->mflags1 & M1_REGEN) != 0L) #define perceives(ptr) (((ptr)->mflags1 & M1_SEE_INVIS) != 0L) #define can_teleport(ptr) (((ptr)->mflags1 & M1_TPORT) != 0L) diff --git a/src/polyself.c b/src/polyself.c index b9e6fa81b..c30ac6583 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -784,8 +784,12 @@ int mntmp; if (is_vampire(youmonst.data)) pline(use_thec, monsterc, "change shape"); - if (lays_eggs(youmonst.data) && flags.female) - pline(use_thec, "sit", "lay an egg"); + if (lays_eggs(youmonst.data) && flags.female && + !(youmonst.data == &mons[PM_GIANT_EEL] + || youmonst.data == &mons[PM_ELECTRIC_EEL])) + pline(use_thec, "sit", + eggs_in_water(youmonst.data) ? + "spawn in the water" : "lay an egg"); } /* you now know what an egg of your type looks like */ diff --git a/src/sit.c b/src/sit.c index 5f85bb13e..09cbc9bf2 100644 --- a/src/sit.c +++ b/src/sit.c @@ -116,12 +116,13 @@ dosit() You("sit down."); dotrap(trap, VIASITTING); } - } else if (Underwater || Is_waterlevel(&u.uz)) { + } else if ((Underwater || Is_waterlevel(&u.uz)) + && !eggs_in_water(youmonst.data)) { if (Is_waterlevel(&u.uz)) There("are no cushions floating nearby."); else You("sit down on the muddy bottom."); - } else if (is_pool(u.ux, u.uy)) { + } else if (is_pool(u.ux, u.uy) && !eggs_in_water(youmonst.data)) { in_water: You("sit in the %s.", hliquid("water")); if (!rn2(10) && uarm) @@ -297,8 +298,18 @@ dosit() } else if (u.uhunger < (int) objects[EGG].oc_nutrition) { You("don't have enough energy to lay an egg."); return 0; + } else if (eggs_in_water(youmonst.data)) { + if (!(Underwater || Is_waterlevel(&u.uz))) { + pline("A splash tetra you are not."); + return 0; + } + if (Upolyd && + (youmonst.data == &mons[PM_GIANT_EEL] + || youmonst.data == &mons[PM_ELECTRIC_EEL])) { + You("yearn for the Sargasso Sea."); + return 0; + } } - uegg = mksobj(EGG, FALSE, FALSE); uegg->spe = 1; uegg->quan = 1L; @@ -306,7 +317,7 @@ dosit() /* this sets hatch timers if appropriate */ set_corpsenm(uegg, egg_type_from_parent(u.umonnum, FALSE)); uegg->known = uegg->dknown = 1; - You("lay an egg."); + You("%s an egg.", eggs_in_water(youmonst.data) ? "spawn" : "lay"); dropy(uegg); stackobj(uegg); morehungry((int) objects[EGG].oc_nutrition);