diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 7a8595c78..846fc9c51 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.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, @@ -380,6 +380,11 @@ 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 +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 @@ -441,6 +446,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/include/mondata.h b/include/mondata.h index 7f15365d6..e35601ae4 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/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/display.c b/src/display.c index a8fe3248d..786e0f64b 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(); + g.context.botlx = 1; /* force a redraw of the bottom line */ } diff --git a/src/do_wear.c b/src/do_wear.c index a1a6567fe..f71c6819d 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. */ @@ -1227,7 +1227,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/end.c b/src/end.c index fe4838b11..08109b05d 100644 --- a/src/end.c +++ b/src/end.c @@ -114,8 +114,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/src/hack.c b/src/hack.c index 0d3ddac3b..e6f332a22 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. */ @@ -2885,6 +2885,8 @@ const char *msg_override; encumbrance hack for levitation--see weight_cap()) */ g.afternmv = (int NDECL((*))) 0; (void) (*f)(); + /* for finishing Armor/Boots/&c_on() */ + update_inventory(); } } diff --git a/src/objnam.c b/src/objnam.c index 360942f5e..a88a390e6 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. */ @@ -1029,7 +1029,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) diff --git a/src/options.c b/src/options.c index 8486e1cbc..9015fb57d 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: 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 const 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 const 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 const 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 const 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 }, @@ -440,7 +444,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 }, @@ -3315,6 +3319,7 @@ boolean tinitial, tfrom_file; return retval; } #endif /* VIDEOSHADES */ + #ifdef MSDOS #ifdef NO_TERMS /* video:string -- must be after longer tests */ @@ -3437,8 +3442,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; @@ -3583,29 +3588,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; } @@ -3615,22 +3625,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) + g.opt_need_redraw = TRUE; } return retval; } @@ -3638,28 +3657,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"; @@ -3977,8 +3999,11 @@ boolean tinitial, tfrom_file; #endif g.context.botl = TRUE; } else if (boolopt[i].addr == &flags.invlet_constant) { - if (flags.invlet_constant) + if (flags.invlet_constant) { reassign(); + if (iflags.perm_invent) + g.opt_need_redraw = TRUE; + } } else if (boolopt[i].addr == &flags.lit_corridor || boolopt[i].addr == &flags.dark_room) { /* @@ -3996,6 +4021,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) { g.opt_need_redraw = TRUE; @@ -4004,10 +4033,6 @@ boolean tinitial, tfrom_file; status_initialize(REASSESS_ONLY); g.opt_need_redraw = TRUE; #endif -#ifdef CURSES_GRAPHICS - } else if ((boolopt[i].addr) == &iflags.cursesgraphics) { - g.opt_need_redraw = TRUE; -#endif #ifdef TEXTCOLOR } else if (boolopt[i].addr == &iflags.use_color) { g.opt_need_redraw = TRUE; @@ -5576,6 +5601,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", (g.preferred_pet == 'c') ? "cat" : (g.preferred_pet == 'd') ? "dog" @@ -5658,7 +5695,6 @@ char *buf; g.symset[PRIMARY].name ? g.symset[PRIMARY].name : "default"); if (g.currentgraphics == PRIMARY && g.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); @@ -5666,10 +5702,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); @@ -6417,9 +6452,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/src/polyself.c b/src/polyself.c index 75ebfd919..d48b07c54 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -780,8 +780,12 @@ int mntmp; if (is_vampire(g.youmonst.data)) pline(use_thec, monsterc, "change shape"); - if (lays_eggs(g.youmonst.data) && flags.female) - pline(use_thec, "sit", "lay an egg"); + if (lays_eggs(g.youmonst.data) && flags.female && + !(g.youmonst.data == &mons[PM_GIANT_EEL] + || g.youmonst.data == &mons[PM_ELECTRIC_EEL])) + pline(use_thec, "sit", + eggs_in_water(g.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 d169f372f..b4e9d32ea 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(g.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(g.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(g.youmonst.data)) { + if (!(Underwater || Is_waterlevel(&u.uz))) { + pline("A splash tetra you are not."); + return 0; + } + if (Upolyd && + (g.youmonst.data == &mons[PM_GIANT_EEL] + || g.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(g.youmonst.data) ? "spawn" : "lay"); dropy(uegg); stackobj(uegg); morehungry((int) objects[EGG].oc_nutrition); diff --git a/sys/unix/NetHack.xcodeproj/project.pbxproj b/sys/unix/NetHack.xcodeproj/project.pbxproj index dcb402a98..e566de3dc 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; diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 09326635c..8abe6b592 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 63b3426db..704cce471 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);