From 5558d62aa8d9a7d8d900d3f0f0718bb0846cac5d Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Tue, 20 Feb 2018 21:53:27 +0000 Subject: [PATCH 01/57] Wake up monsters, and let them stop eating, before angering them If we do it the other way round, then mimics will forget what they're mimicking without a seemimic() call, meaning that the line-of-sight calculations can get confused if the mimic was mimicking something opaque. --- src/mon.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mon.c b/src/mon.c index 62fb34a8f..7e82ba651 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2751,7 +2751,6 @@ boolean via_attack; } } } - } /* wake up a monster, possibly making it angry in the process */ @@ -2761,9 +2760,6 @@ register struct monst *mtmp; boolean via_attack; { mtmp->msleeping = 0; - finish_meating(mtmp); - if (via_attack) - setmangry(mtmp, TRUE); if (mtmp->m_ap_type) { seemimic(mtmp); } else if (context.forcefight && !context.mon_moving @@ -2771,6 +2767,9 @@ boolean via_attack; mtmp->mundetected = 0; newsym(mtmp->mx, mtmp->my); } + finish_meating(mtmp); + if (via_attack) + setmangry(mtmp, TRUE); } /* Wake up nearby monsters without angering them. */ From 964120266ebc2387f86ba98a1ed084985565ad2c Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 20 Feb 2018 19:32:47 -0800 Subject: [PATCH 02/57] pline() -> raw_print() -> dumplog() Reorder some code in pline() so that early pline messages which use raw_print() instead of putstr(WIN_MESSAGE) are included in the DUMPLOG message buffer. If the game ends soon enough they'll be shown in the final log; otherwise they'll get pushed out of the buffer once enough later messages are delivered. --- src/pline.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/pline.c b/src/pline.c index d6ee70266..319f13946 100644 --- a/src/pline.c +++ b/src/pline.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pline.c $NHDT-Date: 1510990667 2017/11/18 07:37:47 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.64 $ */ +/* NetHack 3.6 pline.c $NHDT-Date: 1519183957 2018/02/21 03:32:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.65 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -129,14 +129,7 @@ VA_DECL(const char *, line) pbuf[BUFSZ - 1] = '\0'; line = pbuf; } - if (!iflags.window_inited) { - raw_print(line); - iflags.last_msg = PLNMSG_UNKNOWN; - return; - } - msgtyp = MSGTYP_NORMAL; - no_repeat = (pline_flags & PLINE_NOREPEAT) ? TRUE : FALSE; #ifdef DUMPLOG /* We hook here early to have options-agnostic output. * Unfortunately, that means Norep() isn't honored (general issue) and @@ -145,10 +138,26 @@ VA_DECL(const char *, line) if ((pline_flags & SUPPRESS_HISTORY) == 0) dumplogmsg(line); #endif + + if (!iflags.window_inited) { + raw_print(line); + iflags.last_msg = PLNMSG_UNKNOWN; + return; + } + + msgtyp = MSGTYP_NORMAL; + no_repeat = (pline_flags & PLINE_NOREPEAT) ? TRUE : FALSE; if ((pline_flags & OVERRIDE_MSGTYPE) == 0) { msgtyp = msgtype_type(line, no_repeat); if (msgtyp == MSGTYP_NOSHOW || (msgtyp == MSGTYP_NOREP && !strcmp(line, prevmsg))) + /* FIXME: we need a way to tell our caller that this message + * was suppressed so that caller doesn't set iflags.last_msg + * for something that hasn't been shown, otherwise a subsequent + * message which uses alternate wording based on that would be + * doing so out of context and probably end up seeming silly. + * (Not an issue for no-repeat but matters for no-show.) + */ return; } From 094c7f5c1bda8056323815e973928f8ebd95d177 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 21 Feb 2018 22:44:15 -0800 Subject: [PATCH 03/57] fix #6870 - clairvoyance feedback Forwarded to the contact form from a github "issue": in some circumtances clairvoyance lets you move the cursor around to examine the revealed map, and when doing so starts with "for instructions type '?'". When extended clairvoyance periodically kicks in, as opposed to explicitly casting the spell, there wasn't sufficient context to figure out what it was prompting for (unless you actually answer '?' to get instructions). Depending upon the most recent message, it could seem like quite a strange prompt. Explicitly give a clairvoyance-specific message prior to that. Also, the getpos() help was including suggestions for targetting monsters that aren't appropriate when it's being used for detection. do_name.c has had quite a bit of formatting rot slip in since 3.6.0. This fixes up the stuff I spotted by manual inspection. --- doc/fixes36.1 | 3 ++ src/detect.c | 6 +++- src/do_name.c | 82 +++++++++++++++++++++++++++------------------------ 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 2e697c5ab..69b57c25f 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -584,6 +584,9 @@ unix: fix for freeing MAIL introduced a one-byte buffer overrun which could interfere with malloc/free operation unix: fix for freeing MAIL also introduced a memory leak whenever new mail is detected and MAIL comes from the environment +when clairvoyance lets you move the cursor to examine the map (if it occurs + when engulfed or underwater or when blessed clairvoyance finds a + monster), the "for instructions type '?'" prompt could be confusing Platform- and/or Interface-Specific Fixes diff --git a/src/detect.c b/src/detect.c index 1c5f35203..d835bd86d 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 detect.c $NHDT-Date: 1495346103 2017/05/21 05:55:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.77 $ */ +/* NetHack 3.6 detect.c $NHDT-Date: 1519281847 2018/02/22 06:44:07 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.80 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1324,6 +1324,10 @@ struct obj *sobj; /* scroll--actually fake spellbook--object */ if (!level.flags.hero_memory || unconstrained || mdetected) { flush_screen(1); /* flush temp screen */ + /* the getpos() prompt from browse_map() is only shown when + flags.verbose is set, but make this unconditional so that + not-verbose users become aware of the prompting situation */ + You("sense your surroundings."); if (extended || glyph_is_monster(glyph_at(u.ux, u.uy))) ter_typ |= TER_MON; if (extended) diff --git a/src/do_name.c b/src/do_name.c index db226a548..7aceca6e1 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_name.c $NHDT-Date: 1496531112 2017/06/03 23:05:12 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.119 $ */ +/* NetHack 3.6 do_name.c $NHDT-Date: 1519281849 2018/02/22 06:44:09 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.127 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6,8 +6,7 @@ STATIC_DCL char *NDECL(nextmbuf); STATIC_DCL void FDECL(getpos_help, (BOOLEAN_P, const char *)); -STATIC_DCL int FDECL(CFDECLSPEC cmp_coord_distu, (const void *, - const void *)); +STATIC_DCL int FDECL(CFDECLSPEC cmp_coord_distu, (const void *, const void *)); STATIC_DCL boolean FDECL(gather_locs_interesting, (int, int, int)); STATIC_DCL void FDECL(gather_locs, (coord **, int *, int)); STATIC_DCL int FDECL(gloc_filter_floodfill_matcharea, (int, int)); @@ -37,12 +36,13 @@ nextmbuf() * parameter value 0 = initialize, 1 = highlight, 2 = done */ static void FDECL((*getpos_hilitefunc), (int)) = (void FDECL((*), (int))) 0; -static boolean FDECL((*getpos_getvalid), (int,int)) = (boolean FDECL((*), (int,int))) 0; +static boolean FDECL((*getpos_getvalid), (int, int)) = + (boolean FDECL((*), (int, int))) 0; void getpos_sethilite(gp_hilitef, gp_getvalidf) void FDECL((*gp_hilitef), (int)); -boolean FDECL((*gp_getvalidf), (int,int)); +boolean FDECL((*gp_getvalidf), (int, int)); { getpos_hilitefunc = gp_hilitef; getpos_getvalid = gp_getvalidf; @@ -138,16 +138,18 @@ const char *goal; visctrl(Cmd.spkeys[NHKF_GETPOS_MOVESKIP]), fastmovemode[!iflags.getloc_moveskip]); putstr(tmpwin, 0, sbuf); - - Sprintf(sbuf, "Use '%s' to toggle menu listing for possible targets.", - visctrl(Cmd.spkeys[NHKF_GETPOS_MENU])); - putstr(tmpwin, 0, sbuf); - Sprintf(sbuf, - "Use '%s' to change the mode of limiting possible targets.", - visctrl(Cmd.spkeys[NHKF_GETPOS_LIMITVIEW])); - putstr(tmpwin, 0, sbuf); + if (!iflags.terrainmode || (iflags.terrainmode & TER_DETECT) == 0) { + Sprintf(sbuf, "Use '%s' to toggle menu listing for possible targets.", + visctrl(Cmd.spkeys[NHKF_GETPOS_MENU])); + putstr(tmpwin, 0, sbuf); + Sprintf(sbuf, + "Use '%s' to change the mode of limiting possible targets.", + visctrl(Cmd.spkeys[NHKF_GETPOS_LIMITVIEW])); + putstr(tmpwin, 0, sbuf); + } if (!iflags.terrainmode) { char kbuf[BUFSZ]; + if (getpos_getvalid) { Sprintf(sbuf, "Use '%s' or '%s' to move to valid locations.", visctrl(Cmd.spkeys[NHKF_GETPOS_VALID_NEXT]), @@ -282,20 +284,21 @@ int x,y; if (glyph == gloc_filter_floodfill_match_glyph) return TRUE; - if (gloc_filter_classify_glyph(glyph) == gloc_filter_classify_glyph(gloc_filter_floodfill_match_glyph)) + if (gloc_filter_classify_glyph(glyph) + == gloc_filter_classify_glyph(gloc_filter_floodfill_match_glyph)) return TRUE; return FALSE; } void -gloc_filter_floodfill(x,y) -int x,y; +gloc_filter_floodfill(x, y) +int x, y; { - gloc_filter_floodfill_match_glyph = back_to_glyph(x,y); + gloc_filter_floodfill_match_glyph = back_to_glyph(x, y); set_selection_floodfillchk(gloc_filter_floodfill_matcharea); - selection_floodfill(gloc_filter_map, x,y, FALSE); + selection_floodfill(gloc_filter_map, x, y, FALSE); } void @@ -330,23 +333,20 @@ gloc_filter_done() } } - STATIC_OVL boolean -gather_locs_interesting(x,y, gloc) -int x,y, gloc; +gather_locs_interesting(x, y, gloc) +int x, y, gloc; { /* TODO: if glyph is a pile glyph, convert to ordinary one * in order to keep tail/boulder/rock check simple. */ int glyph = glyph_at(x, y); - if (iflags.getloc_filter == GFILTER_VIEW && !cansee(x,y)) + if (iflags.getloc_filter == GFILTER_VIEW && !cansee(x, y)) return FALSE; - if (iflags.getloc_filter == GFILTER_AREA && !GLOC_SAME_AREA(x,y) - && !GLOC_SAME_AREA(x-1,y) - && !GLOC_SAME_AREA(x,y-1) - && !GLOC_SAME_AREA(x+1,y) - && !GLOC_SAME_AREA(x,y+1)) + if (iflags.getloc_filter == GFILTER_AREA && !GLOC_SAME_AREA(x, y) + && !GLOC_SAME_AREA(x - 1, y) && !GLOC_SAME_AREA(x, y - 1) + && !GLOC_SAME_AREA(x + 1, y) && !GLOC_SAME_AREA(x, y + 1)) return FALSE; switch (gloc) { @@ -480,7 +480,8 @@ boolean fulldir; if (dx) { if (abs(dx) > 9999) dx = sgn(dx) * 9999; - Sprintf(eos(buf), "%d%s", abs(dx), dirnames[2 + (dx > 0)][fulldir]); + Sprintf(eos(buf), "%d%s", abs(dx), + dirnames[2 + (dx > 0)][fulldir]); } } return buf; @@ -544,8 +545,9 @@ int cx, cy; (void) coord_desc(cx, cy, tmpbuf, iflags.getpos_coords); custompline(SUPPRESS_HISTORY, "%s%s%s%s%s", firstmatch, *tmpbuf ? " " : "", tmpbuf, - (iflags.autodescribe && getpos_getvalid && !getpos_getvalid(cx,cy)) - ? " (illegal)" : "", + (iflags.autodescribe + && getpos_getvalid && !getpos_getvalid(cx, cy)) + ? " (illegal)" : "", (iflags.getloc_travelmode && !is_valid_travelpt(cx, cy)) ? " (no travel path)" : ""); curs(WIN_MAP, cx, cy); @@ -590,8 +592,10 @@ int gloc; tmpcc.x = garr[i].x; tmpcc.y = garr[i].y; if (do_screen_description(tmpcc, TRUE, sym, tmpbuf, &firstmatch)) { - (void) coord_desc(garr[i].x, garr[i].y, tmpbuf, iflags.getpos_coords); - Sprintf(fullbuf, "%s%s%s", firstmatch, (*tmpbuf ? " " : ""), tmpbuf); + (void) coord_desc(garr[i].x, garr[i].y, tmpbuf, + iflags.getpos_coords); + Sprintf(fullbuf, "%s%s%s", firstmatch, + (*tmpbuf ? " " : ""), tmpbuf); add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, fullbuf, MENU_UNSELECTED); } @@ -738,8 +742,9 @@ const char *goal; dy = ydir[i]; while (isok(cx + dx, cy + dy) && glyph == glyph_at(cx + dx, cy + dy) - && isok(cx + dx+xdir[i], cy+dy+ydir[i]) - && glyph == glyph_at(cx + dx+xdir[i], cy + dy+ydir[i])) { + && isok(cx + dx + xdir[i], cy + dy + ydir[i]) + && glyph == glyph_at(cx + dx + xdir[i], + cy + dy + ydir[i])) { dx += xdir[i]; dy += ydir[i]; } @@ -928,10 +933,9 @@ const char *goal; if (!force) Strcpy(note, "aborted"); - else - Sprintf(note, "use '%c', '%c', '%c', '%c' or '%s'", /* hjkl */ - Cmd.move_W, Cmd.move_S, Cmd.move_N, - Cmd.move_E, + else /* hjkl */ + Sprintf(note, "use '%c', '%c', '%c', '%c' or '%s'", + Cmd.move_W, Cmd.move_S, Cmd.move_N, Cmd.move_E, visctrl(Cmd.spkeys[NHKF_GETPOS_PICK])); pline("Unknown direction: '%s' (%s).", visctrl((char) c), note); @@ -966,7 +970,7 @@ const char *goal; if (garr[i]) free((genericptr_t) garr[i]); getpos_hilitefunc = (void FDECL((*), (int))) 0; - getpos_getvalid = (boolean FDECL((*), (int,int))) 0; + getpos_getvalid = (boolean FDECL((*), (int, int))) 0; return result; } From 7a3ff2be546d9216baf8627fc11ea215931ff5cc Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 23 Feb 2018 07:25:37 -0800 Subject: [PATCH 04/57] fix "wonky secret door" in Cav quest The earlier fix for hoizontal vs vertical doors would have worked for the Cav quest (lower left in leader's chamber) where door handling occurs before wallification, but it wasn't working for minend-3 (east wall of entry room) which already had walls. The more recent fix solved the second case but broke the first one. I think this actually solves both modes of door classification. I hope.... --- doc/fixes36.1 | 3 +++ src/sp_lev.c | 42 ++++++++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 69b57c25f..bc886b713 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -576,6 +576,9 @@ try again to fix achievement recording bug with mines and sokoban prizes the fix for secret doors on special levels always having vertical orientation resulted in some--but not all--secret doors within vertical walls being displayed as horizontal walls while still hidden +and the previous fix for the for secret doors didn't work if the level hadn't + been wallified yet (Cav quest) so horizontal wall with secret door + mis-displayed as a vertical wall segment could occur the fix intended for "a shop object stolen from outside the shop (via grappling hook) would be left marked as 'unpaid'" broke normal pickup, preventing any picked up item from merging with compatible stack diff --git a/src/sp_lev.c b/src/sp_lev.c index e2d362c6c..5140dd2da 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 sp_lev.c $NHDT-Date: 1514769572 2018/01/01 01:19:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.95 $ */ +/* NetHack 3.6 sp_lev.c $NHDT-Date: 1519399521 2018/02/23 15:25:21 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.96 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -4207,7 +4207,7 @@ genericptr_t arg; { xchar typ = *(xchar *) arg; xchar x = dx, y = dy; - boolean left_or_right, up_and_down; + boolean wleft, wright, wup, wdown; if (!IS_DOOR(levl[x][y].typ) && levl[x][y].typ != SDOOR) levl[x][y].typ = (typ & D_SECRET) ? SDOOR : DOOR; @@ -4231,21 +4231,31 @@ genericptr_t arg; * * A secret door with no adjacent walls is also feasible and makes * even less sense. It will be displayed as a vertical wall while - * hidden and become a vertical door when found. + * hidden and become a vertical door when found. Before resorting + * to that, we check for solid rock which hasn't been wallified + * yet (cf lower leftside of leader's room in Cav quest). */ - left_or_right = ((isok(x - 1, y) && (IS_WALL(levl[x - 1][y].typ) - || IS_DOOR(levl[x - 1][y].typ) - || levl[x - 1][y].typ == SDOOR)) - || (isok(x + 1, y) && (IS_WALL(levl[x + 1][y].typ) - || IS_DOOR(levl[x + 1][y].typ) - || levl[x + 1][y].typ == SDOOR))); - up_and_down = ((isok(x, y - 1) && (IS_WALL(levl[x][y - 1].typ) - || IS_DOOR(levl[x][y - 1].typ) - || levl[x][y - 1].typ == SDOOR)) - && (isok(x, y + 1) && (IS_WALL(levl[x][y + 1].typ) - || IS_DOOR(levl[x][y + 1].typ) - || levl[x][y + 1].typ == SDOOR))); - levl[x][y].horizontal = (left_or_right && !up_and_down) ? 1 : 0; + wleft = (isok(x - 1, y) && (IS_WALL(levl[x - 1][y].typ) + || IS_DOOR(levl[x - 1][y].typ) + || levl[x - 1][y].typ == SDOOR)); + wright = (isok(x + 1, y) && (IS_WALL(levl[x + 1][y].typ) + || IS_DOOR(levl[x + 1][y].typ) + || levl[x + 1][y].typ == SDOOR)); + wup = (isok(x, y - 1) && (IS_WALL(levl[x][y - 1].typ) + || IS_DOOR(levl[x][y - 1].typ) + || levl[x][y - 1].typ == SDOOR)); + wdown = (isok(x, y + 1) && (IS_WALL(levl[x][y + 1].typ) + || IS_DOOR(levl[x][y + 1].typ) + || levl[x][y + 1].typ == SDOOR)); + if (!wleft && !wright && !wup && !wdown) { + /* out of bounds is treated as implicit wall; should be academic + because we don't expect to have doors so near the level's edge */ + wleft = (!isok(x - 1, y) || IS_DOORJOIN(levl[x - 1][y].typ)); + wright = (!isok(x + 1, y) || IS_DOORJOIN(levl[x + 1][y].typ)); + wup = (!isok(x, y - 1) || IS_DOORJOIN(levl[x][y - 1].typ)); + wdown = (!isok(x, y + 1) || IS_DOORJOIN(levl[x][y + 1].typ)); + } + levl[x][y].horizontal = ((wleft || wright) && !(wup && wdown)) ? 1 : 0; levl[x][y].doormask = typ; SpLev_Map[x][y] = 1; } From 5dd6c05322c9ce435f417bc070b73071b78e5fcc Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 23 Feb 2018 13:07:49 -0800 Subject: [PATCH 05/57] switch docall() to safe_qbuf() Simplify docall() for object types. Adds some different complexity to a new routine so the overall simplification is rather minimal, but we already have a routine to construct prompt buffers involving formatted object names without allowing overflow, so use it. tty getlin() limits the input to COLNO characters, so 80 by default. To get potential QBUFSZ overflow, I had to increase COLNO in global.h and rebuild from scratch. A value greater than 127 triggers a lot of warnings. I didn't try 127. 126 gets one warning, involving use of FARAWAY (defined as COLNO+2) in dogmove.c. We should change things to limit object names to much less than 80, but this doesn't attempt to implement that. --- src/do_name.c | 60 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/src/do_name.c b/src/do_name.c index 7aceca6e1..ae57474f9 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_name.c $NHDT-Date: 1519281849 2018/02/22 06:44:09 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.127 $ */ +/* NetHack 3.6 do_name.c $NHDT-Date: 1519420054 2018/02/23 21:07:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.128 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -14,6 +14,7 @@ STATIC_DCL void FDECL(auto_describe, (int, int)); STATIC_DCL void NDECL(do_mname); STATIC_DCL boolean FDECL(alreadynamed, (struct monst *, char *, char *)); STATIC_DCL void FDECL(do_oname, (struct obj *)); +STATIC_PTR char *FDECL(docall_xname, (struct obj *)); STATIC_DCL void NDECL(namefloorobj); STATIC_DCL char *FDECL(bogusmon, (char *,char *)); @@ -1405,33 +1406,56 @@ docallcmd() return 0; } +/* for use by safe_qbuf() */ +STATIC_PTR char * +docall_xname(obj) +struct obj *obj; +{ + struct obj otemp; + + otemp = *obj; + otemp.oextra = (struct oextra *) 0; + otemp.quan = 1L; + /* in case water is already known, convert "[un]holy water" to "water" */ + otemp.blessed = otemp.cursed = 0; + /* remove attributes that are doname() caliber but get formatted + by xname(); most of these fixups aren't really needed because the + relevant type of object isn't callable so won't reach this far */ + if (otemp.oclass == WEAPON_CLASS) + otemp.opoisoned = 0; /* not poisoned */ + else if (otemp.oclass == POTION_CLASS) + otemp.odiluted = 0; /* not diluted */ + else if (otemp.otyp == TOWEL || otemp.otyp == STATUE) + otemp.spe = 0; /* not wet or historic */ + else if (otemp.otyp == TIN) + otemp.known = 0; /* suppress tin type (homemade, &c) and mon type */ + else if (otemp.otyp == FIGURINE) + otemp.corpsenm = NON_PM; /* suppress mon type */ + else if (otemp.otyp == HEAVY_IRON_BALL) + otemp.owt = objects[HEAVY_IRON_BALL].oc_weight; /* not "very heavy" */ + else if (otemp.oclass == FOOD_CLASS && otemp.globby) + otemp.owt = 120; /* 6*20, neither a small glob nor a large one */ + + return an(xname(&otemp)); +} + void docall(obj) -register struct obj *obj; +struct obj *obj; { char buf[BUFSZ], qbuf[QBUFSZ]; - struct obj otemp; - register char **str1; + char **str1; if (!obj->dknown) return; /* probably blind */ - otemp = *obj; - otemp.quan = 1L; - otemp.oextra = (struct oextra *) 0; - if (objects[otemp.otyp].oc_class == POTION_CLASS && otemp.fromsink) { + if (obj->oclass == POTION_CLASS && obj->fromsink) /* kludge, meaning it's sink water */ Sprintf(qbuf, "Call a stream of %s fluid:", - OBJ_DESCR(objects[otemp.otyp])); - } else { - char tmpbuf[BUFSZ], *tmpname = an(xname(&otemp)); - - if (strlen(tmpname) < (BUFSZ - 1)) { - Strcpy(tmpbuf, tmpname); - tmpbuf[QBUFSZ - 7] = '\0'; /* need room for "Call :"*/ - Sprintf(qbuf, "Call %s:", tmpbuf); - } - } + OBJ_DESCR(objects[obj->otyp])); + else + (void) safe_qbuf(qbuf, "Call ", ":", obj, + docall_xname, simpleonames, "thing"); getlin(qbuf, buf); if (!*buf || *buf == '\033') return; From 65655d2ceefa2eb7099b05c5034d72044b9b1176 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 28 Jan 2018 22:54:08 -0500 Subject: [PATCH 06/57] Incorporate some git information into NetHack Incorporate some git information into NetHack so that it is potentially visible to a player. That's useful when collecting details about the version that they are running and, if the gitinfo is present, it can tie the code to a specific git commit in the repository. This modifies 'makedefs -v' to check for the presence of a data file called dat/gitinfo.txt and if it is there, parse out its contents, then write additional lines to include/date.h beyond what 'makedefs -v' was previously putting in there, similar to this sample: #define NETHACK_GIT_SHA "0c84e564c78e2024e562d39539376ce2e21eec8e" #define NETHACK_GIT_BRANCH "NetHack-3.6.0" The contents of an appropriate dat/gitinfo.txt are as follows, and trailing/leading whitespace is not significant: githash = 0c84e564c78e2024e562d39539376ce2e21eec8e gitbranch = NetHack-3.6.0 It also adjusts the contents of the 'v' version information to include the additional git info when available. Also adds some hooks DEVEL/hooksdir and a perl file to DEVEL for simplifying and automating the deposit of dat/gitinfo.txt so that it generally reflects the most current git commit. DEVEL/gitinfo.pl can be used to build dat/gitinfo.txt at any time without doing a commit, merge, or checkout. perl DEVEL/gitinfo.pl command line --version and -version support To complement the extra information being provided in the version by the 'v' command, this also adds support for the following new command line arguments: --version -version Output the NetHack version string then exit. --version:paste Output the NetHack version string and also copy it to -version:paste the platform's paste buffer for insertion somewhere, then exit. If the paste variation of -version is requested on a platform that hasn't incorporated any support for the capability, it will deliver the version info then an error message, prior to exiting. To support the extended -version:paste variation, a port needs to: - provide a port-specific routine to perform the paste buffer copy in a port code file. - #define RUNTIME_PASTEBUF_SUPPORT in the include/portconf.h header file. --skeleton-- void port_insert_pastebuf(buf) char *buf; { /* insert code to copy the version info from buf into platform's paste buffer in a supported way */ } macosx and Windows have both added support for RUNTIME_PASTEBUF_SUPPORT --- DEVEL/gitinfo.pl | 26 ++++++++ DEVEL/hooksdir/NHgithook.pm | 30 +++++++++ DEVEL/hooksdir/post-checkout | 1 + DEVEL/hooksdir/post-commit | 1 + DEVEL/hooksdir/post-merge | 2 + doc/makedefs.6 | 8 +++ doc/nethack.6 | 14 +++++ include/decl.h | 9 +++ include/extern.h | 5 ++ include/ntconf.h | 11 ++-- include/unixconf.h | 4 ++ src/allmain.c | 82 +++++++++++++++++++++++++ src/version.c | 57 +++++++++++++++-- sys/share/pcmain.c | 3 + sys/unix/unixmain.c | 39 ++++++++++++ sys/winnt/winnt.c | 116 +++++++++++++++++++++++++++++++++++ util/makedefs.c | 86 ++++++++++++++++++++++++++ 17 files changed, 485 insertions(+), 9 deletions(-) create mode 100644 DEVEL/gitinfo.pl diff --git a/DEVEL/gitinfo.pl b/DEVEL/gitinfo.pl new file mode 100644 index 000000000..b62428975 --- /dev/null +++ b/DEVEL/gitinfo.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; + +&NHgithook::nhversioning; diff --git a/DEVEL/hooksdir/NHgithook.pm b/DEVEL/hooksdir/NHgithook.pm index 6024c1c03..1bb92cf7e 100644 --- a/DEVEL/hooksdir/NHgithook.pm +++ b/DEVEL/hooksdir/NHgithook.pm @@ -60,6 +60,36 @@ sub POST { &do_hook("POST"); } +### +### store githash and gitbranch in dat/gitinfo.txt +### + +sub nhversioning { + use strict; + use warnings; + + my $git_sha = `git rev-parse HEAD`; + $git_sha =~ s/\s+//g; + my $git_branch = `git rev-parse --abbrev-ref HEAD`; + $git_branch =~ s/\s+//g; + + if (open my $fh, '<', 'dat/gitinfo.txt') { + while(my $line = <$fh>) { + if ((index $line, $git_sha) >= 0) { + close $fh; + print "No update made to dat/gitinfo.txt, existing githash=".$git_sha."\n"; + return; + } + } + close $fh; + } + if (open my $fh, '>', 'dat/gitinfo.txt') { + print $fh 'githash='.$git_sha."\n"; + print $fh 'gitbranch='.$git_branch."\n"; + print "An updated dat/gitinfo.txt was written, githash=".$git_sha."\n"; + } +} + # PRIVATE sub do_hook { my($p) = @_; diff --git a/DEVEL/hooksdir/post-checkout b/DEVEL/hooksdir/post-checkout index b5bf990fe..2df107a2f 100755 --- a/DEVEL/hooksdir/post-checkout +++ b/DEVEL/hooksdir/post-checkout @@ -26,5 +26,6 @@ use NHgithook; #STARTUP-END &NHgithook::PRE; +&NHgithook::nhversioning; &NHgithook::POST; exit 0; diff --git a/DEVEL/hooksdir/post-commit b/DEVEL/hooksdir/post-commit index b5bf990fe..2df107a2f 100755 --- a/DEVEL/hooksdir/post-commit +++ b/DEVEL/hooksdir/post-commit @@ -26,5 +26,6 @@ use NHgithook; #STARTUP-END &NHgithook::PRE; +&NHgithook::nhversioning; &NHgithook::POST; exit 0; diff --git a/DEVEL/hooksdir/post-merge b/DEVEL/hooksdir/post-merge index b5bf990fe..2dc7f3628 100755 --- a/DEVEL/hooksdir/post-merge +++ b/DEVEL/hooksdir/post-merge @@ -22,9 +22,11 @@ BEGIN { chomp $gitdir; push(@INC, $gitdir.$PDS."hooks"); } + use NHgithook; #STARTUP-END &NHgithook::PRE; +&NHgithook::nhversioning; &NHgithook::POST; exit 0; diff --git a/doc/makedefs.6 b/doc/makedefs.6 index 7b55de3e4..29d4899be 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -85,6 +85,14 @@ Generate .I date.h and .I options +file. It will read +.I dat/gitinfo.txt +,only if it is present, to obtain +.B githash= +and +.B gitbranch= + info and include related preprocessor #defines in +.I date.h file. .br .TP diff --git a/doc/nethack.6 b/doc/nethack.6 index 3803ae583..6b38a68ba 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -55,6 +55,9 @@ nethack \- Exploring The Mazes of Menace [ .I playernames ] +[ +.B \-\-version +] .ad .hy 14 .\" Make sure path is not hyphenated below @@ -207,6 +210,17 @@ The playground must contain several auxiliary files such as help files, the list of top scorers, and a subdirectory .I save where games are saved. +.PP +.B \-\-version +can be used to cause NetHack to show the version information it +was compiled with, then exit. That will include the +.I git +commit hash if the information was available when the game was compiled. +On some platforms, such as windows and macosx, a variation +.B \-\-version:paste +can be used to cause NetHack to show the version information, then exit, +while also leaving a copy of the version information in the paste buffer +or clipboard for potential insertion into things like bug reports. .SH AUTHORS .PP Jay Fenlason (+ Kenny Woodland, Mike Thome and Jon Payne) wrote the diff --git a/include/decl.h b/include/decl.h index f6d5764cb..bf99227f9 100644 --- a/include/decl.h +++ b/include/decl.h @@ -422,6 +422,15 @@ E struct plinemsg_type *plinemsg_types; E const char *ARGV0; #endif +enum earlyarg {ARG_DEBUG, ARG_VERSION}; + +struct early_opt { + enum earlyarg e; + const char *name; + int minlength; + boolean valallowed; +}; + #undef E #endif /* DECL_H */ diff --git a/include/extern.h b/include/extern.h index 24a0c06cd..4ea4915c4 100644 --- a/include/extern.h +++ b/include/extern.h @@ -26,6 +26,7 @@ E void NDECL(display_gamewindows); E void NDECL(newgame); E void FDECL(welcome, (BOOLEAN_P)); E time_t NDECL(get_realtime); +E boolean FDECL(argcheck, (int, char **, enum earlyarg)); /* ### apply.c ### */ @@ -2567,10 +2568,14 @@ E void FDECL(store_version, (int)); E unsigned long FDECL(get_feature_notice_ver, (char *)); E unsigned long NDECL(get_current_feature_ver); E const char *FDECL(copyright_banner_line, (int)); +E void FDECL(early_version_info, (BOOLEAN_P)); #ifdef RUNTIME_PORT_ID E char *FDECL(get_port_id, (char *)); #endif +#ifdef RUNTIME_PASTEBUF_SUPPORT +E void FDECL(port_insert_pastebuf, (char *)); +#endif /* ### video.c ### */ diff --git a/include/ntconf.h b/include/ntconf.h index a096a2ff1..534fa6e5d 100644 --- a/include/ntconf.h +++ b/include/ntconf.h @@ -69,6 +69,12 @@ #define PORT_DEBUG /* include ability to debug international keyboard issues \ */ +#define RUNTIME_PORT_ID /* trigger run-time port identification for \ + * identification of exe CPU architecture \ + */ +#define RUNTIME_PASTEBUF_SUPPORT + + #define SAFERHANGUP /* Define SAFERHANGUP to delay hangup processing \ * until the main command loop. 'safer' because it \ * avoids certain cheats and also avoids losing \ @@ -117,11 +123,6 @@ extern void FDECL(interject, (int)); #endif #endif /* _MSC_VER */ - -#define RUNTIME_PORT_ID /* trigger run-time port identification for \ - * identification of exe CPU architecture \ - */ - /* The following is needed for prototypes of certain functions */ #if defined(_MSC_VER) #include /* Provides prototypes of exit(), spawn() */ diff --git a/include/unixconf.h b/include/unixconf.h index 0d4fbce17..88e309d55 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -387,5 +387,9 @@ #endif /* LINUX */ #endif /* GNOME_GRAPHICS */ +#ifdef __APPLE__ +# define RUNTIME_PASTEBUF_SUPPORT +#endif + #endif /* UNIXCONF_H */ #endif /* UNIX */ diff --git a/src/allmain.c b/src/allmain.c index 4a0cfaf8f..789c5d48f 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -737,5 +737,87 @@ const char *msg; } } +/* + * Argument processing helpers - for xxmain() to share + * and call. + * + * These should return TRUE if the argument matched, + * whether the processing of the argument was + * successful or not. + * + * Most of these do their thing, then after returning + * to xxmain(), the code exits without starting a game. + * + */ + +static struct early_opt earlyopts[] = { + {ARG_DEBUG, "debug", 5, FALSE}, + {ARG_VERSION, "version", 4, TRUE}, +}; + +boolean +argcheck(argc, argv, e_arg) +int argc; +char *argv[]; +enum earlyarg e_arg; +{ + int i, idx; + boolean match = FALSE; + char *userea = (char *)0, *dashdash = ""; + + for (idx = 0; idx < SIZE(earlyopts); idx++) { + if (earlyopts[idx].e == e_arg) + break; + } + if ((idx >= SIZE(earlyopts)) || (argc <= 1)) + return FALSE; + + for (i = 1; i < argc; ++i) { + if (argv[i][0] != '-') + continue; + if (argv[i][1] == '-') { + userea = &argv[i][2]; + dashdash = "-"; + } else { + userea = &argv[i][1]; + } + match = match_optname(userea, earlyopts[idx].name, + earlyopts[idx].minlength, earlyopts[idx].valallowed); + if (match) break; + } + + if (match) { + switch(e_arg) { + case ARG_DEBUG: + break; + case ARG_VERSION: { + boolean insert_into_pastebuf = FALSE; + const char *extended_opt = index(userea,':'); + + if (!extended_opt) + extended_opt = index(userea, '='); + + if (extended_opt) { + extended_opt++; + if (match_optname(extended_opt, "paste", + 5, FALSE)) { + insert_into_pastebuf = TRUE; + } else { + raw_printf( + "-%sversion can only be extended with -%sversion:paste.\n", + dashdash, dashdash); + return TRUE; + } + } + early_version_info(insert_into_pastebuf); + return TRUE; + break; + } + default: + break; + } + }; + return FALSE; +} /*allmain.c*/ diff --git a/src/version.c b/src/version.c index 19f74c265..514665663 100644 --- a/src/version.c +++ b/src/version.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 version.c $NHDT-Date: 1506993902 2017/10/03 01:25:02 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.44 $ */ +/* NetHack 3.6 version.c $NHDT-Date: 1517140532 2018/01/28 11:55:32 $ $NHDT-Branch: nhmall-githash3 $:$NHDT-Revision: 1.50 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -15,6 +15,13 @@ #include "patchlevel.h" #endif +#if defined(NETHACK_GIT_SHA) +const char * NetHack_git_sha = NETHACK_GIT_SHA; +#endif +#if defined(NETHACK_GIT_BRANCH) +const char * NetHack_git_branch = NETHACK_GIT_BRANCH; +#endif + STATIC_DCL void FDECL(insert_rtoption, (char *)); /* fill buffer with short version (so caller can avoid including date.h) */ @@ -30,23 +37,34 @@ char * getversionstring(buf) char *buf; { - int details = 0; + boolean details = FALSE; Strcpy(buf, VERSION_ID); -#if defined(RUNTIME_PORT_ID) - details++; +#if defined(RUNTIME_PORT_ID) || \ + defined(NETHACK_GIT_SHA) || defined(NETHACK_GIT_BRANCH) + details = TRUE; #endif if (details) { int c = 0; +#if defined(RUNTIME_PORT_ID) char tmpbuf[BUFSZ]; char *tmp = (char *)0; +#endif Sprintf(eos(buf), " ("); #if defined(RUNTIME_PORT_ID) tmp = get_port_id(tmpbuf); if (tmp) Sprintf(eos(buf), "%s%s", c++ ? "," : "", tmp); +#endif +#if defined(NETHACK_GIT_SHA) + if (NetHack_git_sha) + Sprintf(eos(buf), "%s%s", c++ ? "," : "", NetHack_git_sha); +#endif +#if defined(NETHACK_GIT_BRANCH) + if (NetHack_git_branch) + Sprintf(eos(buf), "%s%s", c++ ? "," : "", NetHack_git_branch); #endif Sprintf(eos(buf), ")"); } @@ -130,6 +148,37 @@ doextversion() return 0; } +void early_version_info(pastebuf) +boolean pastebuf; +{ + char buf[BUFSZ], buf2[BUFSZ]; + char *tmp = getversionstring(buf); + + /* this is early enough that we have to do + our own line-splitting */ + if (tmp) { + tmp = strstri(buf," ("); + if (tmp) *tmp++ = '\0'; + } + + Sprintf(buf2, "%s\n", buf); + if (tmp) Sprintf(eos(buf2), "%s\n", tmp); + raw_printf("%s", buf2); + + if (pastebuf) { +#ifdef RUNTIME_PASTEBUF_SUPPORT + /* + * Call a platform/port-specific routine to insert the + * version information into a paste buffer. Useful for + * easy inclusion in bug reports. + */ + port_insert_pastebuf(buf2); +#else + raw_printf("%s", "Paste buffer copy is not available.\n"); +#endif + } +} + extern const char regex_id[]; /* diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index a18157639..64a175c14 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -329,6 +329,9 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ Strcpy(hackdir, HACKDIR); #endif if (argc > 1) { + if (argcheck(argc, argv, ARG_VERSION)) + nethack_exit(EXIT_SUCCESS); + if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') { /* avoid matching "-dec" for DECgraphics; since the man page * says -d directory, hope nobody's using -desomething_else diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index b9ab44526..95e48cc14 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -110,6 +110,9 @@ char *argv[]; dir = nh_getenv("HACKDIR"); if (argc > 1) { + if (argcheck(argc, argv, ARG_VERSION)) + exit(EXIT_SUCCESS); + if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') { /* avoid matching "-dec" for DECgraphics; since the man page * says -d directory, hope nobody's using -desomething_else @@ -720,4 +723,40 @@ get_login_name() return buf; } +#ifdef __APPLE__ +extern int errno; + +void +port_insert_pastebuf(buf) +char *buf; +{ + /* This should be replaced when there is a Cocoa port. */ + const char *errfmt; + size_t len; + FILE *PB = popen("/usr/bin/pbcopy","w"); + if(!PB){ + errfmt = "Unable to start pbcopy (%d)\n"; + goto error; + } + + len = strlen(buf); + /* Remove the trailing \n, carefully. */ + if(buf[len-1] == '\n') len--; + + /* XXX Sorry, I'm too lazy to write a loop for output this short. */ + if(len!=fwrite(buf,1,len,PB)){ + errfmt = "Error sending data to pbcopy (%d)\n"; + goto error; + } + + if(pclose(PB)!=-1){ + return; + } + errfmt = "Error finishing pbcopy (%d)\n"; + +error: + raw_printf(errfmt,strerror(errno)); +} +#endif + /*unixmain.c*/ diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index 842bfd036..cfd27acac 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -35,6 +35,9 @@ /* globals required within here */ HANDLE ffhandle = (HANDLE) 0; WIN32_FIND_DATA ffd; +typedef HWND(WINAPI *GETCONSOLEWINDOW)(); +static HWND GetConsoleHandle(void); +static HWND GetConsoleHwnd(void); /* The function pointer nt_kbhit contains a kbhit() equivalent * which varies depending on which window port is active. @@ -316,6 +319,119 @@ int interjection_type; msmsg(interjection_buf[interjection_type]); } +#ifdef RUNTIME_PASTEBUF_SUPPORT + +void port_insert_pastebuf(buf) +char *buf; +{ + /* This implementation will utilize the windows clipboard + * to accomplish this. + */ + + char *tmp = buf; + HWND hwndConsole = GetConsoleHandle(); + HGLOBAL hglbCopy; + WCHAR *w, w2[2]; + int cc, rc, abytes; + LPWSTR lpwstrCopy; + HANDLE hresult; + + if (!buf || (hwndConsole == NULL)) + return; + + cc = strlen(buf); + /* last arg=0 means "tell me the size of the buffer that I need" */ + rc = MultiByteToWideChar(GetConsoleOutputCP(), 0, buf, -1, w2, 0); + if (!rc) return; + + abytes = rc * sizeof(WCHAR); + w = (WCHAR *)alloc(abytes); + /* Housekeeping need: +free(w) */ + + rc = MultiByteToWideChar(GetConsoleOutputCP(), 0, buf, -1, w, rc); + if (!rc) { + free(w); + return; + } + if (!OpenClipboard(hwndConsole)) { + free(w); + return; + } + /* Housekeeping need: +CloseClipboard(), free(w) */ + + EmptyClipboard(); + + /* allocate global mem obj to hold the text */ + + hglbCopy = GlobalAlloc(GMEM_MOVEABLE, abytes); + if (hglbCopy == NULL) { + CloseClipboard(); + free(w); + return; + } + /* Housekeeping need: +GlobalFree(hglbCopy), CloseClipboard(), free(w) */ + + lpwstrCopy = (LPWSTR)GlobalLock(hglbCopy); + /* Housekeeping need: +GlobalUnlock(hglbCopy), GlobalFree(hglbCopy), + CloseClipboard(), free(w) */ + + memcpy(lpwstrCopy, w, abytes); + GlobalUnlock(hglbCopy); + /* Housekeeping need: GlobalFree(hglbCopy), CloseClipboard(), free(w) */ + + /* put it on the clipboard */ + hresult = SetClipboardData(CF_UNICODETEXT, hglbCopy); + if (!hresult) { + raw_printf("Error copying to clipboard.\n"); + GlobalFree(hglbCopy); /* only needed if clipboard didn't accept data */ + } + /* Housekeeping need: CloseClipboard(), free(w) */ + + CloseClipboard(); + free(w); + return; +} + +static HWND +GetConsoleHandle(void) +{ + HMODULE hMod = GetModuleHandle("kernel32.dll"); + GETCONSOLEWINDOW pfnGetConsoleWindow = + (GETCONSOLEWINDOW) GetProcAddress(hMod, "GetConsoleWindow"); + if (pfnGetConsoleWindow) + return pfnGetConsoleWindow(); + else + return GetConsoleHwnd(); +} + +static HWND +GetConsoleHwnd(void) +{ + int iterations = 0; + HWND hwndFound = 0; + char OldTitle[1024], NewTitle[1024], TestTitle[1024]; + + /* Get current window title */ + GetConsoleTitle(OldTitle, sizeof OldTitle); + + (void) sprintf(NewTitle, "NETHACK%d/%d", GetTickCount(), + GetCurrentProcessId()); + SetConsoleTitle(NewTitle); + + GetConsoleTitle(TestTitle, sizeof TestTitle); + while (strcmp(TestTitle, NewTitle) != 0) { + iterations++; + /* sleep(0); */ + GetConsoleTitle(TestTitle, sizeof TestTitle); + } + hwndFound = FindWindow(NULL, NewTitle); + SetConsoleTitle(OldTitle); + /* printf("%d iterations\n", iterations); */ + return hwndFound; +} + +#endif + #ifdef RUNTIME_PORT_ID /* * _M_IX86 is Defined for x86 processors. This is not defined for x64 diff --git a/util/makedefs.c b/util/makedefs.c index f3f7135be..2726816e8 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -72,6 +72,7 @@ static const char SCCS_Id[] = "@(#)makedefs.c\t3.6\t2016/02/12"; #define QTXT_O_FILE "quest.dat" #define VIS_TAB_H "vis_tab.h" #define VIS_TAB_C "vis_tab.c" +#define GITINFO_FILE "gitinfo.txt" /* locations for those files */ #ifdef AMIGA #define FILE_PREFIX @@ -177,6 +178,7 @@ static char *FDECL(bannerc_string, (char *, const char *)); static char *FDECL(xcrypt, (const char *)); static unsigned long FDECL(read_rumors_file, (const char *, int *, long *, unsigned long)); +static boolean FDECL(get_gitinfo, (char *, char *)); static void FDECL(do_rnd_access_file, (const char *)); static boolean FDECL(d_filter, (char *)); static boolean FDECL(h_filter, (char *)); @@ -209,6 +211,7 @@ static char *FDECL(fgetline, (FILE*)); static char *FDECL(tmpdup, (const char *)); static char *FDECL(limit, (char *, int)); static char *FDECL(eos, (char *)); +static int FDECL(case_insensitive_comp, (const char *, const char *)); /* input, output, tmp */ static FILE *ifp, *ofp, *tfp; @@ -1239,6 +1242,7 @@ do_date() #else time_t clocktim = 0; #endif + char githash[BUFSZ], gitbranch[BUFSZ]; char *c, cbuf[60], buf[BUFSZ]; const char *ul_sfx; @@ -1372,6 +1376,10 @@ do_date() Fprintf(ofp, "#define COPYRIGHT_BANNER_C \\\n \"%s\"\n", bannerc_string(buf, cbuf)); Fprintf(ofp, "\n"); + if (get_gitinfo(githash, gitbranch)) { + Fprintf(ofp, "#define NETHACK_GIT_SHA \"%s\"\n", githash); + Fprintf(ofp, "#define NETHACK_GIT_BRANCH \"%s\"\n", gitbranch); + } #ifdef AMIGA { struct tm *tm = localtime((time_t *) &clocktim); @@ -1386,6 +1394,84 @@ do_date() return; } +boolean +get_gitinfo(githash, gitbranch) +char *githash, *gitbranch; +{ + FILE *gifp; + size_t len; + char infile[600]; + char *line, *strval, *opt, *c, *end; + boolean havebranch = FALSE, havehash = FALSE; + + if (!githash || !gitbranch) return FALSE; + + Sprintf(infile, DATA_IN_TEMPLATE, GITINFO_FILE); + if (!(gifp = fopen(infile, RDTMODE))) { + /* perror(infile); */ + return FALSE; + } + + /* read the gitinfo file */ + while ((line = fgetline(gifp)) != 0) { + strval = index(line, '='); + if (strval && strlen(strval) < (BUFSZ-1)) { + opt = line; + *strval++ = '\0'; + /* strip off the '\n' */ + if ((c = index(strval, '\n')) != 0) + *c = '\0'; + if ((c = index(opt, '\n')) != 0) + *c = '\0'; + /* strip leading and trailing white space */ + while (*strval == ' ' || *strval == '\t') + strval++; + end = eos(strval); + while (--end >= strval && (*end == ' ' || *end == '\t')) + *end = '\0'; + while (*opt == ' ' || *opt == '\t') + opt++; + end = eos(opt); + while (--end >= opt && (*end == ' ' || *end == '\t')) + *end = '\0'; + + len = strlen(opt); + if ((len >= strlen("gitbranch")) && !case_insensitive_comp(opt, "gitbranch")) { + Strcpy(gitbranch, strval); + havebranch = TRUE; + } + if ((len >= strlen("githash")) && !case_insensitive_comp(opt, "githash")) { + Strcpy(githash, strval); + havehash = TRUE; + } + } + } + Fclose(gifp); + if (havebranch && havehash) + return TRUE; + return FALSE; +} + +static int +case_insensitive_comp(s1, s2) +const char *s1; +const char *s2; +{ + uchar u1, u2; + + for (;; s1++, s2++) { + u1 = (uchar) *s1; + if (isupper(u1)) + u1 = tolower(u1); + u2 = (uchar) *s2; + if (isupper(u2)) + u2 = tolower(u2); + if (u1 == '\0' || u1 != u2) + break; + } + return u1 - u2; +} + static char save_bones_compat_buf[BUFSZ]; static void From cf9cf038f3fdefc4dc54a27c189dd46d47b82dd7 Mon Sep 17 00:00:00 2001 From: keni Date: Fri, 9 Feb 2018 11:48:04 -0500 Subject: [PATCH 07/57] gitinfo.pl: special case code to allow running it from $TOP or DEVEL without installing the hooks first NHgithook.pm: add some warnings if nhversioning can't open files make sure nhversioning fails before opening gitinfo.txt if it can't get valid data --- DEVEL/gitinfo.pl | 7 +++++++ DEVEL/hooksdir/.NHgithook.pm.swp | Bin 16384 -> 0 bytes DEVEL/hooksdir/NHgithook.pm | 7 ++++++- src/allmain.c | 5 +++-- src/version.c | 4 +++- sys/unix/hints/macosx.sh | 2 +- 6 files changed, 20 insertions(+), 5 deletions(-) delete mode 100644 DEVEL/hooksdir/.NHgithook.pm.swp diff --git a/DEVEL/gitinfo.pl b/DEVEL/gitinfo.pl index b62428975..d62f1a588 100644 --- a/DEVEL/gitinfo.pl +++ b/DEVEL/gitinfo.pl @@ -20,6 +20,13 @@ BEGIN { $gitdir = `git rev-parse --git-dir`; chomp $gitdir; push(@INC, $gitdir.$PDS."hooks"); + + # special case for this script only: allow + # it to run from DEVEL or $TOP + if (-f "hooksdir/NHgithook.pm" || -f "DEVEL/hooksdir/NHgithook.pm"){ + push(@INC, "DEVEL/hooksdir"); + } + chdir("..") if (-f "hooksdir/NHgithook.pm"); } use NHgithook; diff --git a/DEVEL/hooksdir/.NHgithook.pm.swp b/DEVEL/hooksdir/.NHgithook.pm.swp deleted file mode 100644 index 19e7ec87309c69aa584791723a272d5c995f868d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI3{cB`b8OKjwb^2mOaeXP2XJ_v2&UBNRq+41^c4M;1Y%+9r5;BwQuAANTX6~8H zZSLGVy)Q|oX<8Hop&+!yUlawQ#g-xnidKtNfAJ5fT4@DW`hto=r63Aw_4}NA@7$Rr zr3HTxxgnpuJLf*6d)z`FEG9b9^n$R_dje<7{|_=^_pH z`BSmeepiR-jZ}eDf%m6C;5UaqeXBTe*XRgm$Yl@HM?bRk{_>_)sRF42sRF42sRF42 zsRF42sRF42{}&4QoomITsL8caZJvp)*X+4o7k$>E>$7|AM<3Hmsz9nhsz9nhsz9nh zsz9nhsz9nhsz9nhsz9p1|DXc8A;clX^%5Td;QfER|9|H;A>IPN0>1=51J8pWfbW85 zz*FEWzymIj;4HWY+zmbnJ`N6n8^K>cB*g3BHSiMnA$T4<2Ob9jxCoZP5;zVDAP?TW z753m+@EF(x7r<%o32+E}4E*~RA^rls2fhxz1ilEq03HG@&;$~E7R-V&m;qy82;2c~ z1#jGpx`U^|Q@{qxpaAmVIv~J1Hwp1C@F(yK@Kf+j5P$`6FDQbWz&|rWyaHYZKLOtW zo1g|3Koy(=WiSeE2e*KmKnC0Zu6|I6-+-Tk?}M*_$3O>M1owa=;Ck@44+!x)@MG`- z_z`#xJPsZJHEQ}p!ENB}>!Ck* z3;Y?p0bU2c1}}pr!4u%~;B#OLEQ2#35AFc}z+uxL!By~E@KsO+=fKij~jQbSY6U;UwBYB=q-W8-2- zRky12=kVnr;ucd?q&&BcgLZLM;+pAug`U&u)VZ<{tE=Ve%<8Hb9T#F(sA}LJSNef# zljcdQIXtmboydn^BR0ZOCR)R(v-sWTuilmp}u?k_z>==A*nF*+tO`ccU`^PCtrUjz;MdP0dO7r zh8(NQT@z*Wb;8B+)XdpRwLI7pBbRHI^gLQQ(rgWp*06NXOM=mwtsT`O@HdhqAJ|>l zR>=X|mC4n9>v!pQ{W&IAF~22wP(xQXNu~Cw5I04RE?l@k-Jr1{;w01@RY*Lr5~?RS=OS1IYD2SRGq8LkB!ypGnMMN$mMbj1?!ln+boUe(3YfzZe#EdV*)ow znJP;R?95T$)f;lvLz`jHXC^&;QyQzfyRJIe)Z*+iQjdhG(&oe?n32atZ!Uum{AN0? zY5P=PoSH6Emb48zH9>0b);4xm>@1vQY`N`IV5=6(vjrXzrTi71+zSuquTC3J=i z=5whxTErS`P~LM~pEhLIQw2lL!J-h%Sm=LW6qmH^(aWT99q`}FQ4~l-CA971m}I!D zJeRY5YGhp7KIt`dOLu8fRU0P9xj1#7jR&fT1}AMK^f_>2`uxlo6ev<-%g7gS%^qM> zt4}S~Y5HuXT&>eWWoAs%hzpIX;&kxbRay>Fc48unzO9<6X<8D2a72USB-0yVtZqKE zhL}8w_cd@hg!Z==o)x5Z5T_cPDg!d3$r_e}Nw+>fH$Q(L;W=xVlCoi<*0S}s93$;8 zX`fN;8_5tFpH$s!0?}r|+Nfky=iy_Egs4NnP@V2){g@S1vl&7-pjWvTYH@qF) zUhBN(1~v3vkUXJI@Tk~n*Sf^+-I;@?%iKhGg)p|8H${&G*Y5M#FNl)MGFl~yA$|5DP5Tua^pbD99P1{*Nri-R3!|Dmv6R|1{Qaw zN4B%o|B(05$ah919qXH3j-lNQ-Pe<8DzFpVB$c}-+i@MV?QmKhxO-%qE3Iu0Bx;-p zcSb%eJCYM|OJ4=U@>8Byqn@-q(>JjqMfmnQp$d~t$3gz6*HHnsJjsUDLq$E(c>>&W zO>RduueM>o?ku5&sFVG=@le9oaC|yAeL;b_wqY3}?$L_73GwFU{hVpOT%(*qAye$hd*+sW&X@ zBkyH~_IABj)$X zKAG(PCP=B(G?9xp^L(bo?hW;_Lv0et34EMs6rmSh&cF&D;X<1bY}`V~$kOKRIwD&S zbk{)cwJzKAwt8b@%GCs%)THm@m_TqC6q5L7ToOO@ZbkA&%X`__3&P5D~ zX_UUs2N_{laej_B_Qn;TpiSL1L!YjEFfh3@N{%zk+H1aAxxTc3_q@FqMyip`w#kQ^ zoQh*k3mT(?o(`H#>3S-qKPWyo?lm)dv&4y{A#uX1H#p{AgY#P|)pEVUXUetd#mWMA zAMWu-`&xwiIG_3C8+;PQU01#3D(p2|EVEUA&R#d>8~Ej;fSzMcOI}g+zdOY70N!ct Id21;C1L-bjZU6uP diff --git a/DEVEL/hooksdir/NHgithook.pm b/DEVEL/hooksdir/NHgithook.pm index 1bb92cf7e..0d586cfb7 100644 --- a/DEVEL/hooksdir/NHgithook.pm +++ b/DEVEL/hooksdir/NHgithook.pm @@ -1,7 +1,7 @@ # # NHgithook.pm # NetHack Git Hook Module -# $NHDT-Date$ +# $NHDT-Date: 1519164205 2018/02/20 22:03:25 $ package NHgithook; use Cwd; @@ -72,6 +72,7 @@ sub nhversioning { $git_sha =~ s/\s+//g; my $git_branch = `git rev-parse --abbrev-ref HEAD`; $git_branch =~ s/\s+//g; + die "git rev-parse failed" unless(length $git_sha and length $git_branch); if (open my $fh, '<', 'dat/gitinfo.txt') { while(my $line = <$fh>) { @@ -82,11 +83,15 @@ sub nhversioning { } } close $fh; + } else { + print "WARNING: Can't find dat directory\n" unless(-d "dat"); } if (open my $fh, '>', 'dat/gitinfo.txt') { print $fh 'githash='.$git_sha."\n"; print $fh 'gitbranch='.$git_branch."\n"; print "An updated dat/gitinfo.txt was written, githash=".$git_sha."\n"; + } else { + print "WARNING: Unable to open dat/gitinfo.txt: $!\n"; } } diff --git a/src/allmain.c b/src/allmain.c index 789c5d48f..eab1fce3d 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 allmain.c $NHDT-Date: 1513130016 2017/12/13 01:53:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.81 $ */ +/* NetHack 3.6 allmain.c $NHDT-Date: 1518193644 2018/02/09 16:27:24 $ $NHDT-Branch: githash $:$NHDT-Revision: 1.86 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -763,7 +763,8 @@ enum earlyarg e_arg; { int i, idx; boolean match = FALSE; - char *userea = (char *)0, *dashdash = ""; + char *userea = (char *)0; + const char *dashdash = ""; for (idx = 0; idx < SIZE(earlyopts); idx++) { if (earlyopts[idx].e == e_arg) diff --git a/src/version.c b/src/version.c index 514665663..30e4ce75f 100644 --- a/src/version.c +++ b/src/version.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 version.c $NHDT-Date: 1517140532 2018/01/28 11:55:32 $ $NHDT-Branch: nhmall-githash3 $:$NHDT-Revision: 1.50 $ */ +/* NetHack 3.6 version.c $NHDT-Date: 1519155525 2018/02/20 19:38:45 $ $NHDT-Branch: githash $:$NHDT-Revision: 1.47 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -46,7 +46,9 @@ char *buf; #endif if (details) { +#if defined(RUNTIME_PORT_ID) || defined(NETHACK_GIT_SHA) || defined(NETHACK_GIT_BRANCH) int c = 0; +#endif #if defined(RUNTIME_PORT_ID) char tmpbuf[BUFSZ]; char *tmp = (char *)0; diff --git a/sys/unix/hints/macosx.sh b/sys/unix/hints/macosx.sh index 93e28ca51..c6cf10c31 100755 --- a/sys/unix/hints/macosx.sh +++ b/sys/unix/hints/macosx.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.6 macosx.sh $NHDT-Date: 1518800856 2018/02/16 17:07:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.19 $ +# NetHack 3.6 macosx.sh $NHDT-Date: 1517231957 2018/01/29 13:19:17 $ $NHDT-Branch: githash $:$NHDT-Revision: 1.20 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # From c8196b645144fb2952a066f66b3e1c3635bfd985 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 20 Feb 2018 21:08:44 -0500 Subject: [PATCH 08/57] a documentation bit --- DEVEL/Developer.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/DEVEL/Developer.txt b/DEVEL/Developer.txt index 1316f23e0..b896e707a 100644 --- a/DEVEL/Developer.txt +++ b/DEVEL/Developer.txt @@ -25,6 +25,7 @@ CONTENTS 5. variable expansion 6. reserved names 7. nhadd/nhcommit +8. DEVEL hooks ------------------------------------------------------------------------------ 1. email Email to devteam@nethack.org will usually get a response, but it may take a @@ -212,3 +213,14 @@ D. Using your own hooks "perldoc DEVEL/hooksdir/nhsub". ------------------------------------------------------------------------------ +8. DEVEL hooks + + If you copy DEVEL/hooksdir/* into .git/hooks, you'll benefit from + having a new dat/gitinfo.txt created for several common git operations + that are likely to result in a new git sha. During the nethack build + process, makedefs will transform the values contained in + dat/gitinfo.txt into #define's in include/date.h which the NetHack + source will utilize. + +------------------------------------------------------------------------------ + From cd96394ccd447a4d58dde6e0ef6f21ec357bf1c9 Mon Sep 17 00:00:00 2001 From: keni Date: Wed, 21 Feb 2018 10:58:31 -0500 Subject: [PATCH 09/57] Update docs, man page. Add last chance attempt to build dat/gitinfo.txt --- DEVEL/Developer.txt | 29 ++++++++++++++++++----------- README | 5 ++++- doc/nethack.6 | 8 ++++---- doc/nethack.txt | 2 +- sys/unix/Makefile.src | 5 ++++- 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/DEVEL/Developer.txt b/DEVEL/Developer.txt index b896e707a..e9b943499 100644 --- a/DEVEL/Developer.txt +++ b/DEVEL/Developer.txt @@ -4,7 +4,7 @@ |___/\___|\_/\___|_\___/ .__/\___|_| |_| -$NHDT-Date: 1518800857 2018/02/16 17:07:37 $ +$NHDT-Date: 1519228647 2018/02/21 15:57:27 $ Welcome to the NetHack Infrastructure Developer's Guide. @@ -25,7 +25,7 @@ CONTENTS 5. variable expansion 6. reserved names 7. nhadd/nhcommit -8. DEVEL hooks +8. hooks ------------------------------------------------------------------------------ 1. email Email to devteam@nethack.org will usually get a response, but it may take a @@ -39,7 +39,8 @@ available can be obtained via git from either of two locations: or https://sourceforge.net/p/nethack/NetHack/ -XXX need to discuss what branches are available +Branches: +NetHack-3.6.0 The 3.6.0 release code and subsequent fixes and additions. ------------------------------------------------------------------------------ 3. bug reporting Please use the form at http://www.nethack.org/common/contact.html (or send @@ -96,7 +97,8 @@ C. Configure the repository: -v verbose -n dry run You can re-run nhgitset.pl as often as needed; occasionally we will - update it and ask you to run it again. + update it (or something it installs) and you will need to run it again + so the changes take effect. D. aliases Two aliases are installed by nhgitset.pl: nhadd @@ -213,14 +215,19 @@ D. Using your own hooks "perldoc DEVEL/hooksdir/nhsub". ------------------------------------------------------------------------------ -8. DEVEL hooks +8. hooks - If you copy DEVEL/hooksdir/* into .git/hooks, you'll benefit from - having a new dat/gitinfo.txt created for several common git operations - that are likely to result in a new git sha. During the nethack build - process, makedefs will transform the values contained in - dat/gitinfo.txt into #define's in include/date.h which the NetHack - source will utilize. + nhgitset.pl also installs hooks into .git/hooks. These hooks provide + a framework which allows local hook code to co-exist with hook code we + supply - see DEVEL/hooksdir/NHgithook.pm for details. + + We currently use the following hooks: + post-checkout + post-commit + post-merge + These are used to generate dat/gitinfo.txt which provides the data that + ends up available through the game command #version and the command line + option --version. ------------------------------------------------------------------------------ diff --git a/README b/README index 5c4117f46..c428e146d 100644 --- a/README +++ b/README @@ -122,7 +122,10 @@ Please read items (1), (2) and (3) BEFORE doing anything with your new code. If you have problems building the game, or you find bugs in it, we recommend filing a bug report from our "Contact Us" web page at: - http://www.nethack.org/ + https://www.nethack.org/common/contact.html or + http://www.nethack.org/common/contact.html +Please include the version information from #version or the command line +option --version in the apropriate field. A public repository of the latest NetHack code that we've made available can be obtained via git here: diff --git a/doc/nethack.6 b/doc/nethack.6 index 6b38a68ba..f2ef799f1 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -1,5 +1,5 @@ .TH NETHACK 6 "7 December 2015" -.\" NetHack 3.6 nethack.6 $NHDT-Date: 1449616496 2015/12/08 23:14:56 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.11 $ +.\" NetHack 3.6 nethack.6 $NHDT-Date: 1519228609 2018/02/21 15:56:49 $ $NHDT-Branch: githash $:$NHDT-Revision: 1.13 $ .SH NAME nethack \- Exploring The Mazes of Menace .SH SYNOPSIS @@ -34,6 +34,9 @@ nethack \- Exploring The Mazes of Menace [ .B \-ibm ] +[ +.BR \-\-version [ :paste ] +] .PP .B nethack [ @@ -55,9 +58,6 @@ nethack \- Exploring The Mazes of Menace [ .I playernames ] -[ -.B \-\-version -] .ad .hy 14 .\" Make sure path is not hyphenated below diff --git a/doc/nethack.txt b/doc/nethack.txt index 9e6275edf..4c9986349 100644 --- a/doc/nethack.txt +++ b/doc/nethack.txt @@ -7,7 +7,7 @@ NAME SYNOPSIS nethack [ -d directory ] [ -n ] [ -p profession ] [ -r race ] [ -[DX] ] - [ -u playername ] [ -dec ] [ -ibm ] + [ -u playername ] [ -dec ] [ -ibm ] [ --version[:paste] ] nethack [ -d directory ] -s [ -v ] [ -p profession ] [ -r race ] [ playernames ] diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 451067a93..19f41ca81 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile. -# NetHack 3.6 Makefile.src $NHDT-Date: 1459122529 2016/03/27 23:48:49 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.46 $ +# NetHack 3.6 Makefile.src $NHDT-Date: 1519228664 2018/02/21 15:57:44 $ $NHDT-Branch: githash $:$NHDT-Revision: 1.51 $ # Root of source tree: NHSROOT=.. @@ -610,6 +610,9 @@ tile.c: ../win/share/tilemap.c $(HACK_H) # hack.h depends on makedefs' output, so we know makedefs will be # up to date before being executed ../include/date.h: $(VERSOURCES) $(HACK_H) + if [[ ! -f ../dat/gitinfo.txt ]]; then \ + (cd ..;perl -IDEVEL/hooksdir -MNHgithook -e '&NHgithook::nhversioning') || true; \ + fi ../util/makedefs -v From f44ff54c7f642864e34249f08e4ec72342f22808 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 24 Feb 2018 19:35:56 -0800 Subject: [PATCH 10/57] fix #H6861 - whatis behaves weirdly with plurals Report indicated that looking up "more info?" for "kittens" would show the data.base entry for "kitten" and then when the display window was dismissed, another "--More--" prompt for a empty second display window would occur. Looking up "2 arrows" from a closely-seen object on the map behaved similarly. User correctly diagnosed that the two-pass lookup left the 'found_in_file' flag set from the first pass during the second but that just clearing that resulted in "I have no info about such things" on the second pass. The code is on the convoluted side and needed an extra flag to handle 'seen on first pass' in addition to clearing found flag after the first pass. I also added a check to skip the second display if primary and secondary keys don't match each other but both find the same entry. To test it, I tried "a +0 aklys named aclys". That found the aclys entry but failed to find "+0 aklys", so I added another change to have the key massaging remove +/-N after removing "a", "an", or "the". If "Want to see more info \"" + lookup string + "\"?" was too long, the prompt buffer passed to yn() was being left uninitialized. Also, test for too long was based on BUFSZ but yn() complains (to paniclog) if the prompt is longer than QBUFSZ. Make checkfile() construct a truncated prompt if the lookup string is too long. I untangled some spaghetti by making all the 'goto's be forward. It didn't help a lot but did simplify a few early returns by having them jump to a common exit instead of replicating the file close. --- dat/data.base | 5 ++ doc/fixes36.1 | 6 +- src/pager.c | 167 +++++++++++++++++++++++++++++++++----------------- 3 files changed, 119 insertions(+), 59 deletions(-) diff --git a/dat/data.base b/dat/data.base index ad7c61477..2cef03af0 100644 --- a/dat/data.base +++ b/dat/data.base @@ -54,10 +54,13 @@ suit or piece of armor [ When Help Collides, by J. D. Berry ] aclys aklys +thonged club A short studded or spiked club attached to a cord allowing it to be drawn back to the wielder after having been thrown. It should not be confused with the atlatl, which is a device used to throw spears for longer distances. + + (NetHack's "aklys" is just a club and won't return if thrown.) ~agate ring agate* Translucent, cryptocrystalline variety of quartz and a subvariety @@ -5053,6 +5056,8 @@ tourist Tourist, Rincewind had decided, meant "idiot". [ The Colour of Magic, by Terry Pratchett ] towel +wet towel +moist towel The Hitchhiker's Guide to the Galaxy has a few things to say on the subject of towels. A towel, it says, is about the most massively useful thing diff --git a/doc/fixes36.1 b/doc/fixes36.1 index bc886b713..479c39d54 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -509,8 +509,10 @@ the Wizard, Angels and lawful minions, the Riders, shopkeep/priest in own room are never frightened by tooled horns 'Iu' would reveal unknown container contents if carrying one unpaid item inside a hero-owned container whose contents weren't known -docall wasn't taking the space allocation needed for the object name + "Call :" - into account in the prompt string +docall for type of object could overflow its prompt buffer if there was a very + long type name previously assigned +whatis lookup for 'more info?' would behave strangely for plural names, either + entered by player or from "N foo" stacks on the map Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/src/pager.c b/src/pager.c index 5d9f4ddc1..5b57c27d4 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pager.c $NHDT-Date: 1505299155 2017/09/13 10:39:15 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.118 $ */ +/* NetHack 3.6 pager.c $NHDT-Date: 1519529752 2018/02/25 03:35:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.120 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -510,8 +510,6 @@ boolean user_typed_name, without_asking; char buf[BUFSZ], newstr[BUFSZ], givenname[BUFSZ]; char *ep, *dbase_str; unsigned long txt_offset = 0L; - int chk_skip, pass = 1; - boolean found_in_file = FALSE, skipping_entry = FALSE, yes_to_moreinfo; winid datawin = WIN_ERR; fp = dlb_fopen(DATAFILE, "r"); @@ -519,12 +517,10 @@ boolean user_typed_name, without_asking; pline("Cannot open data file!"); return; } - - /* - * If someone passed us garbage, prevent fault. - */ - if (!inp || (inp && strlen(inp) > (BUFSZ - 1))) { - pline("bad do_look buffer passed!"); + /* If someone passed us garbage, prevent fault. */ + if (!inp || strlen(inp) > (BUFSZ - 1)) { + impossible("bad do_look buffer passed (%s)!", + !inp ? "null" : "too long"); return; } @@ -538,6 +534,18 @@ boolean user_typed_name, without_asking; dbase_str = strcpy(newstr, inp); (void) lcase(dbase_str); + /* + * TODO: + * The switch from xname() to doname_vague_quan() in look_at_obj() + * had the unintendded side-effect of making names picked from + * pointing at map objects become harder to simplify for lookup. + * We should split the prefix and suffix handling used by wish + * parsing and also wizmode monster generation out into separate + * routines and use those routines here. This currently lacks + * erosion handling and probably lots of other bits and pieces + * that wishing already understands and most of this duplicates + * stuff already done for wish handling or monster generation. + */ if (!strncmp(dbase_str, "interior of ", 12)) dbase_str += 12; if (!strncmp(dbase_str, "a ", 2)) @@ -546,6 +554,15 @@ boolean user_typed_name, without_asking; dbase_str += 3; else if (!strncmp(dbase_str, "the ", 4)) dbase_str += 4; + else if (!strncmp(dbase_str, "some ", 5)) + dbase_str += 5; + else if (digit(*dbase_str)) { + /* remove count prefix ("2 ya") which can come from looking at map */ + while (digit(*dbase_str)) + ++dbase_str; + if (*dbase_str == ' ') + ++dbase_str; + } if (!strncmp(dbase_str, "tame ", 5)) dbase_str += 5; else if (!strncmp(dbase_str, "peaceful ", 9)) @@ -554,29 +571,65 @@ boolean user_typed_name, without_asking; dbase_str += 10; if (!strncmp(dbase_str, "saddled ", 8)) dbase_str += 8; + if (!strncmp(dbase_str, "blessed ", 8)) + dbase_str += 8; + else if (!strncmp(dbase_str, "uncursed ", 9)) + dbase_str += 9; + else if (!strncmp(dbase_str, "cursed ", 7)) + dbase_str += 7; + if (!strncmp(dbase_str, "empty ", 6)) + dbase_str += 6; + if (!strncmp(dbase_str, "partly used ", 12)) + dbase_str += 12; + else if (!strncmp(dbase_str, "partly eaten ", 13)) + dbase_str += 13; if (!strncmp(dbase_str, "statue of ", 10)) dbase_str[6] = '\0'; else if (!strncmp(dbase_str, "figurine of ", 12)) dbase_str[8] = '\0'; + /* remove enchantment ("+0 aklys"); [for 3.6.0 and earlier, this wasn't + needed because looking at items on the map used xname() rather than + doname() hence known enchantment was implicitly suppressed] */ + if (*dbase_str && index("+-", dbase_str[0]) && digit(dbase_str[1])) { + ++dbase_str; /* skip sign */ + while (digit(*dbase_str)) + ++dbase_str; + if (*dbase_str == ' ') + ++dbase_str; + } + /* "towel", "wet towel", and "moist towel" share one data.base entry; + for "wet towel", we keep prefix so that the prompt will ask about + "wet towel"; for "moist towel", we also want to ask about "wet towel". + (note: strncpy() only terminates output string if the specified + count is bigger than the length of the substring being copied) */ + if (!strncmp(dbase_str, "moist towel", 11)) + (void) strncpy(dbase_str += 2, "wet", 3); /* skip "mo" replace "ist" */ /* Make sure the name is non-empty. */ if (*dbase_str) { - /* adjust the input to remove "named " and convert to lower case */ - char *alt = 0; /* alternate description */ + long pass1offset = -1L; + int chk_skip, pass = 1; + boolean yes_to_moreinfo, found_in_file, pass1found_in_file, + skipping_entry; + char *ap, *alt = 0; /* alternate description */ - if ((ep = strstri(dbase_str, " named ")) != 0) + /* adjust the input to remove "named " and "called " */ + if ((ep = strstri(dbase_str, " named ")) != 0) { alt = ep + 7; - else if ((ep = strstri(dbase_str, " called ")) != 0) { - if (strlen(ep + 8) < BUFSZ - 1) { - Strcpy(givenname, ep + 8); - givenname[BUFSZ-1] = '\0'; - alt = &givenname[0]; - } - } - if (!ep) + if ((ap = strstri(dbase_str, " called ")) != 0 && ap < ep) + ep = ap; /* "named" is alt but truncate at "called" */ + } else if ((ep = strstri(dbase_str, " called ")) != 0) { + copynchars(givenname, ep + 8, BUFSZ - 1); + alt = givenname; + } else ep = strstri(dbase_str, ", "); if (ep && ep > dbase_str) *ep = '\0'; + /* remove charges or "(lit)" or wizmode "(N aum)" */ + if ((ep = strstri(dbase_str, " (")) != 0 && ep > dbase_str) + *ep = '\0'; + if (alt && (ap = strstri(alt, " (")) != 0 && ap > alt) + *ap = '\0'; /* * If the object is named, then the name is the alternate description; @@ -588,21 +641,18 @@ boolean user_typed_name, without_asking; if (!alt) alt = makesingular(dbase_str); - if (!strcmp(alt, dbase_str)) - pass = 0; - - for (; pass >= 0; pass--) { + pass1found_in_file = FALSE; + for (pass = !strcmp(alt, dbase_str) ? 0 : 1; pass >= 0; --pass) { + found_in_file = skipping_entry = FALSE; txt_offset = 0L; if (dlb_fseek(fp, txt_offset, SEEK_SET) < 0 ) { impossible("can't get to start of 'data' file"); - dlb_fclose(fp); - return; + goto checkfile_done; } /* skip first record; read second */ if (!dlb_fgets(buf, BUFSZ, fp) || !dlb_fgets(buf, BUFSZ, fp)) { impossible("can't read 'data' file"); - (void) dlb_fclose(fp); - return; + goto checkfile_done; } else if (sscanf(buf, "%8lx\n", &txt_offset) < 1 || txt_offset == 0L) goto bad_data_file; @@ -629,13 +679,15 @@ boolean user_typed_name, without_asking; continue; } else { found_in_file = TRUE; + if (pass == 1) + pass1found_in_file = TRUE; break; } } } } if (found_in_file) { - long entry_offset; + long entry_offset, fseekoffset; int entry_count; int i; @@ -644,37 +696,33 @@ boolean user_typed_name, without_asking; if (!dlb_fgets(buf, BUFSZ, fp)) goto bad_data_file; } while (!digit(*buf)); - if (sscanf(buf, "%ld,%d\n", &entry_offset, &entry_count) < 2) { - bad_data_file: - impossible("'data' file in wrong format or corrupted"); - /* window will exist if came here from below via 'goto' */ - if (datawin != WIN_ERR) - destroy_nhwindow(datawin); - (void) dlb_fclose(fp); - return; - } + if (sscanf(buf, "%ld,%d\n", &entry_offset, &entry_count) < 2) + goto bad_data_file; + fseekoffset = (long) txt_offset + entry_offset; + if (pass == 1) + pass1offset = fseekoffset; + else if (fseekoffset == pass1offset) + goto checkfile_done; yes_to_moreinfo = FALSE; if (!user_typed_name && !without_asking) { - unsigned maxt = strlen("More info about \"\"?"); char *entrytext = pass ? alt : dbase_str; - char question[BUFSZ]; + char question[QBUFSZ]; - if (strlen(entrytext) < BUFSZ - maxt) { - Strcpy(question, "More info about \""); - Strcat(question, entrytext); - Strcat(question, "\"?"); - } + Strcpy(question, "More info about \""); + /* +2 => length of "\"?" */ + copynchars(eos(question), entrytext, + (int) (sizeof question - 1 + - (strlen(question) + 2))); + Strcat(question, "\"?"); if (yn(question) == 'y') yes_to_moreinfo = TRUE; } if (user_typed_name || without_asking || yes_to_moreinfo) { - if (dlb_fseek(fp, (long) txt_offset + entry_offset, - SEEK_SET) < 0) { + if (dlb_fseek(fp, fseekoffset, SEEK_SET) < 0) { pline("? Seek error on 'data' file!"); - (void) dlb_fclose(fp); - return; + goto checkfile_done; } datawin = create_nhwindow(NHW_MENU); for (i = 0; i < entry_count; i++) { @@ -686,13 +734,21 @@ boolean user_typed_name, without_asking; putstr(datawin, 0, buf + 1); } display_nhwindow(datawin, FALSE); - destroy_nhwindow(datawin); + destroy_nhwindow(datawin), datawin = WIN_ERR; } - } else if (user_typed_name && pass == 0) + } else if (user_typed_name && pass == 0 && !pass1found_in_file) pline("I don't have any information on those things."); } } + goto checkfile_done; /* skip error feedback */ + + bad_data_file: + impossible("'data' file in wrong format or corrupted"); + checkfile_done: + if (datawin != WIN_ERR) + destroy_nhwindow(datawin); (void) dlb_fclose(fp); + return; } int @@ -1133,10 +1189,8 @@ coord *click_cc; pline("Pick an object."); ans = getpos(&cc, quick, what_is_an_unknown_object); - if (ans < 0 || cc.x < 0) { - flags.verbose = save_verbose; - return 0; /* done */ - } + if (ans < 0 || cc.x < 0) + break; /* done */ flags.verbose = FALSE; /* only print long question once */ } } @@ -1146,8 +1200,7 @@ coord *click_cc; /* Finally, print out our explanation. */ if (found) { - /* Used putmixed() because there may be an encoded glyph present - */ + /* use putmixed() because there may be an encoded glyph present */ putmixed(WIN_MESSAGE, 0, out_str); /* check the data file for information about this thing */ From 9773742e82c264b2eb148e846c1fb99d9631250e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 24 Feb 2018 23:26:25 -0500 Subject: [PATCH 11/57] fix some msdos build errors --- src/files.c | 2 +- sys/msdos/Makefile.GCC | 2 +- sys/msdos/setup.bat | 4 ++-- sys/msdos/vidvesa.c | 2 +- sys/msdos/vidvga.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/files.c b/src/files.c index 4c46d23d0..f1bb770b2 100644 --- a/src/files.c +++ b/src/files.c @@ -1977,7 +1977,7 @@ int src; set_configfile_name(fqname(backward_compat_configfile, CONFIGPREFIX, 0)); if ((fp = fopenp(configfile, "r")) != (FILE *) 0) { return fp; - } else if (strcmp(backwad_compat_configfile, configfile)) { + } else if (strcmp(backward_compat_configfile, configfile)) { set_configfile_name(backward_compat_configfile); if ((fp = fopenp(configfile, "r")) != (FILE *) 0) return fp; diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index 68265b6c2..38c71fc9b 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -336,7 +336,7 @@ VOBJ19 = $(O)trap.o $(O)u_init.o $(O)uhitm.o $(O)vault.o $(O)vision.o VOBJ20 = $(O)vis_tab.o $(O)weapon.o $(O)were.o $(O)wield.o $(O)windows.o VOBJ21 = $(O)wintty.o $(O)wizard.o $(O)worm.o $(O)worn.o $(O)write.o VOBJ22 = $(O)zap.o $(O)light.o $(O)dlb.o $(O)dig.o $(O)teleport.o -VOBJ23 = $(O)region.o $(O)sys.o $(O)pmatchre.o $(O)string.o $(O)unicode.o +VOBJ23 = $(O)region.o $(O)sys.o $(O)pmatchre.o SOBJ = $(O)msdos.o $(O)sound.o $(O)pcsys.o $(O)tty.o $(O)unix.o \ $(O)video.o $(O)vidtxt.o $(O)pckeys.o diff --git a/sys/msdos/setup.bat b/sys/msdos/setup.bat index 63e9de9d6..b2e373f7a 100755 --- a/sys/msdos/setup.bat +++ b/sys/msdos/setup.bat @@ -1,10 +1,10 @@ @echo off REM NetHack 3.6 setup.bat $NHDT-Date: 1432512792 2015/05/25 00:13:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -REM Copyright (c) NetHack PC Development Team 1990 - 2012 +REM Copyright (c) NetHack PC Development Team 1990 - 2018 REM NetHack may be freely redistributed. See license for details. echo. -echo Copyright (c) NetHack PC Development Team 1990 - 2012 +echo Copyright (c) NetHack PC Development Team 1990 - 2018 echo NetHack may be freely redistributed. See license for details. echo. REM setup batch file for msdos, see Install.dos for details. diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index 4f497ef9b..e9b7bb183 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -766,7 +766,7 @@ vesa_Init(void) * */ tile_file = iflags.wc_tile_file; - if (tile_file == NULL || tile_file == '\0') { + if (tile_file == NULL || *tile_file == '\0') { tile_file = "nhtiles.bmp"; } if (!read_tiles(tile_file, FALSE)) diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index 888010d4b..4e8a18206 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -758,7 +758,7 @@ vga_Init(void) * */ tile_file = iflags.wc_tile_file; - if (tile_file == NULL || tile_file == '\0') { + if (tile_file == NULL || *tile_file == '\0') { tile_file = "nhtiles.bmp"; } if (!read_tiles(tile_file, FALSE)) From 269363467c2cb46d415b166c8dae4f9de2c7cee8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 24 Feb 2018 23:32:54 -0500 Subject: [PATCH 12/57] another msdos bit --- sys/msdos/setup.bat | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/msdos/setup.bat b/sys/msdos/setup.bat index b2e373f7a..34e0f8133 100755 --- a/sys/msdos/setup.bat +++ b/sys/msdos/setup.bat @@ -59,6 +59,12 @@ echo "Copying ..\..\include\patchl~1.h -> ..\..\include\patchlev.h" copy ..\..\include\patchl~1.h ..\..\include\patchlev.h if exist ..\..\include\patchlev.old del /Q ..\..\include\patchlev.old ren ..\..\include\patchl~1.h patchlev.old +:long2c +echo "Copying ..\..\sys\share\pmatch~1.c -> ..\..\sys\share\pmatchre.c" +copy ..\..\sys\share\pmatch~1.c ..\..\sys\share\pmatchre.c +:long2d +echo "Copying ..\..\sys\share\posixr~1.c -> ..\..\sys\share\posixreg.c" +copy ..\..\sys\share\posixr~1.c ..\..\sys\share\posixreg.c :long2ok REM Missing guidebook is not fatal to the build process From 5370c0d337d900ea3d56bde5a263c453f74679ec Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 25 Feb 2018 12:20:50 -0500 Subject: [PATCH 13/57] resolve part of H4422 related to .exe versions I also saw that looking at the details of both windows .exes that they indicate file version 3.5.0.0. Shouldn't it be 3.6.0.0 for the NH version 3.6.0 --- sys/winnt/console.rc | 10 +++++----- win/win32/nethack.rc | 2 +- win/win32/winhack.rc | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sys/winnt/console.rc b/sys/winnt/console.rc index 20570522d..1c35e16bd 100644 --- a/sys/winnt/console.rc +++ b/sys/winnt/console.rc @@ -12,8 +12,8 @@ // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,5,0,0 - PRODUCTVERSION 3,5,0,0 + FILEVERSION 3,6,1,0 + PRODUCTVERSION 3,6,1,0 FILEFLAGSMASK 0x1fL #ifdef _DEBUG FILEFLAGS 0x9L @@ -29,13 +29,13 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "NetHack for Windows - TTY Interface\0" - VALUE "FileVersion", "3.5.0\0" + VALUE "FileVersion", "3.6.1\0" VALUE "InternalName", "NetHack\0" - VALUE "LegalCopyright", "Copyright (C) 1985 - 2005. By Stichting Mathematisch Centrum and M. Stephenson. See license for details.\0" + VALUE "LegalCopyright", "Copyright (C) 1985 - 2018. By Stichting Mathematisch Centrum and M. Stephenson. See license for details.\0" VALUE "OriginalFilename", "NetHack.exe\0" VALUE "PrivateBuild", "050102\0" VALUE "ProductName", "NetHack\0" - VALUE "ProductVersion", "3.5.0\0" + VALUE "ProductVersion", "3.6.1\0" END END BLOCK "VarFileInfo" diff --git a/win/win32/nethack.rc b/win/win32/nethack.rc index 72ce4e0df..04ff88d55 100644 --- a/win/win32/nethack.rc +++ b/win/win32/nethack.rc @@ -79,7 +79,7 @@ BEGIN VALUE "FileDescription", "NetHack for Windows - TTY Interface" VALUE "FileVersion", "3.6.1" VALUE "InternalName", "NetHack" - VALUE "LegalCopyright", "Copyright (C) 1985 - 2017. By Stichting Mathematisch Centrum and M. Stephenson. See license for details." + VALUE "LegalCopyright", "Copyright (C) 1985 - 2018. By Stichting Mathematisch Centrum and M. Stephenson. See license for details." VALUE "OriginalFilename", "NetHack.exe" VALUE "ProductName", "NetHack" VALUE "ProductVersion", "3.6.1" diff --git a/win/win32/winhack.rc b/win/win32/winhack.rc index 06876aecf..aa8c23e9a 100644 --- a/win/win32/winhack.rc +++ b/win/win32/winhack.rc @@ -339,7 +339,7 @@ BEGIN VALUE "FileDescription", "NetHack for Windows - Graphical Interface" VALUE "FileVersion", "3.6.1" VALUE "InternalName", "NetHackW" - VALUE "LegalCopyright", "Copyright (C) 1985 - 2017. By Stichting Mathematisch Centrum and M. Stephenson. See license for details." + VALUE "LegalCopyright", "Copyright (C) 1985 - 2018. By Stichting Mathematisch Centrum and M. Stephenson. See license for details." VALUE "OriginalFilename", "NetHackW.exe" VALUE "PrivateBuild", "140606" VALUE "ProductName", "NetHack" From 176b85fbb773c2b4aa24569098438c77e45e7afd Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 25 Feb 2018 15:09:56 -0500 Subject: [PATCH 14/57] update msdos Makefile so at least possible to build --- sys/msdos/Makefile.GCC | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index 38c71fc9b..6b82a8853 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -648,8 +648,8 @@ $(O)makedefs.o: $(CONFIG_H) $(PERMONST_H) $(INCL)/objclass.h \ #========================================== $(U)lev_comp.exe: $(SPLEVOBJS) - @rm -f temp.a - @ar ru temp.a $(SPLEVOBJS) + -rm -f temp.a + ar ru temp.a $(SPLEVOBJS) $(LINK) $(LFLAGS) -o$@ temp.a ifeq ($(YACC_LEX),Y) @@ -813,18 +813,18 @@ $(DAT)/nhtiles.bmp: $(TILEFILES) $(U)tile2bmp.exe @$(subst /,\,chdir $(SRC)) $(U)tile2bmp.exe: $(O)tile2bmp.o $(TEXTIO) - @rm -f temp.a - @ar ru temp.a $(TEXTIO) + -rm -f temp.a + ar ru temp.a $(TEXTIO) $(LINK) $(LFLAGS) -o$@ $(O)tile2bmp.o temp.a $(U)tile2bin.exe: $(O)tile2bin.o $(TEXTIO) - @rm -f temp.a - @ar ru temp.a $(TEXTIO) + -rm -f temp.a + ar ru temp.a $(TEXTIO) $(LINK) $(LFLAGS) -o$@ $(O)tile2bin.o temp.a $(U)til2bin2.exe: $(O)til2bin2.o $(TEXTIO2) - @rm -f temp.a - @ar ru temp.a $(TEXTIO2) + -rm -f temp.a + ar ru temp.a $(TEXTIO2) $(LINK) $(LFLAGS) -o$@ $(O)til2bin2.o temp.a $(U)thintile.exe: $(O)thintile.o From 418b5e9034512bea4f78b2c92e66abf15fbbba6b Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 25 Feb 2018 15:15:10 -0500 Subject: [PATCH 15/57] update msdos header --- sys/msdos/Makefile.GCC | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index 6b82a8853..dd22541e3 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -1,5 +1,5 @@ -# NetHack 3.6 Makefile.GCC $NHDT-Date: 1457207036 2016/03/05 19:43:56 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.29 $ -# Copyright (c) NetHack PC Development Team 1996-2006. +# NetHack 3.6 Makefile.GCC $NHDT-Date: 1519589698 2018/02/25 20:14:58 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.32 $ +# Copyright (c) NetHack PC Development Team 1996-2018. # PC NetHack 3.6 Makefile for djgpp V2 # # Gnu gcc compiler for msdos (djgpp) From 424ce85e791926c2cdf7f4c2e4b8a866bc6eafde Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 25 Feb 2018 16:28:46 -0500 Subject: [PATCH 16/57] msdos Makefile update for posix regex --- sys/msdos/Makefile.GCC | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index dd22541e3..3496bc8bf 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -1,5 +1,5 @@ -# NetHack 3.6 Makefile.GCC $NHDT-Date: 1519589698 2018/02/25 20:14:58 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.32 $ -# Copyright (c) NetHack PC Development Team 1996-2018. +# NetHack 3.6 Makefile.GCC $NHDT-Date: 1519594120 2018/02/25 21:28:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.33 $ +# Copyright (c) NetHack PC Development Team 1996-2006. # PC NetHack 3.6 Makefile for djgpp V2 # # Gnu gcc compiler for msdos (djgpp) @@ -308,6 +308,9 @@ PPMWRITERS = $(O)ppmwrite.o $(O)alloc.o $(O)panic.o PPMWRIT2 = $(O)ppmwrit2.o $(O)alloc.o $(O)panic.o endif +#REGEX = $(O)pmatchregex.o +#REGEX = $(O)cppregex.o +REGEX = $(O)posixreg.o DLBOBJ = $(O)dlb.o @@ -336,7 +339,7 @@ VOBJ19 = $(O)trap.o $(O)u_init.o $(O)uhitm.o $(O)vault.o $(O)vision.o VOBJ20 = $(O)vis_tab.o $(O)weapon.o $(O)were.o $(O)wield.o $(O)windows.o VOBJ21 = $(O)wintty.o $(O)wizard.o $(O)worm.o $(O)worn.o $(O)write.o VOBJ22 = $(O)zap.o $(O)light.o $(O)dlb.o $(O)dig.o $(O)teleport.o -VOBJ23 = $(O)region.o $(O)sys.o $(O)pmatchre.o +VOBJ23 = $(O)region.o $(O)sys.o $(REGEX) SOBJ = $(O)msdos.o $(O)sound.o $(O)pcsys.o $(O)tty.o $(O)unix.o \ $(O)video.o $(O)vidtxt.o $(O)pckeys.o @@ -648,8 +651,8 @@ $(O)makedefs.o: $(CONFIG_H) $(PERMONST_H) $(INCL)/objclass.h \ #========================================== $(U)lev_comp.exe: $(SPLEVOBJS) - -rm -f temp.a - ar ru temp.a $(SPLEVOBJS) + @rm -f temp.a + @ar ru temp.a $(SPLEVOBJS) $(LINK) $(LFLAGS) -o$@ temp.a ifeq ($(YACC_LEX),Y) @@ -813,18 +816,18 @@ $(DAT)/nhtiles.bmp: $(TILEFILES) $(U)tile2bmp.exe @$(subst /,\,chdir $(SRC)) $(U)tile2bmp.exe: $(O)tile2bmp.o $(TEXTIO) - -rm -f temp.a - ar ru temp.a $(TEXTIO) + @rm -f temp.a + @ar ru temp.a $(TEXTIO) $(LINK) $(LFLAGS) -o$@ $(O)tile2bmp.o temp.a $(U)tile2bin.exe: $(O)tile2bin.o $(TEXTIO) - -rm -f temp.a - ar ru temp.a $(TEXTIO) + @rm -f temp.a + @ar ru temp.a $(TEXTIO) $(LINK) $(LFLAGS) -o$@ $(O)tile2bin.o temp.a $(U)til2bin2.exe: $(O)til2bin2.o $(TEXTIO2) - -rm -f temp.a - ar ru temp.a $(TEXTIO2) + @rm -f temp.a + @ar ru temp.a $(TEXTIO2) $(LINK) $(LFLAGS) -o$@ $(O)til2bin2.o temp.a $(U)thintile.exe: $(O)thintile.o @@ -1035,6 +1038,15 @@ $(O)unix.o: $(HACK_H) $(SSHR)/pcunix.c $(O)pcsys.o : $(HACK_H) $(SSHR)/pcsys.c $(CC) $(cflags) -o$@ $(SSHR)/pcsys.c +$(O)posixreg.o : $(HACK_H) $(SSHR)/posixreg.c + $(CC) $(cflags) -o$@ $(SSHR)/posixreg.c + +$(O)cppregex.o : $(HACK_H) $(SSHR)/cppregex.cpp + gpp $(cflags) -std=c++11 -o$@ $(SSHR)/cppregex.cpp + +$(O)pmatchre.o : $(HACK_H) $(SSHR)/pmatchre.c + $(CC) $(cflags) -o$@ $(SSHR)/pmatchre.c + # sys/msdos $(O)msdos.o : $(HACK_H) $(MSYS)/msdos.c # $(CC) $(cflags) -o$@ $(MSYS)/msdos.c @@ -1084,8 +1096,6 @@ $(O)tos.o: ../sys/atari/tos.c $(HACK_H) $(INCL)/tcap.h $(O)pcmain.o: ../sys/share/pcmain.c $(HACK_H) $(INCL)/dlb.h \ #$(INCL)/win32api.h $(CC) $(cflags) -o$@ ../sys/share/pcmain.c -$(O)pcsys.o: ../sys/share/pcsys.c $(HACK_H) - $(CC) $(cflags) -o$@ ../sys/share/pcsys.c $(O)pctty.o: ../sys/share/pctty.c $(HACK_H) $(CC) $(cflags) -o$@ ../sys/share/pctty.c $(O)pcunix.o: ../sys/share/pcunix.c $(HACK_H) From c475a5f0c64ffcceb6f6fbdaf17463ca99992912 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 25 Feb 2018 17:42:31 -0500 Subject: [PATCH 17/57] Bug 734 - #H4611: Whistling while deaf fixed --- src/apply.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/apply.c b/src/apply.c index 130a53d33..c28e01087 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 apply.c $NHDT-Date: 1496619131 2017/06/04 23:32:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.232 $ */ +/* NetHack 3.6 apply.c $NHDT-Date: 1519598527 2018/02/25 22:42:07 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.243 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -442,7 +442,11 @@ struct obj *obj; } else if (Underwater) { You("blow bubbles through %s.", yname(obj)); } else { - You(whistle_str, obj->cursed ? "shrill" : "high"); + if (Deaf) + You_feel("rushing air tickle your %s.", + body_part(NOSE)); + else + You(whistle_str, obj->cursed ? "shrill" : "high"); wake_nearby(); if (obj->cursed) vault_summon_gd(); From 8db8a14429ecd4062a8105c4765171ce20a7f077 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 25 Feb 2018 17:52:33 -0500 Subject: [PATCH 18/57] fixes36.1 catch-up bit for deaf whistling --- doc/fixes36.1 | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 479c39d54..f5ee11534 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -513,6 +513,7 @@ docall for type of object could overflow its prompt buffer if there was a very long type name previously assigned whatis lookup for 'more info?' would behave strangely for plural names, either entered by player or from "N foo" stacks on the map +you should not hear a whistle if you are deaf Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository From 4126b1e57a7f6286963f1de6a5558e6e08a3651d Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 25 Feb 2018 18:15:28 -0500 Subject: [PATCH 19/57] final msdos bit un-revert a reversion --- sys/msdos/Makefile.GCC | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index 3496bc8bf..3126d7622 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -1,4 +1,4 @@ -# NetHack 3.6 Makefile.GCC $NHDT-Date: 1519594120 2018/02/25 21:28:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.33 $ +# NetHack 3.6 Makefile.GCC $NHDT-Date: 1519600525 2018/02/25 23:15:25 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.34 $ # Copyright (c) NetHack PC Development Team 1996-2006. # PC NetHack 3.6 Makefile for djgpp V2 # @@ -651,7 +651,7 @@ $(O)makedefs.o: $(CONFIG_H) $(PERMONST_H) $(INCL)/objclass.h \ #========================================== $(U)lev_comp.exe: $(SPLEVOBJS) - @rm -f temp.a + -rm -f temp.a @ar ru temp.a $(SPLEVOBJS) $(LINK) $(LFLAGS) -o$@ temp.a @@ -816,17 +816,17 @@ $(DAT)/nhtiles.bmp: $(TILEFILES) $(U)tile2bmp.exe @$(subst /,\,chdir $(SRC)) $(U)tile2bmp.exe: $(O)tile2bmp.o $(TEXTIO) - @rm -f temp.a + -rm -f temp.a @ar ru temp.a $(TEXTIO) $(LINK) $(LFLAGS) -o$@ $(O)tile2bmp.o temp.a $(U)tile2bin.exe: $(O)tile2bin.o $(TEXTIO) - @rm -f temp.a + -rm -f temp.a @ar ru temp.a $(TEXTIO) $(LINK) $(LFLAGS) -o$@ $(O)tile2bin.o temp.a $(U)til2bin2.exe: $(O)til2bin2.o $(TEXTIO2) - @rm -f temp.a + -rm -f temp.a @ar ru temp.a $(TEXTIO2) $(LINK) $(LFLAGS) -o$@ $(O)til2bin2.o temp.a From f3aaee792fa10371e3e903563cc179625964af75 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 26 Feb 2018 08:35:33 -0800 Subject: [PATCH 20/57] fix #H4997 - "Congratulations" -> "Well done" Reported suggested that "congratulations" was too modern for use by your god during ascension and that the longer phrases which were shortened to yield it were too modest for the god to use. Make the suggested change. --- doc/fixes36.1 | 2 ++ src/pray.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index f5ee11534..5a85f7f7a 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -514,6 +514,8 @@ docall for type of object could overflow its prompt buffer if there was a very whatis lookup for 'more info?' would behave strangely for plural names, either entered by player or from "N foo" stacks on the map you should not hear a whistle if you are deaf +change the deity's "congratulations" message upon ascension to something which + sounds a bit more archaic to fit better with the other messages Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/src/pray.c b/src/pray.c index 0e74bb98a..ef61df831 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pray.c $NHDT-Date: 1514593198 2017/12/30 00:19:58 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.95 $ */ +/* NetHack 3.6 pray.c $NHDT-Date: 1519662898 2018/02/26 16:34:58 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.96 $ */ /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1496,7 +1496,7 @@ dosacrifice() u.uachieve.ascended = 1; pline( "An invisible choir sings, and you are bathed in radiance..."); - godvoice(altaralign, "Congratulations, mortal!"); + godvoice(altaralign, "Mortal, thou hast done well!"); display_nhwindow(WIN_MESSAGE, FALSE); verbalize( "In return for thy service, I grant thee the gift of Immortality!"); From b73d45fd66270fcadc2832bc5af894689f92063b Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 26 Feb 2018 11:18:29 -0800 Subject: [PATCH 21/57] throw-and-return for aklys The comment I added to data.base--to explain that despite what the short description says, an aklys wouldn't return to sender after being thrown--was bugging me, so I've made aklyses behave like Mjollnir. If thrown when wielded as primary weapon, it will usually return and usually be re-wielded. I also added a new message when either thrown Mjollnir or thrown aklys is expected to return and fails to do so. Most of the diff to dothrow.c is a change in indentation level. The amount of code needed was quite small. Autopickup for thrown Mjollnir which had failed to return was putting it into the quiver slot if that was empty. Note quite an outright bug, but it started wielded and can't be thrown if quivered, so exclude it from the stuff that will auto-fill the quiver slot when added to invent (post-3.6.0 issue). --- dat/data.base | 2 - doc/fixes36.1 | 5 +++ src/dothrow.c | 101 ++++++++++++++++++++++++++++++-------------------- src/invent.c | 7 +++- 4 files changed, 71 insertions(+), 44 deletions(-) diff --git a/dat/data.base b/dat/data.base index 2cef03af0..848f3112a 100644 --- a/dat/data.base +++ b/dat/data.base @@ -59,8 +59,6 @@ thonged club it to be drawn back to the wielder after having been thrown. It should not be confused with the atlatl, which is a device used to throw spears for longer distances. - - (NetHack's "aklys" is just a club and won't return if thrown.) ~agate ring agate* Translucent, cryptocrystalline variety of quartz and a subvariety diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 5a85f7f7a..62dcedaeb 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -595,6 +595,8 @@ unix: fix for freeing MAIL also introduced a memory leak whenever new mail when clairvoyance lets you move the cursor to examine the map (if it occurs when engulfed or underwater or when blessed clairvoyance finds a monster), the "for instructions type '?'" prompt could be confusing +prevent Mjollnir from being auto-quivered if it's been thrown without return + and then picked back up while quiver slot is empty Platform- and/or Interface-Specific Fixes @@ -785,6 +787,9 @@ change #adjust's behavior when collecting compatible stacks; that used to a prayer result which results in uncursing some or all of the hero's items won't uncurse a worn helm of opposite alignment since that would facilitate the hero switching to another god by taking it off +wielded aklys behaves like Mjollnir when thrown--it usually returns; unlike + Mjollnir, it isn't limited to Valkyries or need gauntlets of power + (so far, hero-only; an aklys won't return if thrown by a monster) Platform- and/or Interface-Specific New Features diff --git a/src/dothrow.c b/src/dothrow.c index 0b1539454..0c72002ee 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dothrow.c $NHDT-Date: 1502243899 2017/08/09 01:58:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.125 $ */ +/* NetHack 3.6 dothrow.c $NHDT-Date: 1519672703 2018/02/26 19:18:23 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.130 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1068,8 +1068,7 @@ void throwit(obj, wep_mask, twoweap) struct obj *obj; long wep_mask; /* used to re-equip returning boomerang */ -boolean - twoweap; /* used to restore twoweapon mode if wielded weapon returns */ +boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */ { register struct monst *mon; register int range, urange; @@ -1120,7 +1119,11 @@ boolean bhitpos.x = mon->mx; bhitpos.y = mon->my; } else if (u.dz) { - if (u.dz < 0 && Role_if(PM_VALKYRIE) && obj->oartifact == ART_MJOLLNIR + if (u.dz < 0 + /* Mjnollnir must we wielded to be thrown--caller verifies this; + aklys must we wielded as primary to return when thrown */ + && ((Role_if(PM_VALKYRIE) && obj->oartifact == ART_MJOLLNIR) + || (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0)) && !impaired) { pline("%s the %s and returns to your hand!", Tobjnam(obj, "hit"), ceiling(u.ux, u.uy)); @@ -1253,47 +1256,63 @@ boolean (void) mpickobj(u.ustuck, obj); thrownobj = (struct obj *) 0; } else { - /* the code following might become part of dropy() */ - if (obj->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE) - && rn2(100)) { - /* we must be wearing Gauntlets of Power to get here */ - sho_obj_return_to_u(obj); /* display its flight */ + /* Mjnollnir must we wielded to be thrown--caller verifies this; + aklys must we wielded as primary to return when thrown */ + if ((obj->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE)) + || (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0)) { + if (rn2(100)) { + sho_obj_return_to_u(obj); /* display its flight */ - if (!impaired && rn2(100)) { - pline("%s to your hand!", Tobjnam(obj, "return")); - obj = addinv(obj); - (void) encumber_msg(); - setuwep(obj); - u.twoweap = twoweap; - if (cansee(bhitpos.x, bhitpos.y)) - newsym(bhitpos.x, bhitpos.y); - } else { - int dmg = rn2(2); - if (!dmg) { - pline(Blind ? "%s lands %s your %s." - : "%s back to you, landing %s your %s.", - Blind ? Something : Tobjnam(obj, "return"), - Levitation ? "beneath" : "at", - makeplural(body_part(FOOT))); + if (!impaired && rn2(100)) { + pline("%s to your hand!", Tobjnam(obj, "return")); + obj = addinv(obj); + (void) encumber_msg(); + setuwep(obj); + u.twoweap = twoweap; + if (cansee(bhitpos.x, bhitpos.y)) + newsym(bhitpos.x, bhitpos.y); } else { - dmg += rnd(3); - pline(Blind ? "%s your %s!" - : "%s back toward you, hitting your %s!", - Tobjnam(obj, Blind ? "hit" : "fly"), - body_part(ARM)); - (void) artifact_hit((struct monst *) 0, &youmonst, obj, - &dmg, 0); - losehp(Maybe_Half_Phys(dmg), killer_xname(obj), - KILLED_BY); + int dmg = rn2(2); + + if (!dmg) { + pline(Blind ? "%s lands %s your %s." + : "%s back to you, landing %s your %s.", + Blind ? Something : Tobjnam(obj, "return"), + Levitation ? "beneath" : "at", + makeplural(body_part(FOOT))); + } else { + dmg += rnd(3); + pline(Blind ? "%s your %s!" + : "%s back toward you, hitting your %s!", + Tobjnam(obj, Blind ? "hit" : "fly"), + body_part(ARM)); + if (obj->oartifact) + (void) artifact_hit((struct monst *) 0, &youmonst, + obj, &dmg, 0); + losehp(Maybe_Half_Phys(dmg), killer_xname(obj), + KILLED_BY); + } + if (ship_object(obj, u.ux, u.uy, FALSE)) { + thrownobj = (struct obj *) 0; + return; + } + dropy(obj); } - if (ship_object(obj, u.ux, u.uy, FALSE)) { - thrownobj = (struct obj *) 0; - return; - } - dropy(obj); + thrownobj = (struct obj *) 0; + return; + } else { + /* when this location is stepped on, the weapon will be + auto-picked up due to 'obj->was_thrown' of 1; + addinv() prevents thrown Mjollnir from being placed + into the quiver slot, but an aklys will end up there if + that slot is empty at the time; since hero will need to + explicitly rewield the weapon to get throw-and-return + capability back anyway, quivered or not shouldn't matter */ + pline("%s fails to return!", + upstart(obj->oartifact ? ONAME(obj) + : thesimpleoname(obj))); + /* continue with placing 'obj' at target location */ } - thrownobj = (struct obj *) 0; - return; } if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ) && breaktest(obj)) { diff --git a/src/invent.c b/src/invent.c index 828a947df..1cd0cdd1a 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 invent.c $NHDT-Date: 1518053384 2018/02/08 01:29:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.224 $ */ +/* NetHack 3.6 invent.c $NHDT-Date: 1519672703 2018/02/26 19:18:23 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.225 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -598,6 +598,11 @@ struct obj *obj; /* fill empty quiver if obj was thrown */ if (flags.pickup_thrown && !uquiver && obj_was_thrown + /* if Mjollnir is thrown and fails to return, we want to + auto-pick it when we move to its spot, but not into quiver; + aklyses behave like Mjollnir when thrown while wielded, but + we lack sufficient information here make them exceptions */ + && obj->oartifact != ART_MJOLLNIR && (throwing_weapon(obj) || is_ammo(obj))) setuqwep(obj); added: From 8acc72b53a709e5219789d17bd55babfd23e37dc Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 27 Feb 2018 09:28:15 -0800 Subject: [PATCH 22/57] Mjollnir bit Ue the same object name formatting for the new "Mjollnir fails to return" message as is used for most of the other throwing messages. --- src/dothrow.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/dothrow.c b/src/dothrow.c index 0c72002ee..28791805a 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dothrow.c $NHDT-Date: 1519672703 2018/02/26 19:18:23 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.130 $ */ +/* NetHack 3.6 dothrow.c $NHDT-Date: 1519752483 2018/02/27 17:28:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.131 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1308,10 +1308,8 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */ that slot is empty at the time; since hero will need to explicitly rewield the weapon to get throw-and-return capability back anyway, quivered or not shouldn't matter */ - pline("%s fails to return!", - upstart(obj->oartifact ? ONAME(obj) - : thesimpleoname(obj))); - /* continue with placing 'obj' at target location */ + pline("%s to return!", Tobjnam(obj, "fail")); + /* continue below with placing 'obj' at target location */ } } From ee64ef548264cde0ea3de2bfe5e7064fb3588aa4 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 28 Feb 2018 09:17:06 +0200 Subject: [PATCH 23/57] Fix comment typo --- src/dothrow.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dothrow.c b/src/dothrow.c index 28791805a..e57ee4122 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1120,7 +1120,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */ bhitpos.y = mon->my; } else if (u.dz) { if (u.dz < 0 - /* Mjnollnir must we wielded to be thrown--caller verifies this; + /* Mjollnir must we wielded to be thrown--caller verifies this; aklys must we wielded as primary to return when thrown */ && ((Role_if(PM_VALKYRIE) && obj->oartifact == ART_MJOLLNIR) || (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0)) @@ -1256,7 +1256,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */ (void) mpickobj(u.ustuck, obj); thrownobj = (struct obj *) 0; } else { - /* Mjnollnir must we wielded to be thrown--caller verifies this; + /* Mjollnir must we wielded to be thrown--caller verifies this; aklys must we wielded as primary to return when thrown */ if ((obj->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE)) || (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0)) { From a9b6b6a4eb038e9fef87f0b3b87b6086f07be4fe Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 2 Mar 2018 15:49:45 +0200 Subject: [PATCH 24/57] Fix Cleaving giving dmonsfree warning Due to inverted logic, hitting a blue jelly with the Cleaver could cause a dmonsfree warning - the jelly would die, but then come back to life via the passive attack. This is a post-3.6.0 bug --- src/uhitm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uhitm.c b/src/uhitm.c index daa069cc4..6807df056 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -540,7 +540,7 @@ struct attack *uattk; mhit = (tmp > dieroll); result = known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty, uattk, dieroll); - (void) passive(mtmp, uwep, mhit, DEADMONSTER(mtmp), AT_WEAP, !uwep); + (void) passive(mtmp, uwep, mhit, !DEADMONSTER(mtmp), AT_WEAP, !uwep); if (mon == mtmp) malive = result; } From a7df3ce4c7f7e5dacd7700566b9c255682b9c77f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 2 Mar 2018 16:32:29 +0200 Subject: [PATCH 25/57] fixes typo bit --- doc/fixes36.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 62dcedaeb..adab9a96a 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -190,7 +190,7 @@ grammar bit when hallucinating: "you kill poor goblin" ('the' missing for pet) some blindness cures ignored u.ucreamed some instances of stun or confusion timers were being overridden rather than incremented when new stun or confusion damage was suffered -female gnome who gains level can grow up into male-only gnome lord; give an +female gnome who gains level can grow up into male-only gnome lord; give an alternate message instead of prohibiting the promotion kicked weapon which successfully hits monster vanishes from play unseen landmine explosion could result in "The statue crumbles." From fc74b77c946caacf1e7b43e3707a4aff16a0c691 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 2 Mar 2018 16:38:52 +0200 Subject: [PATCH 26/57] fixes typo bit, pt2 --- doc/fixes36.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index adab9a96a..a54728019 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -295,7 +295,7 @@ don't give "you cannot pass through the bars" when travel is testing possible paths in the vicinity of iron bars if blind and no gloves, using 'm' to move and then 'e' could be used to locate cockatrice corpse without fatal touching (by declining to eat) -it's cannabilism for a were to eat a corpse +it's cannibalism for a were to eat a corpse conduct: wishing for an artifact and not getting it because it already exists counts as wishing for an artifact, just like when not getting it because of quest restrictions or too many artifacts in play does From d136ffbba6d5878933243847995daee88bd7abcb Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 2 Mar 2018 16:56:18 +0200 Subject: [PATCH 27/57] fixes typo bit, pt3 --- doc/fixes36.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index a54728019..887ba0e70 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -304,7 +304,7 @@ gelatinous cube shouldn't be able to eat a scroll of scare monster make fireballs or cones of cold cast at skilled or higher not go through walls prevent flying monsters from hovering over unreachable underwater objects lembas wafer gives increased nutrition to elves, reduced nutrition to orcs; - cram ration gives increase nutrition to dwarves + cram ration gives increased nutrition to dwarves when #tip's terse object drop format got interrupted by a regular message, it continued using "obj2, obj3, ..." for subsequent objects, where the sentence grammar no longer made sense (the interrupting message From d4ea0f6ce60a54be2acdfedbecefd1ff5797dba4 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 2 Mar 2018 15:35:07 -0500 Subject: [PATCH 28/57] date bit --- util/makedefs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/makedefs.c b/util/makedefs.c index 2726816e8..2c55ba710 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 makedefs.c $NHDT-Date: 1516697571 2018/01/23 08:52:51 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.118 $ */ +/* NetHack 3.6 makedefs.c $NHDT-Date: 1520022901 2018/03/02 20:35:01 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.121 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) M. Stephenson, 1990, 1991. */ /* Copyright (c) Dean Luick, 1990. */ @@ -52,7 +52,7 @@ #endif #if defined(UNIX) && !defined(LINT) && !defined(GCC_WARN) -static const char SCCS_Id[] = "@(#)makedefs.c\t3.6\t2016/02/12"; +static const char SCCS_Id[] = "@(#)makedefs.c\t3.6\t2018/03/02"; #endif /* names of files to be generated */ From 36e4d80547dc2e56416e09788b0b8d0542c429dd Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 2 Mar 2018 18:19:23 -0800 Subject: [PATCH 29/57] Cleaver update I worked on this a while back but didn't commit it because I couldn't figure out the dead monster which wouldn't die. Pasi beat me to that. Clean up the Cleaver code some and make the three-target swing alternate between counter-clockwise and clockwise to simulate normal right-to-left swing followed by left-to-right backswing. (Alternation happens on each swing regardless of whether it is consecutive with the most recent one. That's suboptimal but easy....) Also, stop three-target attack early if hero is life-saved after being killed by a passive counter-attack from the first or second target. Prevent rogue backstab and two-hander breaking foes' weapons when using Cleaver hand-to-hand because getting more than one of either of those bonuses at a time would be excessive. I think allowing those for the primary target but not for the two adjacent ones would be better, but I just thought of that and am not going back for another round of revising. This doesn't incorporate the two pull requests: one to avoid hitting tame or peaceful adjacent targets unless the primary was also tame or peaceful, the other to avoid hitting unseen adjacent targets. I'm not sure if that includes remembered-unseen 'I' on the spot or no monster shown at all. (There's a third one about updating the map but it isn't needed for the existing Cleaver code either before or after this patch.) I'm in favor of the first one and am not sure about the second. My original concern was that someone could use Cleaver to find/hit three unknown monsters at a time via 'F' prefix, but forcefight aimed at thin air doesn't reach the Cleaver code so that can't happen, nor can attacking two known close monsters at once by targetting an empty spot between them. --- src/uhitm.c | 107 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 40 deletions(-) diff --git a/src/uhitm.c b/src/uhitm.c index 6807df056..bfc103e0a 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 uhitm.c $NHDT-Date: 1517128664 2018/01/28 08:37:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.173 $ */ +/* NetHack 3.6 uhitm.c $NHDT-Date: 1520043553 2018/03/03 02:19:13 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.175 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -14,8 +14,7 @@ STATIC_DCL boolean FDECL(hmon_hitmon, (struct monst *, struct obj *, int, int)); STATIC_DCL int FDECL(joust, (struct monst *, struct obj *)); STATIC_DCL void NDECL(demonpet); -STATIC_DCL boolean FDECL(m_slips_free, (struct monst * mtmp, - struct attack *mattk)); +STATIC_DCL boolean FDECL(m_slips_free, (struct monst *, struct attack *)); STATIC_DCL int FDECL(explum, (struct monst *, struct attack *)); STATIC_DCL void FDECL(start_engulf, (struct monst *)); STATIC_DCL void NDECL(end_engulf); @@ -489,63 +488,85 @@ int dieroll; return malive; } -/* hit the monster next to you and the monsters to the left and right of it */ +/* hit the monster next to you and the monsters to the left and right of it; + return False if the primary target is killed, True otherwise */ STATIC_OVL boolean -hitum_cleave(mon, uattk) -struct monst *mon; -struct attack *uattk; +hitum_cleave(target, uattk) +struct monst *target; /* non-Null; forcefight at nothing doesn't cleave... */ +struct attack *uattk; /* ... but we don't enforce that here; Null works ok */ { - int i = 0; - int x = u.ux; - int y = u.uy; - int count = 3; - boolean malive = TRUE; - struct monst *mtmp; + /* swings will be delivered in alternate directions; with consecutive + attacks it will simulate normal swing and backswing; when swings + are non-consecutive, hero will sometimes start a series of attacks + with a backswing--that doesn't impact actual play, just spoils the + simulation attempt a bit */ + static boolean clockwise = FALSE; + unsigned i; + int count, umort, x = u.ux, y = u.uy; - /* find the direction we're swinging */ - while (i < 8) { + /* find the direction toward primary target */ + for (i = 0; i < 8; ++i) if (xdir[i] == u.dx && ydir[i] == u.dy) break; - i++; - } - if (i == 8) { - impossible("hitum_cleave: failed to find target monster?"); - return TRUE; + impossible("hitum_cleave: unknown target direction [%d,%d,%d]?", + u.dx, u.dy, u.dz); + return TRUE; /* target hasn't been killed */ } - i = (i + 2) % 8; + clockwise = !clockwise; /* alternate */ + /* adjust direction by two so that loop's increment (for clockwise) + or decrement (for counter-clockwise) will point at the spot next + to primary target */ + if (clockwise) + i = (i + 6) % 8; + else + i = (i + 2) % 8; + umort = u.umortality; /* used to detect life-saving */ - /* swing from right to left */ - while (count-- && uwep) { - boolean result; - int tmp, dieroll, mhit, attknum, armorpenalty; + /* + * Three attacks: adjacent to primary, primary, adjacent on other + * side. Primary target must be present or we wouldn't have gotten + * here (forcefight at thin air won't 'cleave'). However, the + * first attack might kill it (gas spore explosion, weak long worm + * occupying both spots) so we don't assume that it's still present + * on the second attack. + */ + for (count = 3; count > 0; --count) { + struct monst *mtmp; + int tx, ty, tmp, dieroll, mhit, attknum, armorpenalty; - if (!i) - i = 7; + if (clockwise) + i = (i + 1) % 8; /* ++i, wrap 8 to i=0 */ else - i--; + i = (i + 7) % 8; /* --i, wrap -1 to i=7 */ - mtmp = NULL; - if (isok(x + xdir[i], y + ydir[i])) - mtmp = m_at(x + xdir[i], y + ydir[i]); + tx = x + xdir[i], ty = y + ydir[i]; /* current target location */ + if (!isok(tx, ty)) + continue; + mtmp = m_at(tx, ty); if (!mtmp) { - (void) unmap_invisible(x + xdir[i], y + ydir[i]); + if (glyph_is_invisible(levl[tx][ty].glyph)) + (void) unmap_invisible(tx, ty); continue; } - tmp = find_roll_to_hit(mtmp, uattk->aatyp, uwep, &attknum, &armorpenalty); dieroll = rnd(20); mhit = (tmp > dieroll); - result = known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty, - uattk, dieroll); + (void) known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty, + uattk, dieroll); (void) passive(mtmp, uwep, mhit, !DEADMONSTER(mtmp), AT_WEAP, !uwep); - if (mon == mtmp) - malive = result; + + /* stop attacking if weapon is gone or hero got killed and + life-saved after passive counter-attack */ + if (!uwep || u.umortality > umort) + break; } - return malive; + /* return False if primary target died, True otherwise; note: if 'target' + was nonNull upon entry then it's still nonNull even if *target died */ + return (target && DEADMONSTER(target)) ? FALSE : TRUE; } /* hit target monster; returns TRUE if it still lives */ @@ -562,7 +583,10 @@ struct attack *uattk; int dieroll = rnd(20); int mhit = (tmp > dieroll || u.uswallow); - if (uwep && uwep->oartifact == ART_CLEAVER + /* Cleaver attacks three spots, one on either side of 'mon'; + it can't we part of dual-wielding but we guard against that anyway; + cleave return value reflects status of primary target ('mon') */ + if (uwep && uwep->oartifact == ART_CLEAVER && !u.twoweap && !u.uswallow && !u.ustuck && !NODIAG(u.umonnum)) return hitum_cleave(mon, uattk); @@ -718,7 +742,10 @@ int dieroll; tmp = dmgval(obj, mon); /* a minimal hit doesn't exercise proficiency */ valid_weapon_attack = (tmp > 1); - if (!valid_weapon_attack || mon == u.ustuck || u.twoweap) { + if (!valid_weapon_attack || mon == u.ustuck || u.twoweap + /* Cleaver can hit up to three targets at once so don't + let it also hit from behind or shatter foes' weapons */ + || (hand_to_hand && obj->oartifact == ART_CLEAVER)) { ; /* no special bonuses */ } else if (mon->mflee && Role_if(PM_ROGUE) && !Upolyd /* multi-shot throwing is too powerful here */ From 68523fe88c107c1129f4933505e356287b6b222e Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 3 Mar 2018 16:15:12 +0200 Subject: [PATCH 30/57] Add catch-all database entry for the polearms --- dat/data.base | 36 ++++++++++++++++++++++++++++++------ doc/fixes36.1 | 1 + 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/dat/data.base b/dat/data.base index 848f3112a..e07ab954e 100644 --- a/dat/data.base +++ b/dat/data.base @@ -3183,12 +3183,12 @@ mars martial arts unarmed combat bare*handed combat - "What else can we do? None of this is fast enough." "It will have - to be." He stood up, a tall, broad wall of a man. "Why don't you - ask around, see if anyone in the neighborhoods knows anything - about martial arts. You need more than a book or two to learn - good dependable unarmed combat." - [ Parable of the Sower, by Octavia Butler ] + "What else can we do? None of this is fast enough." "It will have + to be." He stood up, a tall, broad wall of a man. "Why don't you + ask around, see if anyone in the neighborhoods knows anything + about martial arts. You need more than a book or two to learn + good dependable unarmed combat." + [ Parable of the Sower, by Octavia Butler ] master assassin He strolled down the stairs, followed by a number of assassins. When he was directly in front of Ymor he said: "I've come for @@ -3943,6 +3943,30 @@ user Might just kill you. [ It's a Jungle Out There, by Randy Newman ] # [ theme song from "Monk" ] +polearm +* polearm +partisan +ranseur +spetum +glaive +halberd +bardiche +angled poleaxe +long poleaxe +voulge +pole cleaver +fauchard +pole sickle +guisarme +bill-guisarme +lucern hammer +bec de corbin + Many of the weapons of the Middle Ages were poled or long-shafted + arms. Unlike the ancient spear or javelin, however, they were not + intended to be thrown. Some were devices with simple single- or + double-edged blades and nothing more, while others combined + the pick, spear, and hammer or axe all in one weapon. + [ Heraldry and Armor of the Middle Ages, by Marvin H. Pakula ] polymorph trap One morning, as Gregor Samsa was waking up from anxious dreams, he discovered that in bed he had been changed into a monstrous diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 887ba0e70..02bded2af 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -414,6 +414,7 @@ surviving a gas spore's explosion would leave that explosion as a stale reason for death which might show up strangely ("crushed to death by a gas spore's explosion" when killed by an opening drawbridge) add database entry for "martial arts" +add catch-all database entry for the polearms starting inventory for rogues specified +9 lock pick, where +/-N is meaningless fix pile mark when picking up all-but-one items while invisible improve config file error reporting From 09554c2b96cf3a69e2eb99e21c520d9f5de67956 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 3 Mar 2018 16:58:07 +0200 Subject: [PATCH 31/57] Make spotless should remove qt4 specific files --- sys/unix/Makefile.dat | 1 + sys/unix/Makefile.utl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/unix/Makefile.dat b/sys/unix/Makefile.dat index 6327b0c10..3992b1769 100644 --- a/sys/unix/Makefile.dat +++ b/sys/unix/Makefile.dat @@ -168,3 +168,4 @@ spotless: -rm -f spec_levs quest_levs *.lev $(VARDAT) dungeon dungeon.pdf -rm -f nhdat x11tiles beostiles pet_mark.xbm pilemark.xbm rip.xpm mapbg.xpm -rm -f rip.img GEM_RSC.RSC title.img nh16.img NetHack.ad + -rm -f nhsplash.xpm nhtiles.bmp diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index 224df10a7..ca7124a40 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -481,4 +481,4 @@ spotless: clean -rm -f ../include/tile.h tiletxt.c -rm -f makedefs lev_comp dgn_comp recover dlb -rm -f gif2txt txt2ppm tile2x11 tile2img.ttp xpm2img.ttp \ - tilemap tileedit + tilemap tileedit tile2bmp From 4029e2580a85da479faca318300e6f4d32263054 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 3 Mar 2018 10:19:47 -0500 Subject: [PATCH 32/57] interim dungeoneer, README update --- README | 43 ++++++++++++++++++++--------- doc/Guidebook.mn | 70 ++++++++++++++++++++--------------------------- doc/Guidebook.tex | 60 ++++++++++++++++++++-------------------- 3 files changed, 90 insertions(+), 83 deletions(-) diff --git a/README b/README index c428e146d..bc0996a82 100644 --- a/README +++ b/README @@ -1,24 +1,38 @@ NetHack 3.6.1 -- General information -NetHack 3.6 is an enhancement to the dungeon exploration game NetHack. -It is a distant descendent of Rogue and Hack, and a direct descendent of -NetHack 3.4. In order to avoid confusion with interim development code -that was posted online in 2014 by others, there is no NetHack 3.5 release. +NetHack 3.6 is an enhancement to the dungeon exploration game NetHack, +which is a distant descendent of Rogue and Hack, and a direct descendent of +NetHack 3.4 as there was no NetHack 3.5 release. -NetHack 3.6.1 contains several dozen bugfixes. - -The file doc/fixes36.1 in the source distribution has a full list of each. +NetHack 3.6.1 contains several hundred bug fixes to NetHack 3.6.0. The +file doc/fixes36.1 in the source distribution has a full list of them. The text in there was written for the development team's own use and is provided "as is", so please do not ask us to further explain the entries in that file. Some entries might be considered "spoilers", particularly in the "new features" section. -Here are some additional general notes that are not considered spoilers: - * Some code paths and long-established game features have been made - part of the base build and no longer conditional on compile settings. - * Several treasured NetHack community patches, or a variation of - them, have been rolled in to the base NetHack source tree, incuding: - menucolors, pickup thrown, statue glyphs, dungeon overview, sortloot. +Below you will find some other general notes were not considered spoilers: +* additional Terry Pratchett tribute passages +* enhanced map position picking +* new status line conditions Stone Strngl Deaf Lev Fly Ride +* updated status hilites and several interface enhancements +* new paranoid_confirm settings +* a new extended command #kick +* the vanquished monsters list can be sorted during end of game disclosure +* fountains are bright blue +* travel accepts 'm' (request menu) prefix +* pressing a or A when cursor positioning shows menu of "interesting" features +* pressing z or Z when cursor positioning can cycle through valid locations +* add option herecmd_menu to make a mouse click on your character pop up a menu +* #adjust's behavior altered when collecting compatible stacks +* Some community patches that were included: + - Malcolm Ryan's improved tin opener + - Ray Chason's MSDOS port support for some VESA modes + - Ray Chason's Qt4 windowport + - Darshan Shaligram's pet ranged attack + - Jason Dorje Short's key rebinding + - Maxime Bacoux's new DUMPLOG +* updated database entries for several things - - - - - - - - - - - @@ -66,6 +80,9 @@ Please read items (1), (2) and (3) BEFORE doing anything with your new code. Mac OS X 10.9 OpenVMS (aka VMS) V8.4 on Alpha and on Integrity/Itanium/IA64 + Instructions have been provided by way of community contribution on: + msdos protected mode using djgpp + Previous versions of NetHack were tested and known to run on the following systems, but it is unknown if they can still build and execute NetHack 3.6: diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 3989cec93..ef2bfd9c4 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -4292,46 +4292,36 @@ in this, the list of Dungeoneers: center; c c c. .\"TABLE_START -Adam Aronow Janet Walz Nathan Eady -Alex Kompel Janne Salmijarvi Norm Meluch -Andreas Dorn Jean-Christophe Collet Olaf Seibert -Andy Church Jeff Bailey Pasi Kallinen -Andy Swanson Jochen Erwied Pat Rankin -Ari Huttunen John Kallen Paul Winner -Barton House John Rupley Pierre Martineau -Benson I. Margulies John S. Bien Ralf Brown -Bill Dyer Johnny Lee Ray Chason -Boudewijn Waijers Jon W{tte Richard Addison -Bruce Cox Jonathan Handler Richard Beigel -Bruce Holloway Joshua Delahunty Richard P. Hughey -Bruce Mewborne Keizo Yamamoto Rob Menke -Carl Schelin Ken Arnold Robin Bandy -Chris Russo Ken Arromdee Robin Johnson -David Cohrs Ken Lorber Roderick Schertler -David Damerell Ken Washikita Roland McGrath -David Gentzel Kevin Darcy Ron Van Iwaarden -David Hairston Kevin Hugo Ronnen Miller -Dean Luick Kevin Sitze Ross Brown -Del Lamb Kevin Smolkowski Sascha Wostmann -Derek S. Ray Kevin Sweet Scott Bigham -Deron Meranda Lars Huttar Scott R. Turner -Dion Nicolaas Leon Arnott Sean Hunt -Dylan O'Donnell M. Drew Streib Stephen Spackman -Eric Backus Malcolm Ryan Stefan Thielscher -Eric Hendrickson Mark Gooderum Stephen White -Eric R. Smith Mark Modrall Steve Creps -Eric S. Raymond Marvin Bressler Steve Linhart -Erik Andersen Matthew Day Steve VanDevender -Frederick Roeber Merlyn LeRoy Teemu Suikki -Gil Neiger Michael Allison Tim Lennan -Greg Laskin Michael Feir Timo Hakulinen -Greg Olson Michael Hamel Tom Almy -Gregg Wonderly Michael Sokolov Tom West -Hao-yang Wang Mike Engber Warren Cheung -Helge Hafting Mike Gallop Warwick Allison -Irina Rempt-Drijfhout Mike Passaretti Yitzhak Sapir -Izchak Miller Mike Stephenson -J. Ali Harlow Mikko Juola +Adam Aronow Erik Andersen Kevin Sitze Ray Chason +Alex Kompel Frederick Roeber Kevin Smolkowski Richard Addison +Alex Smith Gil Neiger Kevin Sweet Richard Beigel +Andreas Dorn Greg Laskin Lars Huttar Richard P. Hughey +Andy Church Greg Olson Leon Arnott Rob Menke +Andy Swanson Gregg Wonderly M. Drew Streib Robin Bandy +Ari Huttunen Hao-yang Wang Malcolm Ryan Robin Johnson +Barton House Helge Hafting Mark Gooderum Roderick Schertler +Benson I. Margulies Irina Rempt-Drijfhout Mark Modrall Roland McGrath +Bill Dyer Izchak Miller Marvin Bressler Ron Van Iwaarden +Boudewijn Waijers J. Ali Harlow Matthew Day Ronnen Miller +Bruce Cox Janet Walz Merlyn LeRoy Ross Brown +Bruce Holloway Janne Salmijarvi Michael Allison Sascha Wostmann +Bruce Mewborne Jean-Christophe Collet Michael Feir Scott Bigham +Carl Schelin Jeff Bailey Michael Hamel Scott R. Turner +Chris Russo Jochen Erwied Michael Sokolov Sean Hunt +David Cohrs John Kallen Mike Engber Stephen Spackman +David Damerell John Rupley Mike Gallop Stefan Thielscher +David Gentzel John S. Bien Mike Passaretti Stephen White +David Hairston Johnny Lee Mike Stephenson Steve Creps +Dean Luick Jon W{tte Mikko Juola Steve Linhart +Del Lamb Jonathan Handler Nathan Eady Steve VanDevender +Derek S. Ray Joshua Delahunty Norm Meluch Teemu Suikki +Deron Meranda Keizo Yamamoto Olaf Seibert Tim Lennan +Dion Nicolaas Ken Arnold Pasi Kallinen Timo Hakulinen +Dylan O'Donnell Ken Arromdee Pat Rankin Tom Almy +Eric Backus Ken Lorber Patric Mueller Tom West +Eric Hendrickson Ken Washikita Paul Winner Warren Cheung +Eric R. Smith Kevin Darcy Pierre Martineau Warwick Allison +Eric S. Raymond Kevin Hugo Ralf Brown Yitzhak Sapir .\"TABLE_END Do not delete this line. .TE diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index ea948813b..48c122a7e 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -5236,36 +5236,36 @@ in this, the list of Dungeoneers: \begin{center} \begin{tabular}{llll} %TABLE_START -Adam Aronow & Frederick Roeber & Kevin Smolkowski & Richard Beigel\\ -Alex Kompel & Gil Neiger & Kevin Sweet & Richard P. Hughey\\ -Andreas Dorn & Greg Laskin & Lars Huttar & Rob Menke\\ -Andy Church & Greg Olson & Leon Arnott & Robin Bandy\\ -Andy Swanson & Gregg Wonderly & M. Drew Streib & Robin Johnson\\ -Ari Huttunen & Hao-yang Wang & Malcolm Ryan & Roderick Schertler\\ -Barton House & Helge Hafting & Mark Gooderum & Roland McGrath\\ -Benson I. Margulies & Irina Rempt-Drijfhout & Mark Modrall & Ron Van Iwaarden\\ -Bill Dyer & Izchak Miller & Marvin Bressler & Ronnen Miller\\ -Boudewijn Waijers & J. Ali Harlow & Matthew Day & Ross Brown\\ -Bruce Cox & Janet Walz & Merlyn LeRoy & Sascha Wostmann\\ -Bruce Holloway & Janne Salmij\"{a}rvi & Michael Allison & Scott Bigham\\ -Bruce Mewborne & Jean-Christophe Collet & Michael Feir & Scott R. Turner\\ -Carl Schelin & Jeff Bailey & Michael Hamel & Sean Hunt\\ -Chris Russo & Jochen Erwied & Michael Sokolov & Stephen Spackman\\ -David Cohrs & John Kallen & Mike Engber & Stefan Thielscher\\ -David Damerell & John Rupley & Mike Gallop & Stephen White\\ -David Gentzel & John S. Bien & Mike Passaretti & Steve Creps\\ -David Hairston & Johnny Lee & Mike Stephenson & Steve Linhart\\ -Dean Luick & Jon W\{tte & Mikko Juola & Steve VanDevender\\ -Del Lamb & Jonathan Handler & Nathan Eady & Teemu Suikki\\ -Derek S. Ray & Joshua Delahunty & Norm Meluch & Tim Lennan\\ -Deron Meranda & Keizo Yamamoto & Olaf Seibert & Timo Hakulinen\\ -Dion Nicolaas & Ken Arnold & Pasi Kallinen & Tom Almy\\ -Dylan O'Donnell & Ken Arromdee & Pat Rankin & Tom West\\ -Eric Backus & Ken Lorber & Paul Winner & Warren Cheung\\ -Eric Hendrickson & Ken Washikita & Pierre Martineau & Warwick Allison\\ -Eric R. Smith & Kevin Darcy & Ralf Brown & Yitzhak Sapir\\ -Eric S. Raymond & Kevin Hugo & Ray Chason\\ -Erik Andersen & Kevin Sitze & Richard Addison +Adam Aronow & Erik Andersen & Kevin Sitze & Ray Chason\\ +Alex Kompel & Frederick Roeber & Kevin Smolkowski & Richard Addison\\ +Alex Smith & Gil Neiger & Kevin Sweet & Richard Beigel\\ +Andreas Dorn & Greg Laskin & Lars Huttar & Richard P. Hughey\\ +Andy Church & Greg Olson & Leon Arnott & Rob Menke\\ +Andy Swanson & Gregg Wonderly & M. Drew Streib & Robin Bandy\\ +Ari Huttunen & Hao-yang Wang & Malcolm Ryan & Robin Johnson\\ +Barton House & Helge Hafting & Mark Gooderum & Roderick Schertler\\ +Benson I. Margulies & Irina Rempt-Drijfhout & Mark Modrall & Roland McGrath\\ +Bill Dyer & Izchak Miller & Marvin Bressler & Ron Van Iwaarden\\ +Boudewijn Waijers & J. Ali Harlow & Matthew Day & Ronnen Miller\\ +Bruce Cox & Janet Walz & Merlyn LeRoy & Ross Brown\\ +Bruce Holloway & Janne Salmij\"{a}rvi & Michael Allison & Sascha Wostmann\\ +Bruce Mewborne & Jean-Christophe Collet & Michael Feir & Scott Bigham\\ +Carl Schelin & Jeff Bailey & Michael Hamel & Scott R. Turner\\ +Chris Russo & Jochen Erwied & Michael Sokolov & Sean Hunt\\ +David Cohrs & John Kallen & Mike Engber & Stephen Spackman\\ +David Damerell & John Rupley & Mike Gallop & Stefan Thielscher\\ +David Gentzel & John S. Bien & Mike Passaretti & Stephen White\\ +David Hairston & Johnny Lee & Mike Stephenson & Steve Creps\\ +Dean Luick & Jon W\{tte & Mikko Juola & Steve Linhart\\ +Del Lamb & Jonathan Handler & Nathan Eady & Steve VanDevender\\ +Derek S. Ray & Joshua Delahunty & Norm Meluch & Teemu Suikki\\ +Deron Meranda & Keizo Yamamoto & Olaf Seibert & Tim Lennan\\ +Dion Nicolaas & Ken Arnold & Pasi Kallinen & Timo Hakulinen\\ +Dylan O'Donnell & Ken Arromdee & Pat Rankin & Tom Almy\\ +Eric Backus & Ken Lorber & Patric Mueller & Tom West\\ +Eric Hendrickson & Ken Washikita & Paul Winner & Warren Cheung\\ +Eric R. Smith & Kevin Darcy & Pierre Martineau & Warwick Allison\\ +Eric S. Raymond & Kevin Hugo & Ralf Brown & Yitzhak Sapir %TABLE_END Do not delete this line. \end{tabular} \end{center} From 9ee13bdd22a66d6c95563c23e35ce58ca1d15896 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 3 Mar 2018 10:24:26 -0500 Subject: [PATCH 33/57] typo missing word --- README | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README b/README index bc0996a82..1fe8f8146 100644 --- a/README +++ b/README @@ -11,7 +11,8 @@ provided "as is", so please do not ask us to further explain the entries in that file. Some entries might be considered "spoilers", particularly in the "new features" section. -Below you will find some other general notes were not considered spoilers: +Below you will find some other general notes that were not considered +spoilers: * additional Terry Pratchett tribute passages * enhanced map position picking * new status line conditions Stone Strngl Deaf Lev Fly Ride From 27a7538e381dbc251b195d0e14fce851bea82f23 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 3 Mar 2018 12:58:53 -0500 Subject: [PATCH 34/57] enable USE_WIN_IOCTL code unless explicitly avoided Changes to be committed: modified: doc/fixes36.1 modified: include/unixconf.h modified: sys/share/ioctl.c github pull request #19 made reference to resulting code behaviour being better when windows were resized when USE_WIN_IOCTL was defined. The logic for including the necessary enabling code in the build in sys/share/ioctl.c was an explicit "opt-in" strategy, so anything not deliberately and explicitly listed was not able to take advantae of the potentially useful code. The need to add #defines to that list would have been perpetual as new platforms came online, and unnecessarily restrictive for everything else. This switches the logic to include the code by default now, and thus unless there is an explicit "opt-out" by uncommenting AVOID_WIN_IOCTL in include/unixconf.h Some platforms, and we have no way of knowing which ones, may have to ensure that AVOID_WIN_IOCTL is #define'd. --- doc/fixes36.1 | 2 ++ include/unixconf.h | 4 +++- sys/share/ioctl.c | 11 +++++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 02bded2af..c282bdc58 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -635,6 +635,8 @@ unix: race condition with parallel make: src/Makefile might start building unix: Makefile.{src,utl} ignored CPPFLAGS which is expanded by the default .c rule by GNU make so if user had a value for that in the environment, it would apply to some files but not others; explicitly override it +unix: enable code guarded by USE_WIN_IOCTL by default unless prevented by + uncommenting #define AVOID_WIN_IOCTL in include/unixconf.h win32gui: getversionstring() was overflowing the provided Help About buffer win32gui: guard against buffer overflow in in mswin_getlin() win32gui: handle menu_color attribute diff --git a/include/unixconf.h b/include/unixconf.h index 88e309d55..cec8c709a 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 unixconf.h $NHDT-Date: 1451342112 2015/12/28 22:35:12 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.25 $ */ +/* NetHack 3.6 unixconf.h $NHDT-Date: 1520099325 2018/03/03 17:48:45 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.30 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -136,6 +136,8 @@ #define TIMED_DELAY #endif +/* #define AVOID_WIN_IOCTL */ /* ensure USE_WIN_IOCTL remains undefined */ + /* * If you define MAIL, then the player will be notified of new mail * when it arrives. If you also define DEF_MAILREADER then this will diff --git a/sys/share/ioctl.c b/sys/share/ioctl.c index 3da74b81a..138d02b5c 100644 --- a/sys/share/ioctl.c +++ b/sys/share/ioctl.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 ioctl.c $NHDT-Date: 1432512788 2015/05/25 00:13:08 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.6 ioctl.c $NHDT-Date: 1520099308 2018/03/03 17:48:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -63,9 +63,12 @@ struct termio termio; #include #endif -#if defined(TIOCGWINSZ) \ - && (defined(BSD) || defined(ULTRIX) || defined(AIX_31) \ - || defined(_BULL_SOURCE) || defined(SVR4)) +/* AVOID_WIN_IOCTL can be uncommented in unixconf.h + * to force USE_WIN_IOTCL to remain undefined, + * instead of the restricted explicit opt-in + * logic that used to be here. + */ +#if defined(TIOCGWINSZ) && !defined(AVOID_WIN_IOCTL) #define USE_WIN_IOCTL #include "tcap.h" /* for LI and CO */ #endif From 6bd8efe510699b7f52e17eb466f23a56c4a58137 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 3 Mar 2018 10:54:43 -0800 Subject: [PATCH 35/57] aklys tweaks It turns out that Mjollnir before the recent aklys enhancement and aklys since then would end up both wielded and quivered if it returned to thrower's hand while quiver was empty. Remove it from quiver before restoring it to hand. Limit the throwing range of an aklys if it is expected to return (ie, thrown while wielded as primary) since it is a "thonged club" which is supposedly attached by a cord to the thrower's wrist or hand. I have no idea how long a real cord like that might be. I set the range limit to BOLT_LIM/2. Shorter makes throw-and-return uninteresting for an item that needs to be wielded to throw--so would probably be swapped back and forth with a stronger melee weapon or longer range missile weapon--and longer seems absurd. --- src/dothrow.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/dothrow.c b/src/dothrow.c index e57ee4122..0c889cd29 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dothrow.c $NHDT-Date: 1519752483 2018/02/27 17:28:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.131 $ */ +/* NetHack 3.6 dothrow.c $NHDT-Date: 1520103267 2018/03/03 18:54:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.133 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1078,6 +1078,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */ notonhead = FALSE; /* reset potentially stale value */ if ((obj->cursed || obj->greased) && (u.dx || u.dy) && !rn2(7)) { boolean slipok = TRUE; + if (ammo_and_launcher(obj, uwep)) pline("%s!", Tobjnam(obj, "misfire")); else { @@ -1129,6 +1130,8 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */ ceiling(u.ux, u.uy)); obj = addinv(obj); (void) encumber_msg(); + if (obj->owornmask & W_QUIVER) /* in case addinv() autoquivered */ + setuqwep((struct obj *) 0); setuwep(obj); u.twoweap = twoweap; } else if (u.dz < 0) { @@ -1206,6 +1209,10 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */ range = 20; /* you must be giant */ else if (obj->oartifact == ART_MJOLLNIR) range = (range + 1) / 2; /* it's heavy */ + else if (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0) + /* if an aklys is going to return, range is limited by the + length of the attached cord [implicit aspect of item] */ + range = min(range, BOLT_LIM / 2); else if (obj == uball && u.utrap && u.utraptype == TT_INFLOOR) range = 1; @@ -1267,6 +1274,10 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */ pline("%s to your hand!", Tobjnam(obj, "return")); obj = addinv(obj); (void) encumber_msg(); + /* addinv autoquivers an aklys if quiver is empty; + if obj is quivered, remove it before wielding */ + if (obj->owornmask & W_QUIVER) + setuqwep((struct obj *) 0); setuwep(obj); u.twoweap = twoweap; if (cansee(bhitpos.x, bhitpos.y)) From 2111abdc2993f813b4b67f269fbd5baa6d9c1400 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 3 Mar 2018 15:26:49 -0800 Subject: [PATCH 36/57] buried_ball() Noticed when I was looking at float_up()/float_down() vs being trapped. (I have a substantial patch for that but it involves infrastructure changes so will have to go into master instead of the 3.6.0 branch.) buried_ball() was using nested loops as a very convoluted way to test if (otmp->ox >= cc->x - 2 && otmp->ox <= cc->x + 2 && otmp->oy >= cc->y - 2 && otmp->oy <= cc->y + 2) I think this revised version is closer to what was intended. There are issues. buried_ball() finds the buried iron ball nearest to the specified location--which is always the hero's current location-- rather than the one which was 'uball' before being buried. A player can spot that since iron balls aren't necessarily identical. Also, it searches within a radius of two steps but a tethered hero is only allowed to move one step away from buried ball, so something is off. --- src/dig.c | 62 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/src/dig.c b/src/dig.c index 0886ed477..d1a557648 100644 --- a/src/dig.c +++ b/src/dig.c @@ -1714,36 +1714,47 @@ struct obj * buried_ball(cc) coord *cc; { - xchar check_x, check_y; - struct obj *otmp, *otmp2; + int odist, bdist = COLNO; + struct obj *otmp, *ball = 0; - if (u.utraptype == TT_BURIEDBALL) - for (otmp = level.buriedobjlist; otmp; otmp = otmp2) { - otmp2 = otmp->nobj; + /* FIXME: + * This is just approximate; if multiple buried balls meet the + * criterium (within 2 steps of tethered hero's present location) + * it will find an arbitrary one rather than the one which used + * to be uball. Once 3.6.{0,1} save file compatibility is broken, + * we should add context.buriedball_oid and then we can find the + * actual former uball, which might be extra heavy or christened + * or not the one buried directly underneath the target spot. + * + * [Why does this search within a radius of two when trapmove() + * only lets hero get one step away from the buried ball?] + */ + + if (u.utrap && u.utraptype == TT_BURIEDBALL) + for (otmp = level.buriedobjlist; otmp; otmp = otmp->nobj) { if (otmp->otyp != HEAVY_IRON_BALL) continue; - /* try the exact location first */ + /* if found at the target spot, we're done */ if (otmp->ox == cc->x && otmp->oy == cc->y) return otmp; - /* Now try the vicinity */ - /* - * (x-2,y-2) (x+2,y-2) - * (x,y) - * (x-2,y+2) (x+2,y+2) + /* find nearest within allowable vicinity: +/-2 + * 4 5 8 + * 1 2 5 + * 0 1 4 */ - for (check_x = cc->x - 2; check_x <= cc->x + 2; ++check_x) - for (check_y = cc->y - 2; check_y <= cc->y + 2; ++check_y) { - if (check_x == cc->x && check_y == cc->y) - continue; - if (isok(check_x, check_y) - && (otmp->ox == check_x && otmp->oy == check_y)) { - cc->x = check_x; - cc->y = check_y; - return otmp; - } - } + odist = dist2(otmp->ox, otmp->oy, cc->x, cc->y); + if (odist <= 8 && (!ball || odist < bdist)) { + /* remember nearest buried ball but keep checking others */ + ball = otmp; + bdist = odist; + } } - return (struct obj *) 0; + if (ball) { + /* found, but not at < cc->x, cc->y > */ + cc->x = ball->ox; + cc->y = ball->oy; + } + return ball; } void @@ -1751,6 +1762,7 @@ buried_ball_to_punishment() { coord cc; struct obj *ball; + cc.x = u.ux; cc.y = u.uy; ball = buried_ball(&cc); @@ -1774,6 +1786,7 @@ buried_ball_to_freedom() { coord cc; struct obj *ball; + cc.x = u.ux; cc.y = u.uy; ball = buried_ball(&cc); @@ -1913,7 +1926,8 @@ int x, y; for (otmp = level.buriedobjlist; otmp; otmp = otmp2) { otmp2 = otmp->nobj; if (otmp->ox == x && otmp->oy == y) { - if (bball && otmp == bball && u.utraptype == TT_BURIEDBALL) { + if (bball && otmp == bball + && u.utrap && u.utraptype == TT_BURIEDBALL) { buried_ball_to_punishment(); } else { obj_extract_self(otmp); From 4328cf49ef9f779eeab4e8176b8e9ea1f183a3fc Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 3 Mar 2018 16:46:39 -0800 Subject: [PATCH 37/57] fix prayer infinite loop Reported internally, if a prayer resulted in 'fix all troubles' and one of those was TROUBLE_STUCK_IN_WALL but safe_teleds() couldn't find any place to relocate the hero to, nothing was done and STUCK_IN_WALL would be found again as the next trouble to fix. Since safe_teleds() eventually resorts to trying every single spot on the map, there was no other result possible than failing to find an available spot again, nothing would be done, and next trouble would be STUCK_IN_WALL, ad naseum. I started out with a fix that looked for secret corridors to expose and doors to open, to make more space available, then try to move a monster off the level, then try digging out rock and/or walls and smashing boulders. None of those guarantee success and I got bogged down by the digging case. This was going to be a last resort if all of those still failed to make somewhere to move the hero, but for now, at least, I'm skipping all that other stuff and going directly to the last resort: give the hero Passes_walls ability for a short time, and let him or her find own way out of trouble. The next trouble to fix won't be STUCK_IN_WALL because Passes_walls makes that a non-issue. I'm not thrilled with the new messages involved but want to get this behind me. --- doc/fixes36.1 | 2 ++ include/extern.h | 1 + src/pray.c | 57 +++++++++++++++++++++++++++++++++++------------- src/timeout.c | 38 +++++++++++++++++++++++++++++++- 4 files changed, 82 insertions(+), 16 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index c282bdc58..e1c5c4468 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -517,6 +517,8 @@ whatis lookup for 'more info?' would behave strangely for plural names, either you should not hear a whistle if you are deaf change the deity's "congratulations" message upon ascension to something which sounds a bit more archaic to fit better with the other messages +prayer boon of 'fix all troubles' could get stuck in an infinite loop for + TROUBLE_STUCK_IN_WALL if there was no spot to teleport into available Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 4ea4915c4..b6f482515 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1917,6 +1917,7 @@ E const char *NDECL(bottlename); /* ### pray.c ### */ E boolean FDECL(critically_low_hp, (BOOLEAN_P)); +E boolean NDECL(stuck_in_wall); #ifdef USE_TRAMPOLI E int NDECL(prayer_done); #endif diff --git a/src/pray.c b/src/pray.c index ef61df831..29a2bd601 100644 --- a/src/pray.c +++ b/src/pray.c @@ -140,6 +140,31 @@ boolean only_if_injured; /* determines whether maxhp <= 5 matters */ return (boolean) (curhp <= 5 || curhp * divisor <= maxhp); } +/* return True if surrounded by impassible rock, regardless of the state + of your own location (for example, inside a doorless closet) */ +boolean +stuck_in_wall() +{ + int i, j, x, y, count = 0; + + if (Passes_walls) + return FALSE; + for (i = -1; i <= 1; i++) { + x = u.ux + i; + for (j = -1; j <= 1; j++) { + if (!i && !j) + continue; + y = u.uy + j; + if (!isok(x, y) + || (IS_ROCK(levl[x][y].typ) + && (levl[x][y].typ != SDOOR || levl[x][y].typ != SCORR)) + || (blocked_boulder(i, j) && !throws_rocks(youmonst.data))) + ++count; + } + } + return (count == 8) ? TRUE : FALSE; +} + /* * Return 0 if nothing particular seems wrong, positive numbers for * serious trouble, and negative numbers for comparative annoyances. @@ -158,7 +183,7 @@ STATIC_OVL int in_trouble() { struct obj *otmp; - int i, j, count = 0; + int i; /* * major troubles @@ -183,19 +208,8 @@ in_trouble() return TROUBLE_LYCANTHROPE; if (near_capacity() >= EXT_ENCUMBER && AMAX(A_STR) - ABASE(A_STR) > 3) return TROUBLE_COLLAPSING; - - for (i = -1; i <= 1; i++) - for (j = -1; j <= 1; j++) { - if (!i && !j) - continue; - if (!isok(u.ux + i, u.uy + j) - || IS_ROCK(levl[u.ux + i][u.uy + j].typ) - || (blocked_boulder(i, j) && !throws_rocks(youmonst.data))) - count++; - } - if (count == 8 && !Passes_walls) + if (stuck_in_wall()) return TROUBLE_STUCK_IN_WALL; - if (Cursed_obj(uarmf, LEVITATION_BOOTS) || stuck_ring(uleft, RIN_LEVITATION) || stuck_ring(uright, RIN_LEVITATION)) @@ -396,9 +410,22 @@ int trouble; } break; case TROUBLE_STUCK_IN_WALL: - Your("surroundings change."); /* no control, but works on no-teleport levels */ - (void) safe_teleds(FALSE); + if (safe_teleds(FALSE)) { + Your("surroundings change."); + } else { + /* safe_teleds() couldn't find a safe place; perhaps the + level is completely full. As a last resort, confer + intrinsic wall/rock-phazing. Hero might get stuck + again fairly soon.... + Without something like this, fix_all_troubles can get + stuck in an infinite loop trying to fix STUCK_IN_WALL + and repeatedly failing. */ + set_itimeout(&HPasses_walls, (long) d(4, 4)); + /* how else could you move between packed rocks or among + lattice forming "solid" rock? */ + You_feel("much slimmer."); + } break; case TROUBLE_CURSED_LEVITATION: if (Cursed_obj(uarmf, LEVITATION_BOOTS)) { diff --git a/src/timeout.c b/src/timeout.c index b8535bbd5..86e01ae5f 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -275,6 +275,7 @@ levitation_dialogue() if (((HLevitation & TIMEOUT) % 2L) && i > 0L && i <= SIZE(levi_texts)) { const char *s = levi_texts[SIZE(levi_texts) - i]; + if (index(s, '%')) { boolean danger = (is_pool_or_lava(u.ux, u.uy) && !Is_waterlevel(&u.uz)); @@ -336,6 +337,30 @@ burn_away_slime() } } +/* Intrinsic Passes_walls is temporary when your god is trying to fix + all troubles and then TROUBLE_STUCK_IN_WALL calls safe_teleds() but + it can't find anywhere to place you. If that happens you get a small + value for (HPasses_walls & TIMEOUT) to move somewhere yourself. + Message given is "you feel much slimmer" as a joke hint that you can + move between things which are closely packed--like the substance of + solid rock! */ +static NEARDATA const char *const phaze_texts[] = { + "You start to feel bloated.", + "You are feeling rather flabby.", +}; + +STATIC_OVL void +phaze_dialogue() +{ + long i = ((HPasses_walls & TIMEOUT) / 2L); + + if (EPasses_walls || (HPasses_walls & ~TIMEOUT)) + return; + + if (((HPasses_walls & TIMEOUT) % 2L) && i > 0L && i <= SIZE(phaze_texts)) + pline1(phaze_texts[SIZE(phaze_texts) - i]); +} + void nh_timeout() { @@ -373,8 +398,10 @@ nh_timeout() vomiting_dialogue(); if (Strangled) choke_dialogue(); - if (Levitation) + if (HLevitation & TIMEOUT) levitation_dialogue(); + if (HPasses_walls & TIMEOUT) + phaze_dialogue(); if (u.mtimedone && !--u.mtimedone) { if (Unchanging) u.mtimedone = rnd(100 * youmonst.data->mlevel + 1); @@ -526,6 +553,15 @@ nh_timeout() case LEVITATION: (void) float_down(I_SPECIAL | TIMEOUT, 0L); break; + case PASSES_WALLS: + if (!Passes_walls) { + if (stuck_in_wall()) + You_feel("hemmed in again."); + else + pline("You're back to your %s self again.", + !Upolyd ? "normal" : "unusual"); + } + break; case STRANGLED: killer.format = KILLED_BY; Strcpy(killer.name, From eddfcc44228f9f129027fa557966a8962dfbe66c Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Mar 2018 09:07:16 -0500 Subject: [PATCH 38/57] windows cmdline Makefile --- sys/winnt/Makefile.msc | 29 +++++++++++++++++++++-------- win/win32/dgnstuff.mak | 29 ++++++++++++++++++++++++----- win/win32/levstuff.mak | 34 +++++++++++++++++++++++++++------- 3 files changed, 72 insertions(+), 20 deletions(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 588a393b2..55e6f45c8 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -569,7 +569,7 @@ default : install all : install -install: envchk $(O)obj.tag $(O)utility.tag $(GAMEDIR)\NetHack.exe $(GAMEDIR)\NetHackW.exe $(O)install.tag +install: $(O)envchk.tag $(O)obj.tag $(O)utility.tag $(GAMEDIR)\NetHack.exe $(GAMEDIR)\NetHackW.exe $(O)install.tag @echo Done. $(O)install.tag: $(DAT)\data $(DAT)\rumors $(DAT)\dungeon \ @@ -913,14 +913,19 @@ $(MSWIN)\splash.bmp: $(U)uudecode.exe $(MSWIN)\splash.uu # defer to the steps in ..\win\win32\levstuff.mak # -$(U)lev_yacc.c $(INCL)\lev_comp.h: $(U)lev_comp.y - nmake -nologo -f ..\win\win32\levstuff.mak default +$(U)lev_yacc.c: + nmake -nologo -f ..\win\win32\levstuff.mak $(U)lev_yacc.c + +$(U)lev_lex.c: + nmake -nologo -f ..\win\win32\levstuff.mak $(U)lev_lex.c + +$(INCL)\lev_comp.h: + nmake -nologo -f ..\win\win32\levstuff.mak $(INCL)\lev_comp.h $(O)lev_yacc.o: $(HACK_H) $(SP_LEV_H) $(INCL)\lev_comp.h $(U)lev_yacc.c @$(cc) $(cflagsBuild) -Fo$@ $(U)lev_yacc.c -$(O)lev_lex.o: $(HACK_H) $(INCL)\lev_comp.h $(SP_LEV_H) \ - $(U)lev_lex.c +$(O)lev_lex.o: $(HACK_H) $(INCL)\lev_comp.h $(SP_LEV_H) $(U)lev_lex.c @$(cc) $(cflagsBuild) -Fo$@ $(U)lev_lex.c $(O)lev_main.o: $(U)lev_main.c $(HACK_H) $(SP_LEV_H) @@ -939,8 +944,14 @@ $(U)levcomp.exe: $(LEVCOMPOBJS) # # defer to the steps in ..\win\win32\dgnstuff.mak # -$(U)dgn_yacc.c $(INCL)\dgn_comp.h : $(U)dgn_comp.y - nmake -nologo -f ..\win\win32\dgnstuff.mak default +$(U)dgn_yacc.c: + nmake -nologo -f ..\win\win32\dgnstuff.mak $(U)dgn_yacc.c + +$(INCL)\dgn_comp.h: + nmake -nologo -f ..\win\win32\dgnstuff.mak $(INCL)\dgn_comp.h + +$(U)dgn_lex.c: + nmake -nologo -f ..\win\win32\dgnstuff.mak $(U)dgn_lex.c $(O)dgn_yacc.o: $(HACK_H) $(DGN_FILE_H) $(INCL)\dgn_comp.h $(U)dgn_yacc.c @$(cc) $(cflagsBuild) -Fo$@ $(U)dgn_yacc.c @@ -974,7 +985,7 @@ $(O)obj.tag: # options. #========================================== -envchk: +$(O)envchk.tag: ! IF "$(TARGET_CPU)"=="x64" @echo Windows x64 64-bit target build ! ELSE @@ -984,6 +995,7 @@ envchk: # @echo Warning, the CL Environment variable is defined: # @echo CL=$(CL) ! ENDIF + echo envchk >$@ #========================================== #=========== SECONDARY TARGETS ============ @@ -1262,6 +1274,7 @@ clean: if exist $(O)nhraykey.lib del $(O)nhraykey.lib if exist $(O)nhraykey.map del $(O)nhraykey.map if exist $(O)nhraykey.PDB del $(O)nhraykey.PDB + if exist $(O)envchk.tag del $(O)envchk.tag if exist $(O)obj.tag del $(O)obj.tag if exist $(O)sp_lev.tag del $(O)sp_lev.tag if exist $(O)uudecode.MAP del $(O)uudecode.MAP diff --git a/win/win32/dgnstuff.mak b/win/win32/dgnstuff.mak index 9196c5c53..7420960a1 100644 --- a/win/win32/dgnstuff.mak +++ b/win/win32/dgnstuff.mak @@ -41,11 +41,28 @@ tools: # Dungeon Compiler Stuff #========================================== -..\util\dgn_yacc.c ..\include\dgn_comp.h : ..\util\dgn_comp.y +..\include\dgn_comp.h : ..\util\dgn_comp.y !IF "$(YACC)"=="" - @echo Using pre-built dgn_yacc.c and dgn_comp.h - @copy ..\sys\share\dgn_yacc.c ..\util\dgn_yacc.c - @copy ..\sys\share\dgn_comp.h ..\include\dgn_comp.h + @echo Using pre-built dgn_comp.h + chdir ..\include + copy /b ..\sys\share\dgn_comp.h +,, + chdir ..\src +!ELSE + chdir ..\util + $(YACC) -d dgn_comp.y + copy $(YTABC) $@ + copy $(YTABH) ..\include\dgn_comp.h + @del $(YTABC) + @del $(YTABH) + chdir ..\build +!ENDIF + +..\util\dgn_yacc.c : ..\util\dgn_comp.y +!IF "$(YACC)"=="" + @echo Using pre-built dgn_yacc.c + chdir ..\util + copy /b ..\sys\share\dgn_yacc.c +,, + chdir ..\src !ELSE chdir ..\util $(YACC) -d dgn_comp.y @@ -59,7 +76,9 @@ tools: ..\util\dgn_lex.c: ..\util\dgn_comp.l !IF "$(LEX)"=="" @echo Using pre-built dgn_lex.c - @copy ..\sys\share\dgn_lex.c $@ + chdir ..\util + copy /b ..\sys\share\dgn_lex.c +,, + chdir ..\src !ELSE chdir ..\util $(LEX) dgn_comp.l diff --git a/win/win32/levstuff.mak b/win/win32/levstuff.mak index 1e92cd69e..e36986d99 100644 --- a/win/win32/levstuff.mak +++ b/win/win32/levstuff.mak @@ -40,11 +40,12 @@ tools: # Level Compiler Stuff #========================================== -..\util\lev_yacc.c ..\include\lev_comp.h: ..\util\lev_comp.y +..\include\lev_comp.h: ..\util\lev_comp.y !IFNDEF YACC - @echo Using pre-built lev_yacc.c and lev_comp.h - @copy ..\sys\share\lev_yacc.c ..\util\lev_yacc.c - @copy ..\sys\share\lev_comp.h ..\include\lev_comp.h + @echo Using pre-built lev_comp.h + chdir ..\include + copy /b ..\sys\share\lev_comp.h +,, + chdir ..\src !ELSE @echo Generating lev_yacc.c and lev_comp.h chdir ..\util @@ -53,19 +54,38 @@ tools: copy $(YTABH) ..\include\lev_comp.h @del $(YTABC) @del $(YTABH) - chdir ..\build + chdir ..\src +!ENDIF + +..\util\lev_yacc.c: ..\util\lev_comp.y +!IFNDEF YACC + @echo Using pre-built lev_yacc.c + chdir ..\util + copy /b ..\sys\share\lev_yacc.c +,, + chdir ..\src +!ELSE + @echo Generating lev_yacc.c and lev_comp.h + chdir ..\util + $(YACC) -d lev_comp.y + copy $(YTABC) $@ + copy $(YTABH) ..\include\lev_comp.h + @del $(YTABC) + @del $(YTABH) + chdir ..\src !ENDIF ..\util\lev_lex.c: ..\util\lev_comp.l !IFNDEF LEX @echo Using pre-built lev_lex.c - @copy ..\sys\share\lev_lex.c $@ + chdir ..\util + copy /b ..\sys\share\lev_lex.c +,, + chdir ..\src !ELSE @echo Generating lev_lex.c chdir ..\util $(LEX) lev_comp.l copy $(LEXYYC) $@ @del $(LEXYYC) - chdir ..\build + chdir ..\src !ENDIF From 777317224b2f167d82a0469611dcacec85e95599 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Mar 2018 09:11:01 -0500 Subject: [PATCH 39/57] windows cmdline dependency bit --- sys/winnt/Makefile.msc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 55e6f45c8..c843dfc1d 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -1,4 +1,4 @@ -# NetHack 3.6 Makefile.msc $NHDT-Date: 1518220654 2018/02/09 23:57:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.105 $ */ +# NetHack 3.6 Makefile.msc $NHDT-Date: 1520172650 2018/03/04 14:10:50 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.107 $ */ # Copyright (c) NetHack PC Development Team 1993-2018 # #============================================================================== @@ -985,7 +985,7 @@ $(O)obj.tag: # options. #========================================== -$(O)envchk.tag: +$(O)envchk.tag: $(O)obj.tag ! IF "$(TARGET_CPU)"=="x64" @echo Windows x64 64-bit target build ! ELSE @@ -1274,7 +1274,7 @@ clean: if exist $(O)nhraykey.lib del $(O)nhraykey.lib if exist $(O)nhraykey.map del $(O)nhraykey.map if exist $(O)nhraykey.PDB del $(O)nhraykey.PDB - if exist $(O)envchk.tag del $(O)envchk.tag + if exist $(O)envchk.tag del $(O)envchk.tag if exist $(O)obj.tag del $(O)obj.tag if exist $(O)sp_lev.tag del $(O)sp_lev.tag if exist $(O)uudecode.MAP del $(O)uudecode.MAP From 939bd356a4aff13fec5711596ddc101a8f0434cc Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Mar 2018 09:54:29 -0500 Subject: [PATCH 40/57] more msc makefile tweaks --- sys/winnt/Makefile.msc | 131 +++++++++++++++++++++-------------------- win/win32/dgnstuff.mak | 9 ++- win/win32/levstuff.mak | 9 ++- 3 files changed, 79 insertions(+), 70 deletions(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index c843dfc1d..0d414da1e 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -1,4 +1,4 @@ -# NetHack 3.6 Makefile.msc $NHDT-Date: 1520172650 2018/03/04 14:10:50 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.107 $ */ +# NetHack 3.6 Makefile.msc $NHDT-Date: 1520175248 2018/03/04 14:54:08 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.108 $ */ # Copyright (c) NetHack PC Development Team 1993-2018 # #============================================================================== @@ -913,10 +913,10 @@ $(MSWIN)\splash.bmp: $(U)uudecode.exe $(MSWIN)\splash.uu # defer to the steps in ..\win\win32\levstuff.mak # -$(U)lev_yacc.c: +$(U)lev_yacc.c: $(U)lev_comp.y nmake -nologo -f ..\win\win32\levstuff.mak $(U)lev_yacc.c -$(U)lev_lex.c: +$(U)lev_lex.c: $(U)lev_comp.l nmake -nologo -f ..\win\win32\levstuff.mak $(U)lev_lex.c $(INCL)\lev_comp.h: @@ -944,13 +944,13 @@ $(U)levcomp.exe: $(LEVCOMPOBJS) # # defer to the steps in ..\win\win32\dgnstuff.mak # -$(U)dgn_yacc.c: +$(U)dgn_yacc.c: $(U)dgn_comp.y nmake -nologo -f ..\win\win32\dgnstuff.mak $(U)dgn_yacc.c $(INCL)\dgn_comp.h: nmake -nologo -f ..\win\win32\dgnstuff.mak $(INCL)\dgn_comp.h -$(U)dgn_lex.c: +$(U)dgn_lex.c: $(U)dgn_comp.l nmake -nologo -f ..\win\win32\dgnstuff.mak $(U)dgn_lex.c $(O)dgn_yacc.o: $(HACK_H) $(DGN_FILE_H) $(INCL)\dgn_comp.h $(U)dgn_yacc.c @@ -1182,63 +1182,67 @@ spotless: clean if exist $(GAMEDIR)\NetHack.pdb del $(GAMEDIR)\NetHack.pdb if exist $(GAMEDIR)\nhdat del $(GAMEDIR)\nhdat ! ENDIF - if exist $(INCL)\date.h del $(INCL)\date.h - if exist $(INCL)\onames.h del $(INCL)\onames.h - if exist $(INCL)\pm.h del $(INCL)\pm.h - if exist $(INCL)\vis_tab.h del $(INCL)\vis_tab.h - if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c - if exist $(SRC)\tile.c del $(SRC)\tile.c - if exist $(U)*.lnk del $(U)*.lnk - if exist $(U)*.map del $(U)*.map - if exist $(DAT)\data del $(DAT)\data - if exist $(DAT)\rumors del $(DAT)\rumors - if exist $(DAT)\engrave del $(DAT)\engrave - if exist $(DAT)\epitaph del $(DAT)\epitaph - if exist $(DAT)\bogusmon del $(DAT)\bogusmon - if exist $(DAT)\???-fil?.lev del $(DAT)\???-fil?.lev - if exist $(DAT)\???-goal.lev del $(DAT)\???-goal.lev - if exist $(DAT)\???-loca.lev del $(DAT)\???-loca.lev - if exist $(DAT)\???-strt.lev del $(DAT)\???-strt.lev - if exist $(DAT)\air.lev del $(DAT)\air.lev - if exist $(DAT)\asmodeus.lev del $(DAT)\asmodeus.lev - if exist $(DAT)\astral.lev del $(DAT)\astral.lev - if exist $(DAT)\baalz.lev del $(DAT)\baalz.lev - if exist $(DAT)\bigrm-*.lev del $(DAT)\bigrm-*.lev - if exist $(DAT)\castle.lev del $(DAT)\castle.lev - if exist $(DAT)\data del $(DAT)\data - if exist $(DAT)\dungeon del $(DAT)\dungeon - if exist $(DAT)\dungeon.pdf del $(DAT)\dungeon.pdf - if exist $(DAT)\earth.lev del $(DAT)\earth.lev - if exist $(DAT)\fakewiz?.lev del $(DAT)\fakewiz?.lev - if exist $(DAT)\fire.lev del $(DAT)\fire.lev - if exist $(DAT)\juiblex.lev del $(DAT)\juiblex.lev - if exist $(DAT)\knox.lev del $(DAT)\knox.lev - if exist $(DAT)\medusa-?.lev del $(DAT)\medusa-?.lev - if exist $(DAT)\mine*.lev del $(DAT)\mine*.lev - if exist $(DAT)\options del $(DAT)\options - if exist $(DAT)\ttyoptions del $(DAT)\ttyoptions - if exist $(DAT)\guioptions del $(DAT)\guioptions - if exist $(DAT)\oracle.lev del $(DAT)\oracle.lev - if exist $(DAT)\oracles del $(DAT)\oracles - if exist $(DAT)\orcus.lev del $(DAT)\orcus.lev - if exist $(DAT)\rumors del $(DAT)\rumors - if exist $(DAT)\quest.dat del $(DAT)\quest.dat - if exist $(DAT)\sanctum.lev del $(DAT)\sanctum.lev - if exist $(DAT)\soko?-?.lev del $(DAT)\soko?-?.lev - if exist $(DAT)\tower?.lev del $(DAT)\tower?.lev - if exist $(DAT)\valley.lev del $(DAT)\valley.lev - if exist $(DAT)\water.lev del $(DAT)\water.lev - if exist $(DAT)\wizard?.lev del $(DAT)\wizard?.lev - if exist $(DAT)\dlb.lst del $(DAT)\dlb.lst - if exist $(O)sp_lev.tag del $(O)sp_lev.tag - if exist $(SRC)\monstr.c del $(SRC)\monstr.c - if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c - if exist $(U)recover.exe del $(U)recover.exe - if exist nhdat. del nhdat. - if exist $(O)obj.tag del $(O)obj.tag - if exist $(O)gamedir.tag del $(O)gamedir.tag - if exist $(O)nh*key.lib del $(O)nh*key.lib - if exist $(O)nh*key.exp del $(O)nh*key.exp + if exist $(INCL)\date.h del $(INCL)\date.h + if exist $(INCL)\onames.h del $(INCL)\onames.h + if exist $(INCL)\pm.h del $(INCL)\pm.h + if exist $(INCL)\vis_tab.h del $(INCL)\vis_tab.h + if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c + if exist $(SRC)\tile.c del $(SRC)\tile.c + if exist $(U)*.lnk del $(U)*.lnk + if exist $(U)*.map del $(U)*.map + if exist $(DAT)\data del $(DAT)\data + if exist $(DAT)\rumors del $(DAT)\rumors + if exist $(DAT)\engrave del $(DAT)\engrave + if exist $(DAT)\epitaph del $(DAT)\epitaph + if exist $(DAT)\bogusmon del $(DAT)\bogusmon + if exist $(DAT)\???-fil?.lev del $(DAT)\???-fil?.lev + if exist $(DAT)\???-goal.lev del $(DAT)\???-goal.lev + if exist $(DAT)\???-loca.lev del $(DAT)\???-loca.lev + if exist $(DAT)\???-strt.lev del $(DAT)\???-strt.lev + if exist $(DAT)\air.lev del $(DAT)\air.lev + if exist $(DAT)\asmodeus.lev del $(DAT)\asmodeus.lev + if exist $(DAT)\astral.lev del $(DAT)\astral.lev + if exist $(DAT)\baalz.lev del $(DAT)\baalz.lev + if exist $(DAT)\bigrm-*.lev del $(DAT)\bigrm-*.lev + if exist $(DAT)\castle.lev del $(DAT)\castle.lev + if exist $(DAT)\data del $(DAT)\data + if exist $(DAT)\dungeon del $(DAT)\dungeon + if exist $(DAT)\dungeon.pdf del $(DAT)\dungeon.pdf + if exist $(DAT)\earth.lev del $(DAT)\earth.lev + if exist $(DAT)\fakewiz?.lev del $(DAT)\fakewiz?.lev + if exist $(DAT)\fire.lev del $(DAT)\fire.lev + if exist $(DAT)\juiblex.lev del $(DAT)\juiblex.lev + if exist $(DAT)\knox.lev del $(DAT)\knox.lev + if exist $(DAT)\medusa-?.lev del $(DAT)\medusa-?.lev + if exist $(DAT)\mine*.lev del $(DAT)\mine*.lev + if exist $(DAT)\options del $(DAT)\options + if exist $(DAT)\ttyoptions del $(DAT)\ttyoptions + if exist $(DAT)\guioptions del $(DAT)\guioptions + if exist $(DAT)\oracle.lev del $(DAT)\oracle.lev + if exist $(DAT)\oracles del $(DAT)\oracles + if exist $(DAT)\orcus.lev del $(DAT)\orcus.lev + if exist $(DAT)\rumors del $(DAT)\rumors + if exist $(DAT)\quest.dat del $(DAT)\quest.dat + if exist $(DAT)\sanctum.lev del $(DAT)\sanctum.lev + if exist $(DAT)\soko?-?.lev del $(DAT)\soko?-?.lev + if exist $(DAT)\tower?.lev del $(DAT)\tower?.lev + if exist $(DAT)\valley.lev del $(DAT)\valley.lev + if exist $(DAT)\water.lev del $(DAT)\water.lev + if exist $(DAT)\wizard?.lev del $(DAT)\wizard?.lev + if exist $(DAT)\dlb.lst del $(DAT)\dlb.lst + if exist $(O)sp_lev.tag del $(O)sp_lev.tag + if exist $(SRC)\monstr.c del $(SRC)\monstr.c + if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c + if exist nhdat. del nhdat. + if exist $(O)obj.tag del $(O)obj.tag + if exist $(O)gamedir.tag del $(O)gamedir.tag + if exist $(O)nh*key.lib del $(O)nh*key.lib + if exist $(O)nh*key.exp del $(O)nh*key.exp + if exist $(U)recover.exe del $(U)recover.exe + if exist $(U)tile2bmp.exe del $(U)tile2bmp.exe + if exist $(U)tilemap.exe del $(U)tilemap.exe + if exist $(U)uudecode.exe del $(U)uudecode.exe + if exist $(U)dlb_main.exe del $(U)dlb_main.exe clean: if exist $(O)*.o del $(O)*.o if exist $(O)utility.tag del $(O)utility.tag @@ -1286,8 +1290,7 @@ clean: rem rem defer to the steps in ..\win\win32\dgnstuff.mak rem - nmake -nologo -f ..\win\win32\dgnstuff.mak clean - + nmake -nologo -f ..\win\win32\dgnstuff.mak clean if exist $(TILEBMP16) del $(TILEBMP16) if exist $(TILEBMP32) del $(TILEBMP32) diff --git a/win/win32/dgnstuff.mak b/win/win32/dgnstuff.mak index 7420960a1..0965501fe 100644 --- a/win/win32/dgnstuff.mak +++ b/win/win32/dgnstuff.mak @@ -45,7 +45,8 @@ tools: !IF "$(YACC)"=="" @echo Using pre-built dgn_comp.h chdir ..\include - copy /b ..\sys\share\dgn_comp.h +,, + copy /y ..\sys\share\dgn_comp.h + copy /b dgn_comp.h+,, chdir ..\src !ELSE chdir ..\util @@ -61,7 +62,8 @@ tools: !IF "$(YACC)"=="" @echo Using pre-built dgn_yacc.c chdir ..\util - copy /b ..\sys\share\dgn_yacc.c +,, + copy /y ..\sys\share\dgn_yacc.c + copy /b dgn_yacc.c+,, chdir ..\src !ELSE chdir ..\util @@ -77,7 +79,8 @@ tools: !IF "$(LEX)"=="" @echo Using pre-built dgn_lex.c chdir ..\util - copy /b ..\sys\share\dgn_lex.c +,, + copy /y ..\sys\share\dgn_lex.c + copy /b dgn_lex.c+,, chdir ..\src !ELSE chdir ..\util diff --git a/win/win32/levstuff.mak b/win/win32/levstuff.mak index e36986d99..2072c2cc0 100644 --- a/win/win32/levstuff.mak +++ b/win/win32/levstuff.mak @@ -44,7 +44,8 @@ tools: !IFNDEF YACC @echo Using pre-built lev_comp.h chdir ..\include - copy /b ..\sys\share\lev_comp.h +,, + copy /y ..\sys\share\lev_comp.h + copy /b lev_comp.h+,, chdir ..\src !ELSE @echo Generating lev_yacc.c and lev_comp.h @@ -61,7 +62,8 @@ tools: !IFNDEF YACC @echo Using pre-built lev_yacc.c chdir ..\util - copy /b ..\sys\share\lev_yacc.c +,, + copy /y ..\sys\share\lev_yacc.c + copy /b lev_yacc.c+,, chdir ..\src !ELSE @echo Generating lev_yacc.c and lev_comp.h @@ -78,7 +80,8 @@ tools: !IFNDEF LEX @echo Using pre-built lev_lex.c chdir ..\util - copy /b ..\sys\share\lev_lex.c +,, + copy /y ..\sys\share\lev_lex.c + copy /b lev_lex.c+,, chdir ..\src !ELSE @echo Generating lev_lex.c From 12562694a90b2d8ca296f99f3a1a9b8185f1afb3 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Mar 2018 10:09:35 -0500 Subject: [PATCH 41/57] update nmake spotless for windows --- sys/winnt/Makefile.msc | 135 ++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 69 deletions(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 0d414da1e..7d2c103ae 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -1,4 +1,4 @@ -# NetHack 3.6 Makefile.msc $NHDT-Date: 1520175248 2018/03/04 14:54:08 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.108 $ */ +# NetHack 3.6 Makefile.msc $NHDT-Date: 1520176171 2018/03/04 15:09:31 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.109 $ */ # Copyright (c) NetHack PC Development Team 1993-2018 # #============================================================================== @@ -913,10 +913,10 @@ $(MSWIN)\splash.bmp: $(U)uudecode.exe $(MSWIN)\splash.uu # defer to the steps in ..\win\win32\levstuff.mak # -$(U)lev_yacc.c: $(U)lev_comp.y +$(U)lev_yacc.c: nmake -nologo -f ..\win\win32\levstuff.mak $(U)lev_yacc.c -$(U)lev_lex.c: $(U)lev_comp.l +$(U)lev_lex.c: nmake -nologo -f ..\win\win32\levstuff.mak $(U)lev_lex.c $(INCL)\lev_comp.h: @@ -944,13 +944,13 @@ $(U)levcomp.exe: $(LEVCOMPOBJS) # # defer to the steps in ..\win\win32\dgnstuff.mak # -$(U)dgn_yacc.c: $(U)dgn_comp.y +$(U)dgn_yacc.c: nmake -nologo -f ..\win\win32\dgnstuff.mak $(U)dgn_yacc.c $(INCL)\dgn_comp.h: nmake -nologo -f ..\win\win32\dgnstuff.mak $(INCL)\dgn_comp.h -$(U)dgn_lex.c: $(U)dgn_comp.l +$(U)dgn_lex.c: nmake -nologo -f ..\win\win32\dgnstuff.mak $(U)dgn_lex.c $(O)dgn_yacc.o: $(HACK_H) $(DGN_FILE_H) $(INCL)\dgn_comp.h $(U)dgn_yacc.c @@ -985,7 +985,7 @@ $(O)obj.tag: # options. #========================================== -$(O)envchk.tag: $(O)obj.tag +$(O)envchk.tag: ! IF "$(TARGET_CPU)"=="x64" @echo Windows x64 64-bit target build ! ELSE @@ -1182,67 +1182,63 @@ spotless: clean if exist $(GAMEDIR)\NetHack.pdb del $(GAMEDIR)\NetHack.pdb if exist $(GAMEDIR)\nhdat del $(GAMEDIR)\nhdat ! ENDIF - if exist $(INCL)\date.h del $(INCL)\date.h - if exist $(INCL)\onames.h del $(INCL)\onames.h - if exist $(INCL)\pm.h del $(INCL)\pm.h - if exist $(INCL)\vis_tab.h del $(INCL)\vis_tab.h - if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c - if exist $(SRC)\tile.c del $(SRC)\tile.c - if exist $(U)*.lnk del $(U)*.lnk - if exist $(U)*.map del $(U)*.map - if exist $(DAT)\data del $(DAT)\data - if exist $(DAT)\rumors del $(DAT)\rumors - if exist $(DAT)\engrave del $(DAT)\engrave - if exist $(DAT)\epitaph del $(DAT)\epitaph - if exist $(DAT)\bogusmon del $(DAT)\bogusmon - if exist $(DAT)\???-fil?.lev del $(DAT)\???-fil?.lev - if exist $(DAT)\???-goal.lev del $(DAT)\???-goal.lev - if exist $(DAT)\???-loca.lev del $(DAT)\???-loca.lev - if exist $(DAT)\???-strt.lev del $(DAT)\???-strt.lev - if exist $(DAT)\air.lev del $(DAT)\air.lev - if exist $(DAT)\asmodeus.lev del $(DAT)\asmodeus.lev - if exist $(DAT)\astral.lev del $(DAT)\astral.lev - if exist $(DAT)\baalz.lev del $(DAT)\baalz.lev - if exist $(DAT)\bigrm-*.lev del $(DAT)\bigrm-*.lev - if exist $(DAT)\castle.lev del $(DAT)\castle.lev - if exist $(DAT)\data del $(DAT)\data - if exist $(DAT)\dungeon del $(DAT)\dungeon - if exist $(DAT)\dungeon.pdf del $(DAT)\dungeon.pdf - if exist $(DAT)\earth.lev del $(DAT)\earth.lev - if exist $(DAT)\fakewiz?.lev del $(DAT)\fakewiz?.lev - if exist $(DAT)\fire.lev del $(DAT)\fire.lev - if exist $(DAT)\juiblex.lev del $(DAT)\juiblex.lev - if exist $(DAT)\knox.lev del $(DAT)\knox.lev - if exist $(DAT)\medusa-?.lev del $(DAT)\medusa-?.lev - if exist $(DAT)\mine*.lev del $(DAT)\mine*.lev - if exist $(DAT)\options del $(DAT)\options - if exist $(DAT)\ttyoptions del $(DAT)\ttyoptions - if exist $(DAT)\guioptions del $(DAT)\guioptions - if exist $(DAT)\oracle.lev del $(DAT)\oracle.lev - if exist $(DAT)\oracles del $(DAT)\oracles - if exist $(DAT)\orcus.lev del $(DAT)\orcus.lev - if exist $(DAT)\rumors del $(DAT)\rumors - if exist $(DAT)\quest.dat del $(DAT)\quest.dat - if exist $(DAT)\sanctum.lev del $(DAT)\sanctum.lev - if exist $(DAT)\soko?-?.lev del $(DAT)\soko?-?.lev - if exist $(DAT)\tower?.lev del $(DAT)\tower?.lev - if exist $(DAT)\valley.lev del $(DAT)\valley.lev - if exist $(DAT)\water.lev del $(DAT)\water.lev - if exist $(DAT)\wizard?.lev del $(DAT)\wizard?.lev - if exist $(DAT)\dlb.lst del $(DAT)\dlb.lst - if exist $(O)sp_lev.tag del $(O)sp_lev.tag - if exist $(SRC)\monstr.c del $(SRC)\monstr.c - if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c - if exist nhdat. del nhdat. - if exist $(O)obj.tag del $(O)obj.tag - if exist $(O)gamedir.tag del $(O)gamedir.tag - if exist $(O)nh*key.lib del $(O)nh*key.lib - if exist $(O)nh*key.exp del $(O)nh*key.exp - if exist $(U)recover.exe del $(U)recover.exe - if exist $(U)tile2bmp.exe del $(U)tile2bmp.exe - if exist $(U)tilemap.exe del $(U)tilemap.exe - if exist $(U)uudecode.exe del $(U)uudecode.exe - if exist $(U)dlb_main.exe del $(U)dlb_main.exe + if exist $(INCL)\date.h del $(INCL)\date.h + if exist $(INCL)\onames.h del $(INCL)\onames.h + if exist $(INCL)\pm.h del $(INCL)\pm.h + if exist $(INCL)\vis_tab.h del $(INCL)\vis_tab.h + if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c + if exist $(SRC)\tile.c del $(SRC)\tile.c + if exist $(U)*.lnk del $(U)*.lnk + if exist $(U)*.map del $(U)*.map + if exist $(DAT)\data del $(DAT)\data + if exist $(DAT)\rumors del $(DAT)\rumors + if exist $(DAT)\engrave del $(DAT)\engrave + if exist $(DAT)\epitaph del $(DAT)\epitaph + if exist $(DAT)\bogusmon del $(DAT)\bogusmon + if exist $(DAT)\???-fil?.lev del $(DAT)\???-fil?.lev + if exist $(DAT)\???-goal.lev del $(DAT)\???-goal.lev + if exist $(DAT)\???-loca.lev del $(DAT)\???-loca.lev + if exist $(DAT)\???-strt.lev del $(DAT)\???-strt.lev + if exist $(DAT)\air.lev del $(DAT)\air.lev + if exist $(DAT)\asmodeus.lev del $(DAT)\asmodeus.lev + if exist $(DAT)\astral.lev del $(DAT)\astral.lev + if exist $(DAT)\baalz.lev del $(DAT)\baalz.lev + if exist $(DAT)\bigrm-*.lev del $(DAT)\bigrm-*.lev + if exist $(DAT)\castle.lev del $(DAT)\castle.lev + if exist $(DAT)\data del $(DAT)\data + if exist $(DAT)\dungeon del $(DAT)\dungeon + if exist $(DAT)\dungeon.pdf del $(DAT)\dungeon.pdf + if exist $(DAT)\earth.lev del $(DAT)\earth.lev + if exist $(DAT)\fakewiz?.lev del $(DAT)\fakewiz?.lev + if exist $(DAT)\fire.lev del $(DAT)\fire.lev + if exist $(DAT)\juiblex.lev del $(DAT)\juiblex.lev + if exist $(DAT)\knox.lev del $(DAT)\knox.lev + if exist $(DAT)\medusa-?.lev del $(DAT)\medusa-?.lev + if exist $(DAT)\mine*.lev del $(DAT)\mine*.lev + if exist $(DAT)\options del $(DAT)\options + if exist $(DAT)\ttyoptions del $(DAT)\ttyoptions + if exist $(DAT)\guioptions del $(DAT)\guioptions + if exist $(DAT)\oracle.lev del $(DAT)\oracle.lev + if exist $(DAT)\oracles del $(DAT)\oracles + if exist $(DAT)\orcus.lev del $(DAT)\orcus.lev + if exist $(DAT)\rumors del $(DAT)\rumors + if exist $(DAT)\quest.dat del $(DAT)\quest.dat + if exist $(DAT)\sanctum.lev del $(DAT)\sanctum.lev + if exist $(DAT)\soko?-?.lev del $(DAT)\soko?-?.lev + if exist $(DAT)\tower?.lev del $(DAT)\tower?.lev + if exist $(DAT)\valley.lev del $(DAT)\valley.lev + if exist $(DAT)\water.lev del $(DAT)\water.lev + if exist $(DAT)\wizard?.lev del $(DAT)\wizard?.lev + if exist $(DAT)\dlb.lst del $(DAT)\dlb.lst + if exist $(O)sp_lev.tag del $(O)sp_lev.tag + if exist $(SRC)\monstr.c del $(SRC)\monstr.c + if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c + if exist $(U)recover.exe del $(U)recover.exe + if exist nhdat. del nhdat. + if exist $(O)obj.tag del $(O)obj.tag + if exist $(O)gamedir.tag del $(O)gamedir.tag + if exist $(O)nh*key.lib del $(O)nh*key.lib + if exist $(O)nh*key.exp del $(O)nh*key.exp clean: if exist $(O)*.o del $(O)*.o if exist $(O)utility.tag del $(O)utility.tag @@ -1278,7 +1274,7 @@ clean: if exist $(O)nhraykey.lib del $(O)nhraykey.lib if exist $(O)nhraykey.map del $(O)nhraykey.map if exist $(O)nhraykey.PDB del $(O)nhraykey.PDB - if exist $(O)envchk.tag del $(O)envchk.tag + if exist $(O)envchk.tag del $(O)envchk.tag if exist $(O)obj.tag del $(O)obj.tag if exist $(O)sp_lev.tag del $(O)sp_lev.tag if exist $(O)uudecode.MAP del $(O)uudecode.MAP @@ -1290,7 +1286,8 @@ clean: rem rem defer to the steps in ..\win\win32\dgnstuff.mak rem - nmake -nologo -f ..\win\win32\dgnstuff.mak clean + nmake -nologo -f ..\win\win32\dgnstuff.mak clean + if exist $(TILEBMP16) del $(TILEBMP16) if exist $(TILEBMP32) del $(TILEBMP32) From dee2fea82d94f0d6ee6911433df559ec42a7505c Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Mar 2018 10:25:11 -0500 Subject: [PATCH 42/57] msc Makefile --- sys/winnt/Makefile.msc | 133 +++++++++++++++++++++-------------------- win/win32/dgnstuff.mak | 9 +-- win/win32/levstuff.mak | 9 +-- 3 files changed, 74 insertions(+), 77 deletions(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 7d2c103ae..1e5dd7183 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -1,4 +1,4 @@ -# NetHack 3.6 Makefile.msc $NHDT-Date: 1520176171 2018/03/04 15:09:31 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.109 $ */ +# NetHack 3.6 Makefile.msc $NHDT-Date: 1520177086 2018/03/04 15:24:46 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.110 $ */ # Copyright (c) NetHack PC Development Team 1993-2018 # #============================================================================== @@ -913,10 +913,10 @@ $(MSWIN)\splash.bmp: $(U)uudecode.exe $(MSWIN)\splash.uu # defer to the steps in ..\win\win32\levstuff.mak # -$(U)lev_yacc.c: +$(U)lev_yacc.c: $(U)lev_comp.y nmake -nologo -f ..\win\win32\levstuff.mak $(U)lev_yacc.c -$(U)lev_lex.c: +$(U)lev_lex.c: $(U)lev_comp.l nmake -nologo -f ..\win\win32\levstuff.mak $(U)lev_lex.c $(INCL)\lev_comp.h: @@ -944,13 +944,13 @@ $(U)levcomp.exe: $(LEVCOMPOBJS) # # defer to the steps in ..\win\win32\dgnstuff.mak # -$(U)dgn_yacc.c: +$(U)dgn_yacc.c: $(U)dgn_comp.y nmake -nologo -f ..\win\win32\dgnstuff.mak $(U)dgn_yacc.c $(INCL)\dgn_comp.h: nmake -nologo -f ..\win\win32\dgnstuff.mak $(INCL)\dgn_comp.h -$(U)dgn_lex.c: +$(U)dgn_lex.c: $(U)dgn_comp.l nmake -nologo -f ..\win\win32\dgnstuff.mak $(U)dgn_lex.c $(O)dgn_yacc.o: $(HACK_H) $(DGN_FILE_H) $(INCL)\dgn_comp.h $(U)dgn_yacc.c @@ -985,7 +985,7 @@ $(O)obj.tag: # options. #========================================== -$(O)envchk.tag: +$(O)envchk.tag: $(O)obj.tag ! IF "$(TARGET_CPU)"=="x64" @echo Windows x64 64-bit target build ! ELSE @@ -1182,63 +1182,67 @@ spotless: clean if exist $(GAMEDIR)\NetHack.pdb del $(GAMEDIR)\NetHack.pdb if exist $(GAMEDIR)\nhdat del $(GAMEDIR)\nhdat ! ENDIF - if exist $(INCL)\date.h del $(INCL)\date.h - if exist $(INCL)\onames.h del $(INCL)\onames.h - if exist $(INCL)\pm.h del $(INCL)\pm.h - if exist $(INCL)\vis_tab.h del $(INCL)\vis_tab.h - if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c - if exist $(SRC)\tile.c del $(SRC)\tile.c - if exist $(U)*.lnk del $(U)*.lnk - if exist $(U)*.map del $(U)*.map - if exist $(DAT)\data del $(DAT)\data - if exist $(DAT)\rumors del $(DAT)\rumors - if exist $(DAT)\engrave del $(DAT)\engrave - if exist $(DAT)\epitaph del $(DAT)\epitaph - if exist $(DAT)\bogusmon del $(DAT)\bogusmon - if exist $(DAT)\???-fil?.lev del $(DAT)\???-fil?.lev - if exist $(DAT)\???-goal.lev del $(DAT)\???-goal.lev - if exist $(DAT)\???-loca.lev del $(DAT)\???-loca.lev - if exist $(DAT)\???-strt.lev del $(DAT)\???-strt.lev - if exist $(DAT)\air.lev del $(DAT)\air.lev - if exist $(DAT)\asmodeus.lev del $(DAT)\asmodeus.lev - if exist $(DAT)\astral.lev del $(DAT)\astral.lev - if exist $(DAT)\baalz.lev del $(DAT)\baalz.lev - if exist $(DAT)\bigrm-*.lev del $(DAT)\bigrm-*.lev - if exist $(DAT)\castle.lev del $(DAT)\castle.lev - if exist $(DAT)\data del $(DAT)\data - if exist $(DAT)\dungeon del $(DAT)\dungeon - if exist $(DAT)\dungeon.pdf del $(DAT)\dungeon.pdf - if exist $(DAT)\earth.lev del $(DAT)\earth.lev - if exist $(DAT)\fakewiz?.lev del $(DAT)\fakewiz?.lev - if exist $(DAT)\fire.lev del $(DAT)\fire.lev - if exist $(DAT)\juiblex.lev del $(DAT)\juiblex.lev - if exist $(DAT)\knox.lev del $(DAT)\knox.lev - if exist $(DAT)\medusa-?.lev del $(DAT)\medusa-?.lev - if exist $(DAT)\mine*.lev del $(DAT)\mine*.lev - if exist $(DAT)\options del $(DAT)\options - if exist $(DAT)\ttyoptions del $(DAT)\ttyoptions - if exist $(DAT)\guioptions del $(DAT)\guioptions - if exist $(DAT)\oracle.lev del $(DAT)\oracle.lev - if exist $(DAT)\oracles del $(DAT)\oracles - if exist $(DAT)\orcus.lev del $(DAT)\orcus.lev - if exist $(DAT)\rumors del $(DAT)\rumors - if exist $(DAT)\quest.dat del $(DAT)\quest.dat - if exist $(DAT)\sanctum.lev del $(DAT)\sanctum.lev - if exist $(DAT)\soko?-?.lev del $(DAT)\soko?-?.lev - if exist $(DAT)\tower?.lev del $(DAT)\tower?.lev - if exist $(DAT)\valley.lev del $(DAT)\valley.lev - if exist $(DAT)\water.lev del $(DAT)\water.lev - if exist $(DAT)\wizard?.lev del $(DAT)\wizard?.lev - if exist $(DAT)\dlb.lst del $(DAT)\dlb.lst - if exist $(O)sp_lev.tag del $(O)sp_lev.tag - if exist $(SRC)\monstr.c del $(SRC)\monstr.c - if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c - if exist $(U)recover.exe del $(U)recover.exe - if exist nhdat. del nhdat. - if exist $(O)obj.tag del $(O)obj.tag - if exist $(O)gamedir.tag del $(O)gamedir.tag - if exist $(O)nh*key.lib del $(O)nh*key.lib - if exist $(O)nh*key.exp del $(O)nh*key.exp + if exist $(INCL)\date.h del $(INCL)\date.h + if exist $(INCL)\onames.h del $(INCL)\onames.h + if exist $(INCL)\pm.h del $(INCL)\pm.h + if exist $(INCL)\vis_tab.h del $(INCL)\vis_tab.h + if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c + if exist $(SRC)\tile.c del $(SRC)\tile.c + if exist $(U)*.lnk del $(U)*.lnk + if exist $(U)*.map del $(U)*.map + if exist $(DAT)\data del $(DAT)\data + if exist $(DAT)\rumors del $(DAT)\rumors + if exist $(DAT)\engrave del $(DAT)\engrave + if exist $(DAT)\epitaph del $(DAT)\epitaph + if exist $(DAT)\bogusmon del $(DAT)\bogusmon + if exist $(DAT)\???-fil?.lev del $(DAT)\???-fil?.lev + if exist $(DAT)\???-goal.lev del $(DAT)\???-goal.lev + if exist $(DAT)\???-loca.lev del $(DAT)\???-loca.lev + if exist $(DAT)\???-strt.lev del $(DAT)\???-strt.lev + if exist $(DAT)\air.lev del $(DAT)\air.lev + if exist $(DAT)\asmodeus.lev del $(DAT)\asmodeus.lev + if exist $(DAT)\astral.lev del $(DAT)\astral.lev + if exist $(DAT)\baalz.lev del $(DAT)\baalz.lev + if exist $(DAT)\bigrm-*.lev del $(DAT)\bigrm-*.lev + if exist $(DAT)\castle.lev del $(DAT)\castle.lev + if exist $(DAT)\data del $(DAT)\data + if exist $(DAT)\dungeon del $(DAT)\dungeon + if exist $(DAT)\dungeon.pdf del $(DAT)\dungeon.pdf + if exist $(DAT)\earth.lev del $(DAT)\earth.lev + if exist $(DAT)\fakewiz?.lev del $(DAT)\fakewiz?.lev + if exist $(DAT)\fire.lev del $(DAT)\fire.lev + if exist $(DAT)\juiblex.lev del $(DAT)\juiblex.lev + if exist $(DAT)\knox.lev del $(DAT)\knox.lev + if exist $(DAT)\medusa-?.lev del $(DAT)\medusa-?.lev + if exist $(DAT)\mine*.lev del $(DAT)\mine*.lev + if exist $(DAT)\options del $(DAT)\options + if exist $(DAT)\ttyoptions del $(DAT)\ttyoptions + if exist $(DAT)\guioptions del $(DAT)\guioptions + if exist $(DAT)\oracle.lev del $(DAT)\oracle.lev + if exist $(DAT)\oracles del $(DAT)\oracles + if exist $(DAT)\orcus.lev del $(DAT)\orcus.lev + if exist $(DAT)\rumors del $(DAT)\rumors + if exist $(DAT)\quest.dat del $(DAT)\quest.dat + if exist $(DAT)\sanctum.lev del $(DAT)\sanctum.lev + if exist $(DAT)\soko?-?.lev del $(DAT)\soko?-?.lev + if exist $(DAT)\tower?.lev del $(DAT)\tower?.lev + if exist $(DAT)\valley.lev del $(DAT)\valley.lev + if exist $(DAT)\water.lev del $(DAT)\water.lev + if exist $(DAT)\wizard?.lev del $(DAT)\wizard?.lev + if exist $(DAT)\dlb.lst del $(DAT)\dlb.lst + if exist $(O)sp_lev.tag del $(O)sp_lev.tag + if exist $(SRC)\monstr.c del $(SRC)\monstr.c + if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c + if exist nhdat. del nhdat. + if exist $(O)obj.tag del $(O)obj.tag + if exist $(O)gamedir.tag del $(O)gamedir.tag + if exist $(O)nh*key.lib del $(O)nh*key.lib + if exist $(O)nh*key.exp del $(O)nh*key.exp + if exist $(U)recover.exe del $(U)recover.exe + if exist $(U)tile2bmp.exe del $(U)tile2bmp.exe + if exist $(U)tilemap.exe del $(U)tilemap.exe + if exist $(U)uudecode.exe del $(U)uudecode.exe + if exist $(U)dlb_main.exe del $(U)dlb_main.exe clean: if exist $(O)*.o del $(O)*.o if exist $(O)utility.tag del $(O)utility.tag @@ -1274,7 +1278,7 @@ clean: if exist $(O)nhraykey.lib del $(O)nhraykey.lib if exist $(O)nhraykey.map del $(O)nhraykey.map if exist $(O)nhraykey.PDB del $(O)nhraykey.PDB - if exist $(O)envchk.tag del $(O)envchk.tag + if exist $(O)envchk.tag del $(O)envchk.tag if exist $(O)obj.tag del $(O)obj.tag if exist $(O)sp_lev.tag del $(O)sp_lev.tag if exist $(O)uudecode.MAP del $(O)uudecode.MAP @@ -1287,7 +1291,6 @@ clean: rem defer to the steps in ..\win\win32\dgnstuff.mak rem nmake -nologo -f ..\win\win32\dgnstuff.mak clean - if exist $(TILEBMP16) del $(TILEBMP16) if exist $(TILEBMP32) del $(TILEBMP32) diff --git a/win/win32/dgnstuff.mak b/win/win32/dgnstuff.mak index 0965501fe..7420960a1 100644 --- a/win/win32/dgnstuff.mak +++ b/win/win32/dgnstuff.mak @@ -45,8 +45,7 @@ tools: !IF "$(YACC)"=="" @echo Using pre-built dgn_comp.h chdir ..\include - copy /y ..\sys\share\dgn_comp.h - copy /b dgn_comp.h+,, + copy /b ..\sys\share\dgn_comp.h +,, chdir ..\src !ELSE chdir ..\util @@ -62,8 +61,7 @@ tools: !IF "$(YACC)"=="" @echo Using pre-built dgn_yacc.c chdir ..\util - copy /y ..\sys\share\dgn_yacc.c - copy /b dgn_yacc.c+,, + copy /b ..\sys\share\dgn_yacc.c +,, chdir ..\src !ELSE chdir ..\util @@ -79,8 +77,7 @@ tools: !IF "$(LEX)"=="" @echo Using pre-built dgn_lex.c chdir ..\util - copy /y ..\sys\share\dgn_lex.c - copy /b dgn_lex.c+,, + copy /b ..\sys\share\dgn_lex.c +,, chdir ..\src !ELSE chdir ..\util diff --git a/win/win32/levstuff.mak b/win/win32/levstuff.mak index 2072c2cc0..e36986d99 100644 --- a/win/win32/levstuff.mak +++ b/win/win32/levstuff.mak @@ -44,8 +44,7 @@ tools: !IFNDEF YACC @echo Using pre-built lev_comp.h chdir ..\include - copy /y ..\sys\share\lev_comp.h - copy /b lev_comp.h+,, + copy /b ..\sys\share\lev_comp.h +,, chdir ..\src !ELSE @echo Generating lev_yacc.c and lev_comp.h @@ -62,8 +61,7 @@ tools: !IFNDEF YACC @echo Using pre-built lev_yacc.c chdir ..\util - copy /y ..\sys\share\lev_yacc.c - copy /b lev_yacc.c+,, + copy /b ..\sys\share\lev_yacc.c +,, chdir ..\src !ELSE @echo Generating lev_yacc.c and lev_comp.h @@ -80,8 +78,7 @@ tools: !IFNDEF LEX @echo Using pre-built lev_lex.c chdir ..\util - copy /y ..\sys\share\lev_lex.c - copy /b lev_lex.c+,, + copy /b ..\sys\share\lev_lex.c +,, chdir ..\src !ELSE @echo Generating lev_lex.c From a120d99005fb8a4acf124ef47a8ccdeb0d3b1234 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Mar 2018 10:30:17 -0500 Subject: [PATCH 43/57] msc makefiles update timestamp on copied files --- win/win32/dgnstuff.mak | 9 ++++++--- win/win32/levstuff.mak | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/win/win32/dgnstuff.mak b/win/win32/dgnstuff.mak index 7420960a1..0965501fe 100644 --- a/win/win32/dgnstuff.mak +++ b/win/win32/dgnstuff.mak @@ -45,7 +45,8 @@ tools: !IF "$(YACC)"=="" @echo Using pre-built dgn_comp.h chdir ..\include - copy /b ..\sys\share\dgn_comp.h +,, + copy /y ..\sys\share\dgn_comp.h + copy /b dgn_comp.h+,, chdir ..\src !ELSE chdir ..\util @@ -61,7 +62,8 @@ tools: !IF "$(YACC)"=="" @echo Using pre-built dgn_yacc.c chdir ..\util - copy /b ..\sys\share\dgn_yacc.c +,, + copy /y ..\sys\share\dgn_yacc.c + copy /b dgn_yacc.c+,, chdir ..\src !ELSE chdir ..\util @@ -77,7 +79,8 @@ tools: !IF "$(LEX)"=="" @echo Using pre-built dgn_lex.c chdir ..\util - copy /b ..\sys\share\dgn_lex.c +,, + copy /y ..\sys\share\dgn_lex.c + copy /b dgn_lex.c+,, chdir ..\src !ELSE chdir ..\util diff --git a/win/win32/levstuff.mak b/win/win32/levstuff.mak index e36986d99..2072c2cc0 100644 --- a/win/win32/levstuff.mak +++ b/win/win32/levstuff.mak @@ -44,7 +44,8 @@ tools: !IFNDEF YACC @echo Using pre-built lev_comp.h chdir ..\include - copy /b ..\sys\share\lev_comp.h +,, + copy /y ..\sys\share\lev_comp.h + copy /b lev_comp.h+,, chdir ..\src !ELSE @echo Generating lev_yacc.c and lev_comp.h @@ -61,7 +62,8 @@ tools: !IFNDEF YACC @echo Using pre-built lev_yacc.c chdir ..\util - copy /b ..\sys\share\lev_yacc.c +,, + copy /y ..\sys\share\lev_yacc.c + copy /b lev_yacc.c+,, chdir ..\src !ELSE @echo Generating lev_yacc.c and lev_comp.h @@ -78,7 +80,8 @@ tools: !IFNDEF LEX @echo Using pre-built lev_lex.c chdir ..\util - copy /b ..\sys\share\lev_lex.c +,, + copy /y ..\sys\share\lev_lex.c + copy /b lev_lex.c+,, chdir ..\src !ELSE @echo Generating lev_lex.c From 2317288150e62d3d389ae23ef8a7dc0ccc8a48b9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Mar 2018 10:37:43 -0500 Subject: [PATCH 44/57] more nmake spotless --- sys/winnt/Makefile.msc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 1e5dd7183..585f8c29a 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -1,4 +1,4 @@ -# NetHack 3.6 Makefile.msc $NHDT-Date: 1520177086 2018/03/04 15:24:46 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.110 $ */ +# NetHack 3.6 Makefile.msc $NHDT-Date: 1520177858 2018/03/04 15:37:38 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.111 $ */ # Copyright (c) NetHack PC Development Team 1993-2018 # #============================================================================== @@ -1230,6 +1230,7 @@ spotless: clean if exist $(DAT)\water.lev del $(DAT)\water.lev if exist $(DAT)\wizard?.lev del $(DAT)\wizard?.lev if exist $(DAT)\dlb.lst del $(DAT)\dlb.lst + if exist $(DAT)\porthelp del $(DAT)\porthelp if exist $(O)sp_lev.tag del $(O)sp_lev.tag if exist $(SRC)\monstr.c del $(SRC)\monstr.c if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c @@ -1238,6 +1239,15 @@ spotless: clean if exist $(O)gamedir.tag del $(O)gamedir.tag if exist $(O)nh*key.lib del $(O)nh*key.lib if exist $(O)nh*key.exp del $(O)nh*key.exp + if exist $(MSWIN)\mnsel.bmp del $(MSWIN)\mnsel.bmp + if exist $(MSWIN)\mnselcnt.bmp del $(MSWIN)\mnselcnt.bmp + if exist $(MSWIN)\mnunsel.bmp del $(MSWIN)\mnunsel.bmp + if exist $(MSWIN)\petmark.bmp del $(MSWIN)\petmark.bmp + if exist $(MSWIN)\pilemark.bmp del $(MSWIN)\pilemark.bmp + if exist $(MSWIN)\rip.bmp del $(MSWIN)\rip.bmp + if exist $(MSWIN)\splash.bmp del $(MSWIN)\splash.bmp + if exist $(MSWIN)\nethack.ico del $(MSWIN)\nethack.ico + if exist $(MSWSYS)\nethack.ico del $(MSWSYS)\nethack.ico if exist $(U)recover.exe del $(U)recover.exe if exist $(U)tile2bmp.exe del $(U)tile2bmp.exe if exist $(U)tilemap.exe del $(U)tilemap.exe From 4d35ca86f37d8b0ac53a7bd782fc846e530d9972 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 4 Mar 2018 14:17:13 -0800 Subject: [PATCH 45/57] gitinfo.txt on Unix Hide the scary perl command during 'make all' feedback in src/. I'm not a shell programmer but this works fine for me when skipping NHgithook::NHversioning because dat/gitinfo.txt is already present, when creating dat/gitinfo.txt successfully, and when creation fails because perl can't find NHgithook.pm. It hasn't been tested when perl itself is absent. --- sys/unix/Makefile.src | 8 ++++---- sys/unix/gitinfo.sh | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) create mode 100755 sys/unix/gitinfo.sh diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 19f41ca81..f6b9371bc 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile. -# NetHack 3.6 Makefile.src $NHDT-Date: 1519228664 2018/02/21 15:57:44 $ $NHDT-Branch: githash $:$NHDT-Revision: 1.51 $ +# NetHack 3.6 Makefile.src $NHDT-Date: 1520201829 2018/03/04 22:17:09 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.52 $ # Root of source tree: NHSROOT=.. @@ -606,13 +606,13 @@ tile.c: ../win/share/tilemap.c $(HACK_H) # file far more complex. Since "hack.h" depends on most of the include # files, we kludge around this by making date.h dependent on hack.h, # even though it doesn't include this file. +# Do NOT include ../dat/gitinfo.txt as either a prerequisite or target. +# 'makedefs -v' processes it when present and ignores it if not. # # hack.h depends on makedefs' output, so we know makedefs will be # up to date before being executed ../include/date.h: $(VERSOURCES) $(HACK_H) - if [[ ! -f ../dat/gitinfo.txt ]]; then \ - (cd ..;perl -IDEVEL/hooksdir -MNHgithook -e '&NHgithook::nhversioning') || true; \ - fi + -$(SHELL) ../sys/unix/gitinfo.sh #../dat/gitinfo.txt for 'makedefs -v' ../util/makedefs -v diff --git a/sys/unix/gitinfo.sh b/sys/unix/gitinfo.sh new file mode 100755 index 000000000..72d300454 --- /dev/null +++ b/sys/unix/gitinfo.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# NetHack 3.6 gitinfo.sh $NHDT-Date: 1520201830 2018/03/04 22:17:10 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.0 $ + +# if dat/gitinfo.txt doesn't exist, try to make one; called from Makefile.src + +# +# gitinfo.txt is used during development to augment the version number +# (for nethack's 'v' command) with more specific information. That is not +# necessary when building a released version and it is perfectly OK for +# this script to be skipped or to run but fail to generate dat/gitinfo.txt. +# + +# try to figure out where we are: top, one level down (expected), or sys/unix +prefix=. +if [ -f ../sys/unix/gitinfo.sh ]; then prefix=..; fi +if [ -f ../../sys/unix/gitinfo.sh ]; then prefix=../..; fi + +# try to run a perl script which is part of nethack's git repository +if [[ ! -f $prefix/dat/gitinfo.txt ]]; then + ( cd $prefix; \ + perl -IDEVEL/hooksdir -MNHgithook -e '&NHgithook::nhversioning' \ + 2> /dev/null ) \ + || true +fi +exit 0 From b416564f39aa74a4cc53b868779108c0acfae99d Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 5 Mar 2018 21:09:15 +0200 Subject: [PATCH 46/57] Fix garbage value warning --- src/botl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/botl.c b/src/botl.c index f0ee33fd0..78e9b7e59 100644 --- a/src/botl.c +++ b/src/botl.c @@ -1296,9 +1296,8 @@ merge_bestcolor(bestcolor, newcolor) int *bestcolor; int newcolor; { - int batr, bclr, natr, nclr; + int natr = HL_UNDEF, nclr = NO_COLOR; - split_clridx(*bestcolor, &bclr, &batr); split_clridx(newcolor, &nclr, &natr); if (nclr != NO_COLOR) From 8279aa4384cc0c26f569d8159f8ced038f8abb6f Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 5 Mar 2018 12:01:31 -0800 Subject: [PATCH 47/57] removing a monster from current level I ended up not using this, but it might as well be included for potential future use. Extend mlevel_tele_trap() to support forcing a monster off the current level to make room either for the hero or some other monster. goto_level() does something similar when the hero is arriving on a level. This is for situations where the hero is already there (such as divine aid attempting to fix STUCK_IN_WALL). mlevel_tele_trap(mon, (struct trap *) 0) will usually move 'mon' off the level, scheduled to migrate back if the hero leaves the level and subsequently returns. 'Usually' because it doesn't work in endgame and certain monsters are excluded regardless of dungeon location, so caller has to be prepared to try to move another monster (or resort to goto_level()'s unconditional forced migration). --- src/teleport.c | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/teleport.c b/src/teleport.c index 8fb3f8c84..bd3ada997 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -198,6 +198,8 @@ STATIC_OVL boolean tele_jump_ok(x1, y1, x2, y2) int x1, y1, x2, y2; { + if (!isok(x2, y2)) + return FALSE; if (dndest.nlx > 0) { /* if inside a restricted region, can't teleport outside */ if (within_bounded_area(x1, y1, dndest.nlx, dndest.nly, dndest.nhx, @@ -1135,8 +1137,7 @@ struct trap *trap; boolean force_it; int in_sight; { - int tt = trap->ttyp; - struct permonst *mptr = mtmp->data; + int tt = (trap ? trap->ttyp : NO_TRAP); if (mtmp == u.ustuck) /* probably a vortex */ return 0; /* temporary? kludge */ @@ -1157,8 +1158,8 @@ int in_sight; } } else if (tt == MAGIC_PORTAL) { if (In_endgame(&u.uz) - && (mon_has_amulet(mtmp) || is_home_elemental(mptr))) { - if (in_sight && mptr->mlet != S_ELEMENTAL) { + && (mon_has_amulet(mtmp) || is_home_elemental(mtmp->data))) { + if (in_sight && mtmp->data->mlet != S_ELEMENTAL) { pline("%s seems to shimmer for a moment.", Monnam(mtmp)); seetrap(trap); } @@ -1167,27 +1168,44 @@ int in_sight; assign_level(&tolevel, &trap->dst); migrate_typ = MIGR_PORTAL; } - } else { /* (tt == LEVEL_TELEP) */ + } else if (tt == LEVEL_TELEP || tt == NO_TRAP) { int nlev; - if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) { + if (mon_has_amulet(mtmp) || In_endgame(&u.uz) + /* NO_TRAP is used when forcing a monster off the level; + onscary(0,0,) is true for the Wizard, Riders, lawful + minions, Angels of any alignment, shopkeeper or priest + currently inside his or her own special room */ + || (tt == NO_TRAP && onscary(0, 0, mtmp))) { if (in_sight) pline("%s seems very disoriented for a moment.", Monnam(mtmp)); return 0; } - nlev = random_teleport_level(); - if (nlev == depth(&u.uz)) { - if (in_sight) - pline("%s shudders for a moment.", Monnam(mtmp)); - return 0; + if (tt == NO_TRAP) { + /* creature is being forced off the level to make room; + it will try to return to this level (at a random spot + rather than its current one) if the level is left by + the hero and then revisited */ + assign_level(&tolevel, &u.uz); + } else { + nlev = random_teleport_level(); + if (nlev == depth(&u.uz)) { + if (in_sight) + pline("%s shudders for a moment.", Monnam(mtmp)); + return 0; + } + get_level(&tolevel, nlev); } - get_level(&tolevel, nlev); + } else { + impossible("mlevel_tele_trap: unexpected trap type (%d)", tt); + return 0; } if (in_sight) { pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp)); - seetrap(trap); + if (trap) + seetrap(trap); } migrate_to_level(mtmp, ledger_no(&tolevel), migrate_typ, (coord *) 0); return 3; /* no longer on this level */ From a43b2086e46d251ebba12ae211cc25463923868a Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 5 Mar 2018 12:26:44 -0800 Subject: [PATCH 48/57] stuck_in_wall tweak When divine aid granted temporary Passes_walls ability to stuck hero, it was giving 4d4 turns (4..16, avg 10). But the first warning that it's timing out is given at 4 turns left so wouldn't be seen if the random amount of time picked was the minimum. Switch to 4d4+4 (8..20, avg 14) so that the message at 4 turns left will always happen. --- src/pray.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pray.c b/src/pray.c index 29a2bd601..646de494c 100644 --- a/src/pray.c +++ b/src/pray.c @@ -421,7 +421,7 @@ int trouble; Without something like this, fix_all_troubles can get stuck in an infinite loop trying to fix STUCK_IN_WALL and repeatedly failing. */ - set_itimeout(&HPasses_walls, (long) d(4, 4)); + set_itimeout(&HPasses_walls, (long) (d(4, 4) + 4)); /* 8..20 */ /* how else could you move between packed rocks or among lattice forming "solid" rock? */ You_feel("much slimmer."); From 03da0190fbbddeb9ece12aa7792a6c6e6fbcb160 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 6 Mar 2018 17:16:49 -0800 Subject: [PATCH 49/57] nhversioning update Update dat/gitinfo.txt if the current branch is different from the one recorded in the file, not just when the commit hash is different. Make the usual output less verbose so that it fits within 80 columns. --- DEVEL/hooksdir/NHgithook.pm | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/DEVEL/hooksdir/NHgithook.pm b/DEVEL/hooksdir/NHgithook.pm index 0d586cfb7..2f14ae114 100644 --- a/DEVEL/hooksdir/NHgithook.pm +++ b/DEVEL/hooksdir/NHgithook.pm @@ -75,21 +75,28 @@ sub nhversioning { die "git rev-parse failed" unless(length $git_sha and length $git_branch); if (open my $fh, '<', 'dat/gitinfo.txt') { - while(my $line = <$fh>) { + my $hashok = 0; + my $branchok = 0; + while (my $line = <$fh>) { if ((index $line, $git_sha) >= 0) { - close $fh; - print "No update made to dat/gitinfo.txt, existing githash=".$git_sha."\n"; - return; + $hashok++; + } + if ((index $line, $git_branch) >= 0) { + $branchok++; } } close $fh; + if ($hashok && $branchok) { + print "dat/gitinfo.txt unchanged, githash=".$git_sha."\n"; + return; + } } else { print "WARNING: Can't find dat directory\n" unless(-d "dat"); } if (open my $fh, '>', 'dat/gitinfo.txt') { print $fh 'githash='.$git_sha."\n"; print $fh 'gitbranch='.$git_branch."\n"; - print "An updated dat/gitinfo.txt was written, githash=".$git_sha."\n"; + print "dat/gitinfo.txt updated, githash=".$git_sha."\n"; } else { print "WARNING: Unable to open dat/gitinfo.txt: $!\n"; } From cba6761ee6ca8ae1af9ddd95d167a79d74374088 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 8 Mar 2018 10:26:08 -0800 Subject: [PATCH 50/57] Files update I'm not sure of the status for possibly maintaining 'Files' via automation, so manually add the new file 'gitinfo.sh' to sys/unix. There was a sys/unix/hints file that wasn't listed, so add linux-qt4. The whole win/Qt4 subdirectory is missing though. I don't even remember that being added. --- Files | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Files b/Files index c6a2a5c0c..f2bb266aa 100644 --- a/Files +++ b/Files @@ -169,9 +169,9 @@ wdnflute.uu wdnharp.uu sys/unix: (files for UNIX versions) Install.unx Makefile.dat Makefile.doc Makefile.src Makefile.top -Makefile.utl README.linux depend.awk mkmkfile.sh nethack.sh -NewInstall.unx setup.sh sysconf unixmain.c unixres.c -unixunix.c +Makefile.utl README.linux depend.awk gitinfo.sh mkmkfile.sh +nethack.sh NewInstall.unx setup.sh sysconf unixmain.c +unixres.c unixunix.c (files for replacement cpp, only needed by some ancient UNIX systems) cpp1.shr cpp2.shr cpp3.shr (file for sound driver for 386 UNIX) @@ -179,8 +179,9 @@ snd86unx.shr sys/unix/hints: (files for configuring UNIX NetHack versions) -linux linux-chroot linux-x11 macosx macosx10.5 -macosx10.7 macosx10.8 macosx10.10 macosx.sh unix +linux linux-chroot linux-qt4 linux-x11 macosx +macosx10.5 macosx10.7 macosx10.8 macosx10.10 macosx.sh +unix sys/vms: (files for VMS version) From e408c48bb3610b22c5bc29932f19d55bffd10f34 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 9 Mar 2018 14:11:04 -0800 Subject: [PATCH 51/57] mplayer valkyries w/ Mjollnir If an mplayer Valkyrie on the Astral Plane is given a war hammer, give her gauntlets of power instead of random gloves since that will either be Mjollnir or a very wimpy endgame weapon. (Maybe someday mplayer Valkyrie's will be able to throw Mjollnir; their chance of having it on the Astral Plane is moderately high if it hasn't already been created prior to arriving there.) I also gave monsters wearing gauntlets of power a 3..6 damage bonus for hand-to-hand. While making that change, I noticed that monsters wielding a scalpel or tsurugi wouldn't split puddings, unlike the hero (a post-3.6.0 change), so fix that. --- src/mhitm.c | 12 ++++++++++-- src/mhitu.c | 9 ++++++++- src/mplayer.c | 6 ++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/mhitm.c b/src/mhitm.c index 3427645fe..ee7dc0448 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -412,8 +412,9 @@ register struct monst *magr, *mdef; if (strike) { res[i] = hitmm(magr, mdef, mattk); if ((mdef->data == &mons[PM_BLACK_PUDDING] - || mdef->data == &mons[PM_BROWN_PUDDING]) && otmp - && objects[otmp->otyp].oc_material == IRON + || mdef->data == &mons[PM_BROWN_PUDDING]) + && (otmp && (objects[otmp->otyp].oc_material == IRON + || objects[otmp->otyp].oc_material == METAL)) && mdef->mhp > 1 && !mdef->mcan) { if (clone_mon(mdef, 0, 0)) { @@ -908,10 +909,17 @@ register struct attack *mattk; tmp = 0; } else if (mattk->aatyp == AT_WEAP) { if (otmp) { + struct obj *marmg; + if (otmp->otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm])) goto do_stone; tmp += dmgval(otmp, mdef); + if ((marmg = which_armor(magr, W_ARMG)) != 0 + && marmg->otyp == GAUNTLETS_OF_POWER) + tmp += rn1(4, 3); /* 3..6 */ + if (tmp < 1) /* is this necessary? mhitu.c has it... */ + tmp = 1; if (otmp->oartifact) { (void) artifact_hit(magr, mdef, otmp, &tmp, dieroll); if (mdef->mhp <= 0) diff --git a/src/mhitu.c b/src/mhitu.c index fb483b811..8bd4c33e1 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -972,6 +972,7 @@ register struct attack *mattk; struct obj *otmp = mon_currwep; if (mattk->aatyp == AT_WEAP && otmp) { + struct obj *marmg; int tmp; if (otmp->otyp == CORPSE @@ -983,6 +984,9 @@ register struct attack *mattk; goto do_stone; } dmg += dmgval(otmp, &youmonst); + if ((marmg = which_armor(mtmp, W_ARMG)) != 0 + && marmg->otyp == GAUNTLETS_OF_POWER) + dmg += rn1(4, 3); /* 3..6 */ if (dmg <= 0) dmg = 1; if (!(otmp->oartifact @@ -1003,7 +1007,10 @@ register struct attack *mattk; tmp -= rnd(-u.uac); if (tmp < 1) tmp = 1; - if (u.mh - tmp > 1 && objects[otmp->otyp].oc_material == IRON + if (u.mh - tmp > 1 + && (objects[otmp->otyp].oc_material == IRON + /* relevant 'metal' objects are scalpel and tsurugi */ + || objects[otmp->otyp].oc_material == METAL) && (u.umonnum == PM_BLACK_PUDDING || u.umonnum == PM_BROWN_PUDDING)) { if (tmp > 1) diff --git a/src/mplayer.c b/src/mplayer.c index ec895546c..dfb97ab85 100644 --- a/src/mplayer.c +++ b/src/mplayer.c @@ -285,7 +285,9 @@ register boolean special; mk_mplayer_armor(mtmp, cloak); mk_mplayer_armor(mtmp, helm); mk_mplayer_armor(mtmp, shield); - if (rn2(8)) + if (weapon == WAR_HAMMER) /* valkyrie: wimpy weapon or Mjollnir */ + mk_mplayer_armor(mtmp, GAUNTLETS_OF_POWER); + else if (rn2(8)) mk_mplayer_armor(mtmp, rnd_class(LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY)); if (rn2(8)) @@ -337,7 +339,7 @@ boolean special; int tryct = 0; /* roll for character class */ - pm = PM_ARCHEOLOGIST + rn2(PM_WIZARD - PM_ARCHEOLOGIST + 1); + pm = rn1(PM_WIZARD - PM_ARCHEOLOGIST + 1, PM_ARCHEOLOGIST); set_mon_data(&fakemon, &mons[pm], -1); /* roll for an available location */ From 5fece7b175f93b11286dd6ae769b427563870ea1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 10 Mar 2018 10:43:34 -0500 Subject: [PATCH 52/57] pluralization bits --- src/objnam.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/objnam.c b/src/objnam.c index 5daead647..9b9b8fbba 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1471112245 2016/08/13 18:17:25 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.178 $ */ +/* NetHack 3.6 objnam.c $NHDT-Date: 1520696604 2018/03/10 15:43:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.187 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2033,14 +2033,18 @@ static struct sing_plur one_off[] = { { "erinys", "erinyes" }, { "foot", "feet" }, { "fungus", "fungi" }, + { "goose", "geese" }, { "knife", "knives" }, { "labrum", "labra" }, /* candelabrum */ { "louse", "lice" }, { "mouse", "mice" }, { "mumak", "mumakil" }, { "nemesis", "nemeses" }, + { "ovum", "ova" }, + { "ox", "oxen" }, { "rtex", "rtices" }, /* vortex */ { "tooth", "teeth" }, + { "serum", "sera" }, { "staff", "staves" }, { 0, 0 } }; @@ -2050,10 +2054,11 @@ static const char *const as_is[] = { "boots", "shoes", "gloves", "lenses", "scales", "eyes", "gauntlets", "iron bars", /* both singular and plural are spelled the same */ - "deer", "fish", "tuna", "yaki", "-hai", - "krill", "manes", "ninja", "sheep", "ronin", - "roshi", "shito", "tengu", "ki-rin", "Nazgul", - "gunyoki", "piranha", "samurai", "shuriken", 0, + "deer", "elk", "fish", "tuna", "yaki", + "-hai", "krill", "manes", "moose", "ninja", + "sheep", "ronin", "roshi", "shito", "tengu", + "ki-rin", "Nazgul", "gunyoki", "piranha", "samurai", + "shuriken", 0, /* Note: "fish" and "piranha" are collective plurals, suitable for "wiped out all ". For "3 ", they should be "fishes" and "piranhas" instead. We settle for collective From 6586e9204bcec458ea9ed6eb25f0ef0a31921037 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 10 Mar 2018 11:28:01 -0500 Subject: [PATCH 53/57] pluralization special case tweak mongoose -> mongooses, not mongeese --- src/objnam.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/objnam.c b/src/objnam.c index 9b9b8fbba..90c96e156 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1520696604 2018/03/10 15:43:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.187 $ */ +/* NetHack 3.6 objnam.c $NHDT-Date: 1471112245 2016/08/13 18:17:25 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.178 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2094,7 +2094,8 @@ const char *const *alt_as_is; /* another set like as_is[] */ if more of these turn up, one_off[] entries will need to flagged as to which are whole words and which are matchable as suffices then matching in the loop below will end up becoming more complex */ - if (!strcmpi(basestr, "slice")) { + if (!strcmpi(basestr, "slice") + || !strcmpi(basestr, "mongoose")) { if (to_plural) (void) strkitten(basestr, 's'); return TRUE; From 6fc324798e71d545aba67dfdd77aed916240467c Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 10 Mar 2018 13:17:21 -0500 Subject: [PATCH 54/57] H5239 not hypocrisy to speed up your own pet H5239 1100 --- doc/fixes36.1 | 2 ++ src/zap.c | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index e1c5c4468..bb8c17505 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -519,6 +519,8 @@ change the deity's "congratulations" message upon ascension to something which sounds a bit more archaic to fit better with the other messages prayer boon of 'fix all troubles' could get stuck in an infinite loop for TROUBLE_STUCK_IN_WALL if there was no spot to teleport into available +It shouldn't be considered hypocrisy if you speed up your pet while standing + on Elbereth Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/src/zap.c b/src/zap.c index 4ab138938..233ebfee7 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 zap.c $NHDT-Date: 1513297348 2017/12/15 00:22:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.270 $ */ +/* NetHack 3.6 zap.c $NHDT-Date: 1520705645 2018/03/10 18:14:05 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.271 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -137,6 +137,7 @@ struct obj *otmp; boolean wake = TRUE; /* Most 'zaps' should wake monster */ boolean reveal_invis = FALSE, learn_it = FALSE; boolean dbldam = Role_if(PM_KNIGHT) && u.uhave.questart; + boolean helpful_gesture = FALSE; int dmg, otyp = otmp->otyp; const char *zap_type_text = "spell"; struct obj *obj; @@ -192,6 +193,8 @@ struct obj *otmp; mon_adjust_speed(mtmp, 1, otmp); m_dowear(mtmp, FALSE); /* might want speed boots */ } + if (mtmp->mtame) + helpful_gesture = TRUE; break; case WAN_UNDEAD_TURNING: case SPE_TURN_UNDEAD: @@ -426,7 +429,7 @@ struct obj *otmp; } if (wake) { if (mtmp->mhp > 0) { - wakeup(mtmp, TRUE); + wakeup(mtmp, helpful_gesture ? FALSE : TRUE); m_respond(mtmp); if (mtmp->isshk && !*u.ushops) hot_pursuit(mtmp); From 4f459a9532e5b15272261635f315e2a5906e3771 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 10 Mar 2018 21:48:22 +0200 Subject: [PATCH 55/57] Fix WINCHAIN compilation --- include/winprocs.h | 2 +- win/chain/wc_chainout.c | 2 +- win/chain/wc_trace.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/winprocs.h b/include/winprocs.h index 4d0d395a1..3c19d4f03 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -359,7 +359,7 @@ struct chain_procs { void FDECL((*win_status_finish), (CARGS)); void FDECL((*win_status_enablefield), (CARGS, int, const char *, const char *, BOOLEAN_P)); - void FDECL((*win_status_update), (CARGS, int, genericptr_t, int, int, int, unsigned long)); + void FDECL((*win_status_update), (CARGS, int, genericptr_t, int, int, int, unsigned long *)); boolean FDECL((*win_can_suspend), (CARGS)); }; #endif /* WINCHAIN */ diff --git a/win/chain/wc_chainout.c b/win/chain/wc_chainout.c index 593bd6cd8..af964438c 100644 --- a/win/chain/wc_chainout.c +++ b/win/chain/wc_chainout.c @@ -620,7 +620,7 @@ boolean enable; void chainout_status_update(vp, idx, ptr, chg, percent, color, colormasks) void *vp; -int idx, chg, percent; +int idx, chg, percent, color; genericptr_t ptr; unsigned long *colormasks; { diff --git a/win/chain/wc_trace.c b/win/chain/wc_trace.c index 60877623d..ec81f0a8b 100644 --- a/win/chain/wc_trace.c +++ b/win/chain/wc_trace.c @@ -1083,9 +1083,9 @@ boolean enable; } void -trace_status_update(vp, idx, ptr, chg, color, colormasks) +trace_status_update(vp, idx, ptr, chg, percent, color, colormasks) void *vp; -int idx, chg, percent; +int idx, chg, percent, color; genericptr_t ptr; unsigned long *colormasks; { @@ -1095,7 +1095,7 @@ unsigned long *colormasks; ptr, chg, percent); PRE; - (*tdp->nprocs->win_status_update)(tdp->ndata, idx, ptr, chg, color colormasks); + (*tdp->nprocs->win_status_update)(tdp->ndata, idx, ptr, chg, percent, color, colormasks); POST; } From ddb830911e10d0e1596da4977503b8067e4e8012 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 10 Mar 2018 12:32:52 -0800 Subject: [PATCH 56/57] more Unix gitinfo When make uses 'makedefs -v' to create date.h, force it to create gitinfo.txt all the time instead of just when that doesn't already exist. Use 'make GITINFO=0' to get the previous behavior. To skip it entirely, you need to do that and also make sure that some file by that name already exists. 'touch dat/gitinfo.txt' or perhaps 'echo "#no git" > dat/gitinfo.txt' would suffice. --- sys/unix/Makefile.src | 10 +++++++++- sys/unix/gitinfo.sh | 7 +++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index f6b9371bc..56fef8b86 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -332,6 +332,14 @@ RANDOBJ = # used by `make depend' to reconstruct this Makefile; you shouldn't need this AWK = nawk +# when using 'makedefs -v', also force dat/gitinfo.txt to be up to date; +# changing this to 0 will change the behavior to only make that file if +# it doesn't already exist; to skip it completely, create an empty file +# of that name and also set this to 0; there shouldn't be any need to +# skip it--if nethack's sources don't reside in a git repository than +# the script which creates that file will fail benignly and 'makedefs -v' +# will proceed without it +GITINFO=1 #VERBOSEMAKE = 1 @@ -612,7 +620,7 @@ tile.c: ../win/share/tilemap.c $(HACK_H) # hack.h depends on makedefs' output, so we know makedefs will be # up to date before being executed ../include/date.h: $(VERSOURCES) $(HACK_H) - -$(SHELL) ../sys/unix/gitinfo.sh #../dat/gitinfo.txt for 'makedefs -v' + -$(SHELL) ../sys/unix/gitinfo.sh $(GITINFO) #before 'makedefs -v' ../util/makedefs -v diff --git a/sys/unix/gitinfo.sh b/sys/unix/gitinfo.sh index 72d300454..5cdb34715 100755 --- a/sys/unix/gitinfo.sh +++ b/sys/unix/gitinfo.sh @@ -1,7 +1,7 @@ #!/bin/sh # NetHack 3.6 gitinfo.sh $NHDT-Date: 1520201830 2018/03/04 22:17:10 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.0 $ -# if dat/gitinfo.txt doesn't exist, try to make one; called from Makefile.src +# bring dat/gitinfo.txt up to date; called from Makefile.src # # gitinfo.txt is used during development to augment the version number @@ -10,13 +10,16 @@ # this script to be skipped or to run but fail to generate dat/gitinfo.txt. # +always=0 +if [[ $1 -eq 1 || $1 == "force" || $1 == "always" ]]; then always=1; fi + # try to figure out where we are: top, one level down (expected), or sys/unix prefix=. if [ -f ../sys/unix/gitinfo.sh ]; then prefix=..; fi if [ -f ../../sys/unix/gitinfo.sh ]; then prefix=../..; fi # try to run a perl script which is part of nethack's git repository -if [[ ! -f $prefix/dat/gitinfo.txt ]]; then +if [[ $always -eq 1 || ! -f $prefix/dat/gitinfo.txt ]]; then ( cd $prefix; \ perl -IDEVEL/hooksdir -MNHgithook -e '&NHgithook::nhversioning' \ 2> /dev/null ) \ From f026e37573d5a468aec90cc30fe38b63c32b3911 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 10 Mar 2018 12:55:28 -0800 Subject: [PATCH 57/57] last gitinfo bit? If dat/gitinfo.txt is being created from scratch, say so instead of saying "updated". --- DEVEL/hooksdir/NHgithook.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/DEVEL/hooksdir/NHgithook.pm b/DEVEL/hooksdir/NHgithook.pm index 2f14ae114..435fe6c8d 100644 --- a/DEVEL/hooksdir/NHgithook.pm +++ b/DEVEL/hooksdir/NHgithook.pm @@ -73,8 +73,10 @@ sub nhversioning { my $git_branch = `git rev-parse --abbrev-ref HEAD`; $git_branch =~ s/\s+//g; die "git rev-parse failed" unless(length $git_sha and length $git_branch); + my $exists = 0; if (open my $fh, '<', 'dat/gitinfo.txt') { + $exists = 1; my $hashok = 0; my $branchok = 0; while (my $line = <$fh>) { @@ -94,9 +96,10 @@ sub nhversioning { print "WARNING: Can't find dat directory\n" unless(-d "dat"); } if (open my $fh, '>', 'dat/gitinfo.txt') { + my $how = ($exists ? "updated" : "created"); print $fh 'githash='.$git_sha."\n"; print $fh 'gitbranch='.$git_branch."\n"; - print "dat/gitinfo.txt updated, githash=".$git_sha."\n"; + print "dat/gitinfo.txt ".$how.", githash=".$git_sha."\n"; } else { print "WARNING: Unable to open dat/gitinfo.txt: $!\n"; }