From fec245dba23bc4a6ffaef2700e1abc4cf0305ff0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 26 Jan 2018 08:01:03 -0500 Subject: [PATCH 01/20] Only update dat/gitinfo.txt if the hash is new --- DEVEL/hooksdir/NHgithook.pm | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) 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) = @_; From 9728616a2169d07574c032511a314273deb09bfc Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 26 Jan 2018 08:06:23 -0500 Subject: [PATCH 02/20] fix branch placement of change --- DEVEL/hooksdir/NHgithook.pm | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/DEVEL/hooksdir/NHgithook.pm b/DEVEL/hooksdir/NHgithook.pm index 1bb92cf7e..6024c1c03 100644 --- a/DEVEL/hooksdir/NHgithook.pm +++ b/DEVEL/hooksdir/NHgithook.pm @@ -60,36 +60,6 @@ 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) = @_; From d2245aab2959972da53f0466c6d3b14284b42861 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 26 Jan 2018 17:25:21 -0500 Subject: [PATCH 03/20] version output appearance bits --- include/extern.h | 2 +- src/version.c | 23 +++++++++++++++++------ sys/winnt/winnt.c | 14 +++++++------- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/include/extern.h b/include/extern.h index 6f355fa07..ce0b42008 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2567,7 +2567,7 @@ E unsigned long NDECL(get_current_feature_ver); E const char *FDECL(copyright_banner_line, (int)); #ifdef RUNTIME_PORT_ID -E void FDECL(append_port_id, (char *)); +E char *FDECL(get_port_id, (char *)); #endif /* ### video.c ### */ diff --git a/src/version.c b/src/version.c index 4567e30d7..19f74c265 100644 --- a/src/version.c +++ b/src/version.c @@ -15,8 +15,6 @@ #include "patchlevel.h" #endif -#define BETA_INFO "" - STATIC_DCL void FDECL(insert_rtoption, (char *)); /* fill buffer with short version (so caller can avoid including date.h) */ @@ -32,13 +30,26 @@ char * getversionstring(buf) char *buf; { + int details = 0; + Strcpy(buf, VERSION_ID); -#if defined(BETA) && defined(BETA_INFO) - Sprintf(eos(buf), " %s", BETA_INFO); -#endif #if defined(RUNTIME_PORT_ID) - append_port_id(buf); + details++; #endif + + if (details) { + int c = 0; + char tmpbuf[BUFSZ]; + char *tmp = (char *)0; + + Sprintf(eos(buf), " ("); +#if defined(RUNTIME_PORT_ID) + tmp = get_port_id(tmpbuf); + if (tmp) + Sprintf(eos(buf), "%s%s", c++ ? "," : "", tmp); +#endif + Sprintf(eos(buf), ")"); + } return buf; } diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index 892744432..842bfd036 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -326,23 +326,23 @@ int interjection_type; */ #ifndef _M_IX86 #ifdef _M_X64 -#define TARGET_PORT "(x64) " +#define TARGET_PORT "x64" #endif #ifdef _M_IA64 -#define TARGET_PORT "(IA64) " +#define TARGET_PORT "IA64" #endif #endif #ifndef TARGET_PORT -#define TARGET_PORT "(x86) " +#define TARGET_PORT "x86" #endif -void -append_port_id(buf) +char * +get_port_id(buf) char *buf; { - char *portstr = TARGET_PORT; - Sprintf(eos(buf), " %s", portstr); + Strcpy(buf, TARGET_PORT); + return buf; } #endif /* RUNTIME_PORT_ID */ From baba2acb8ddadcdb3e5c357377cbcb9d517588f5 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 28 Jan 2018 00:38:08 -0800 Subject: [PATCH 04/20] fix #6691 and a couple other twoweap issues Report was for dual-wielding hitting an enchanter and assumed that a resistant artifact as primary weapon was protecting vulnerable secondary weapon. Actual reason was simpler. When in normal form, dual-wielding attacks against creatures which cause erosion to the weapon which hits them would only inflict the passive erosion damage to the primary weapon, even if it missed and secondary hit. Make primary attack always trigger passive counter- attack--before second swing now, rather than after--even if it misses, and secondary attack trigger another one if that hits. Both weapons are now subject to passive erosion (but only when they actually hit); when secondary weapon hits, hero gets a double dose of counter-attack. Hero poly'd into a monster with multiple weapon attacks (various leaders: dwarf lord, orc-captain, and so forth) would try to emulate dual wielding and first hit with uwep then with uswapwep. But it would do that even if uswapwep was a bow or stack of darts that the player had no itention of using for hand-to-hand. Stick with repeat hits by uwep when uswapwep seems inappropriate. Splitting a pudding while dual-wielding would only do so when hit by uwep of appropriate material, never when hit by uswapwep. So silver saber and longsword could split if longsword was primary but never split if saber was primary. Check material and splitting separately for each hit. It's now possible to split twice with one dual-weapon attack if both weapons hit and both are made of the right material (iron or 'metal'; among relevant objects the latter is only used for tsurugi and scapel). --- include/extern.h | 9 ++-- src/dokick.c | 18 ++++---- src/uhitm.c | 105 +++++++++++++++++++++++++++++------------------ 3 files changed, 79 insertions(+), 53 deletions(-) diff --git a/include/extern.h b/include/extern.h index ce0b42008..afbf4e498 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1514769568 2018/01/01 01:19:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.622 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1517128658 2018/01/28 08:37:38 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.624 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2473,13 +2473,14 @@ E void NDECL(u_init); E void FDECL(erode_armor, (struct monst *, int)); E boolean FDECL(attack_checks, (struct monst *, struct obj *)); E void FDECL(check_caitiff, (struct monst *)); -E int FDECL(find_roll_to_hit, - (struct monst *, UCHAR_P, struct obj *, int *, int *)); +E int FDECL(find_roll_to_hit, (struct monst *, UCHAR_P, struct obj *, + int *, int *)); E boolean FDECL(attack, (struct monst *)); E boolean FDECL(hmon, (struct monst *, struct obj *, int, int)); E int FDECL(damageum, (struct monst *, struct attack *)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); -E int FDECL(passive, (struct monst *, BOOLEAN_P, int, UCHAR_P, BOOLEAN_P)); +E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, + UCHAR_P, BOOLEAN_P)); E void FDECL(passive_obj, (struct monst *, struct obj *, struct attack *)); E void FDECL(stumble_onto_mimic, (struct monst *)); E int FDECL(flash_hits_mon, (struct monst *, struct obj *)); diff --git a/src/dokick.c b/src/dokick.c index 7aa8e2baa..c1976dbc8 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dokick.c $NHDT-Date: 1446955295 2015/11/08 04:01:35 $ $NHDT-Branch: master $:$NHDT-Revision: 1.104 $ */ +/* NetHack 3.6 dokick.c $NHDT-Date: 1517128663 2018/01/28 08:37:43 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.113 $ */ /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -116,7 +116,7 @@ register boolean clumsy; } } - (void) passive(mon, TRUE, mon->mhp > 0, AT_KICK, FALSE); + (void) passive(mon, uarmf, TRUE, mon->mhp > 0, AT_KICK, FALSE); if (mon->mhp <= 0 && !trapkilled) killed(mon); @@ -162,7 +162,7 @@ xchar x, y; && !is_flyer(mon->data)) { pline("Floating in the air, you miss wildly!"); exercise(A_DEX, FALSE); - (void) passive(mon, FALSE, 1, AT_KICK, FALSE); + (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE); return; } @@ -213,13 +213,13 @@ xchar x, y; } else if (tmp > (kickdieroll = rnd(20))) { You("kick %s.", mon_nam(mon)); sum = damageum(mon, uattk); - (void) passive(mon, (boolean) (sum > 0), (sum != 2), AT_KICK, - FALSE); + (void) passive(mon, uarmf, (boolean) (sum > 0), + (sum != 2), AT_KICK, FALSE); if (sum == 2) break; /* Defender died */ } else { missum(mon, uattk, (tmp + armorpenalty > kickdieroll)); - (void) passive(mon, FALSE, 1, AT_KICK, FALSE); + (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE); } } return; @@ -233,7 +233,7 @@ xchar x, y; if (martial() && !rn2(2)) goto doit; Your("clumsy kick does no damage."); - (void) passive(mon, FALSE, 1, AT_KICK, FALSE); + (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE); return; } if (i < j / 10) @@ -257,7 +257,7 @@ doit: if (!nohands(mon->data) && !rn2(martial() ? 5 : 3)) { pline("%s blocks your %skick.", Monnam(mon), clumsy ? "clumsy " : ""); - (void) passive(mon, FALSE, 1, AT_KICK, FALSE); + (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE); return; } else { maybe_mnexto(mon); @@ -274,7 +274,7 @@ doit: ? "slides" : "jumps", clumsy ? "easily" : "nimbly", clumsy ? "clumsy " : ""); - (void) passive(mon, FALSE, 1, AT_KICK, FALSE); + (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE); return; } } diff --git a/src/uhitm.c b/src/uhitm.c index df0645b96..daa069cc4 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 uhitm.c $NHDT-Date: 1513297347 2017/12/15 00:22:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.172 $ */ +/* NetHack 3.6 uhitm.c $NHDT-Date: 1517128664 2018/01/28 08:37:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.173 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -392,11 +392,10 @@ register struct monst *mtmp; unweapon = FALSE; if (flags.verbose) { if (uwep) - You("begin bashing monsters with %s.", - yobjnam(uwep, (char *) 0)); + You("begin bashing monsters with %s.", yname(uwep)); else if (!cantwield(youmonst.data)) - You("begin %sing monsters with your %s %s.", - Role_if(PM_MONK) ? "strik" : "bash", + You("begin %s monsters with your %s %s.", + ing_suffix(Role_if(PM_MONK) ? "strike" : "bash"), uarmg ? "gloved" : "bare", /* Del Lamb */ makeplural(body_part(HAND))); } @@ -541,7 +540,7 @@ struct attack *uattk; mhit = (tmp > dieroll); result = known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty, uattk, dieroll); - (void) passive(mtmp, mhit, DEADMONSTER(mtmp), AT_WEAP, !uwep); + (void) passive(mtmp, uwep, mhit, DEADMONSTER(mtmp), AT_WEAP, !uwep); if (mon == mtmp) malive = result; } @@ -570,6 +569,10 @@ struct attack *uattk; if (tmp > dieroll) exercise(A_DEX, TRUE); malive = known_hitum(mon, uwep, &mhit, tmp, armorpenalty, uattk, dieroll); + if (wepbefore && !uwep) + wep_was_destroyed = TRUE; + (void) passive(mon, uwep, mhit, malive, AT_WEAP, wep_was_destroyed); + /* second attack for two-weapon combat; won't occur if Stormbringer overrode confirmation (assumes Stormbringer is primary weapon) or if the monster was killed or knocked to different location */ @@ -580,10 +583,10 @@ struct attack *uattk; mhit = (tmp > dieroll || u.uswallow); malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk, dieroll); + /* second passive counter-attack only occurs if second attack hits */ + if (mhit) + (void) passive(mon, uswapwep, mhit, malive, AT_WEAP, !uswapwep); } - if (wepbefore && !uwep) - wep_was_destroyed = TRUE; - (void) passive(mon, mhit, malive, AT_WEAP, wep_was_destroyed); return malive; } @@ -1157,8 +1160,9 @@ int dieroll; if ((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING]) /* pudding is alive and healthy enough to split */ && mon->mhp > 1 && !mon->mcan - /* iron weapon using melee or polearm hit [3.6.1: metal weapon too] */ - && obj && obj == uwep + /* iron weapon using melee or polearm hit [3.6.1: metal weapon too; + also allow either or both weapons to cause split when twoweap] */ + && obj && (obj == uwep || (u.twoweap && obj == uswapwep)) && ((objects[obj->otyp].oc_material == IRON /* allow scalpel and tsurugi to split puddings */ || objects[obj->otyp].oc_material == METAL) @@ -1166,7 +1170,12 @@ int dieroll; && !(is_ammo(obj) || is_missile(obj))) && hand_to_hand) { if (clone_mon(mon, 0, 0)) { - pline("%s divides as you hit it!", Monnam(mon)); + char withwhat[BUFSZ]; + + withwhat[0] = '\0'; + if (u.twoweap && flags.verbose) + Sprintf(withwhat, " with %s", yname(obj)); + pline("%s divides as you hit it%s!", Monnam(mon), withwhat); hittxt = TRUE; } } @@ -2186,7 +2195,7 @@ hmonas(mon) register struct monst *mon; { struct attack *mattk, alt_attk; - struct obj *weapon; + struct obj *weapon, **originalweapon; boolean altwep = FALSE, weapon_used = FALSE; int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0; int dieroll; @@ -2194,6 +2203,7 @@ register struct monst *mon; for (i = 0; i < NATTK; i++) { sum[i] = 0; mattk = getmattk(&youmonst, mon, i, sum, &alt_attk); + weapon = 0; switch (mattk->aatyp) { case AT_WEAP: use_weapon: @@ -2208,20 +2218,36 @@ register struct monst *mon; * we currently allow the player to get each of these as a weapon * attack. Is this really desirable? */ - /* approximate two-weapon mode */ - weapon = (altwep && uswapwep) ? uswapwep : uwep; - altwep = !altwep; /* toggle for next attack */ + /* approximate two-weapon mode; known_hitum() -> hmon() -> &c + might destroy the weapon argument, but it might also already + be Null, and we want to track that for passive() */ + originalweapon = (altwep && uswapwep) ? &uswapwep : &uwep; + if (uswapwep /* set up 'altwep' flag for next iteration */ + /* only switch to uswapwep if it's a weapon */ + && (uswapwep->oclass == WEAPON_CLASS || is_weptool(uswapwep)) + /* only switch if uswapwep is not bow, arrows, or darts */ + && !(is_launcher(uswapwep) || is_ammo(uswapwep) + || is_missile(uswapwep))) /* dart, shuriken, boomerang */ + altwep = !altwep; /* toggle for next attack */ + weapon = *originalweapon; + if (!weapon) /* no need to go beyond no-gloves to rings; not ...*/ + originalweapon = &uarmg; /*... subject to erosion damage */ + tmp = find_roll_to_hit(mon, AT_WEAP, weapon, &attknum, &armorpenalty); dieroll = rnd(20); dhit = (tmp > dieroll || u.uswallow); /* Enemy dead, before any special abilities used */ - if (!known_hitum(mon, weapon, &dhit, tmp, armorpenalty, mattk, - dieroll)) { + if (!known_hitum(mon, weapon, &dhit, tmp, + armorpenalty, mattk, dieroll)) { sum[i] = 2; break; } else sum[i] = dhit; + /* originalweapon points to an equipment slot which might + now be empty if the weapon was destroyed during the hit; + passive(,weapon,...) won't call passive_obj() in that case */ + weapon = *originalweapon; /* might receive passive erosion */ /* might be a worm that gets cut in half */ if (m_at(u.ux + u.dx, u.uy + u.dy) != mon) return (boolean) (nsum != 0); @@ -2366,11 +2392,11 @@ register struct monst *mon; u.mh = -1; /* dead in the current form */ rehumanize(); } - if (sum[i] == 2) - return (boolean) passive(mon, 1, 0, mattk->aatyp, FALSE); - /* defender dead */ - else { - (void) passive(mon, sum[i], 1, mattk->aatyp, FALSE); + if (sum[i] == 2) { + /* defender dead */ + return (boolean) passive(mon, weapon, 1, 0, mattk->aatyp, FALSE); + } else { + (void) passive(mon, weapon, sum[i], 1, mattk->aatyp, FALSE); nsum |= sum[i]; } if (!Upolyd) @@ -2384,10 +2410,11 @@ register struct monst *mon; /* Special (passive) attacks on you by monsters done here. */ int -passive(mon, mhit, malive, aatyp, wep_was_destroyed) -register struct monst *mon; -register boolean mhit; -register int malive; +passive(mon, weapon, mhit, malive, aatyp, wep_was_destroyed) +struct monst *mon; +struct obj *weapon; /* uwep or uswapwep or uarmg or uarmf or Null */ +boolean mhit; +int malive; uchar aatyp; boolean wep_was_destroyed; { @@ -2412,14 +2439,14 @@ boolean wep_was_destroyed; */ switch (ptr->mattk[i].adtyp) { case AD_FIRE: - if (mhit && !mon->mcan) { + if (mhit && !mon->mcan && weapon) { if (aatyp == AT_KICK) { if (uarmf && !rn2(6)) (void) erode_obj(uarmf, xname(uarmf), ERODE_BURN, EF_GREASE | EF_VERBOSE); } else if (aatyp == AT_WEAP || aatyp == AT_CLAW || aatyp == AT_MAGC || aatyp == AT_TUCH) - passive_obj(mon, (struct obj *) 0, &(ptr->mattk[i])); + passive_obj(mon, weapon, &(ptr->mattk[i])); } break; case AD_ACID: @@ -2435,14 +2462,14 @@ boolean wep_was_destroyed; if (!rn2(30)) erode_armor(&youmonst, ERODE_CORRODE); } - if (mhit) { + if (mhit && weapon) { if (aatyp == AT_KICK) { if (uarmf && !rn2(6)) (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE, EF_GREASE | EF_VERBOSE); } else if (aatyp == AT_WEAP || aatyp == AT_CLAW || aatyp == AT_MAGC || aatyp == AT_TUCH) - passive_obj(mon, (struct obj *) 0, &(ptr->mattk[i])); + passive_obj(mon, weapon, &(ptr->mattk[i])); } exercise(A_STR, FALSE); break; @@ -2471,25 +2498,25 @@ boolean wep_was_destroyed; } break; case AD_RUST: - if (mhit && !mon->mcan) { + if (mhit && !mon->mcan && weapon) { if (aatyp == AT_KICK) { if (uarmf) (void) erode_obj(uarmf, xname(uarmf), ERODE_RUST, EF_GREASE | EF_VERBOSE); } else if (aatyp == AT_WEAP || aatyp == AT_CLAW || aatyp == AT_MAGC || aatyp == AT_TUCH) - passive_obj(mon, (struct obj *) 0, &(ptr->mattk[i])); + passive_obj(mon, weapon, &(ptr->mattk[i])); } break; case AD_CORR: - if (mhit && !mon->mcan) { + if (mhit && !mon->mcan && weapon) { if (aatyp == AT_KICK) { if (uarmf) (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE, EF_GREASE | EF_VERBOSE); } else if (aatyp == AT_WEAP || aatyp == AT_CLAW || aatyp == AT_MAGC || aatyp == AT_TUCH) - passive_obj(mon, (struct obj *) 0, &(ptr->mattk[i])); + passive_obj(mon, weapon, &(ptr->mattk[i])); } break; case AD_MAGM: @@ -2504,17 +2531,14 @@ boolean wep_was_destroyed; break; case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ if (mhit) { - struct obj *obj = (struct obj *) 0; - if (aatyp == AT_KICK) { - obj = uarmf; - if (!obj) + if (!weapon) break; } else if (aatyp == AT_BITE || aatyp == AT_BUTT || (aatyp >= AT_STNG && aatyp < AT_WEAP)) { break; /* no object involved */ } - passive_obj(mon, obj, &(ptr->mattk[i])); + passive_obj(mon, weapon, &(ptr->mattk[i])); } break; default: @@ -2628,6 +2652,7 @@ struct attack *mattk; /* null means we find one internally */ struct permonst *ptr = mon->data; int i; + /* [this first bit is obsolete; we're not called with Null anymore] */ /* if caller hasn't specified an object, use uwep, uswapwep or uarmg */ if (!obj) { obj = (u.twoweap && uswapwep && !rn2(2)) ? uswapwep : uwep; From e95a7096634b0e5d9ddeaf617e52e88cd4099264 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 5 Feb 2018 16:36:35 -0800 Subject: [PATCH 05/20] fix #H4459 - shopkeeper/scare monster bug Reported about 18 months ago: standing on a scroll of scare monster while next to a shopkeeper who was blocking the shop entrance because hero was carrying unpaid shop goods would yield " turns to flee" but wouldn't move. This was a side-effect of making standing on scrolls of scare monster be stronger than on "Elbereth" when the latter was nerfed. Make shopkeepers inside their own shops and temple priests inside their own temples be immune to the effect of hero standing on scare monster. Also, make the Wizard, lawful minions, Angels of any alignment, the Riders, and shopkeepers and priests in their own special rooms (ie, all creatures that now ignore standing on scare monster) be immune to the fright effect of tooled horns. Innate magic resistance usually prevented them from being scared anyway, but make it explicit. Reading a scroll of scare monster or casting the spell of cause fear still rely on innate resistance to avoid chasing away those monsters. I'm not sure whether they should have the same adjustment. --- doc/fixes36.1 | 4 ++++ src/monmove.c | 19 ++++++++++++++----- src/music.c | 6 ++++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 28313a87c..9e430def8 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -503,6 +503,10 @@ a shop object stolen from outside the shop (via grappling hook) would be left "unpaid_cost: object wasn't on any bill" when looking at inventory a shop object stolen from outside the shop could trigger a crash if that shop had never been entered by the hero +shopkeepers in their own shop and priests in their own temple are no longer + frightened by hero standing on scroll of scare monster +the Wizard, Angels and lawful minions, the Riders, shopkeep/priest in own room + are never frightened by tooled horns Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/src/monmove.c b/src/monmove.c index 9febe3fc7..64f878246 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 monmove.c $NHDT-Date: 1512808567 2017/12/09 08:36:07 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.95 $ */ +/* NetHack 3.6 monmove.c $NHDT-Date: 1517877380 2018/02/06 00:36:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.96 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -135,11 +135,19 @@ int x, y; struct monst *mtmp; { /* creatures who are directly resistant to magical scaring: - * Rodney, lawful minions, angels, the Riders */ + * Rodney, lawful minions, Angels, the Riders, shopkeepers + * inside their own shop, priests inside their own temple */ if (mtmp->iswiz || is_lminion(mtmp) || mtmp->data == &mons[PM_ANGEL] - || is_rider(mtmp->data)) + || is_rider(mtmp->data) + || (mtmp->isshk && inhishop(mtmp)) + || (mtmp->ispriest && inhistemple(mtmp))) return FALSE; + /* <0,0> is used by musical scaring to check for the above; + * it doesn't care about scrolls or engravings or dungeon branch */ + if (x == 0 && y == 0) + return TRUE; + /* should this still be true for defiled/molochian altars? */ if (IS_ALTAR(levl[x][y].typ) && (mtmp->data->mlet == S_VAMPIRE || is_vampshifter(mtmp))) @@ -152,8 +160,9 @@ struct monst *mtmp; /* * Creatures who don't (or can't) fear a written Elbereth: - * all the above plus shopkeepers, guards, blind or - * peaceful monsters, humans, and minotaurs. + * all the above plus shopkeepers (even if poly'd into non-human), + * vault guards (also even if poly'd), blind or peaceful monsters, + * humans and elves, and minotaurs. * * If the player isn't actually on the square OR the player's image * isn't displaced to the square, no protection is being granted. diff --git a/src/music.c b/src/music.c index 68c9e97d5..6ecd43630 100644 --- a/src/music.c +++ b/src/music.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 music.c $NHDT-Date: 1514504228 2017/12/28 23:37:08 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.46 $ */ +/* NetHack 3.6 music.c $NHDT-Date: 1517877381 2018/02/06 00:36:21 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.47 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -76,7 +76,9 @@ int distance; && (mtmp->mstrategy & STRAT_WAITMASK) != 0) mtmp->mstrategy &= ~STRAT_WAITMASK; else if (distm < distance / 3 - && !resist(mtmp, TOOL_CLASS, 0, NOTELL)) + && !resist(mtmp, TOOL_CLASS, 0, NOTELL) + /* some monsters are immune */ + && onscary(0, 0, mtmp)) monflee(mtmp, 0, FALSE, TRUE); } } From f4b2b39931fe88eb0353af1e51032b00728c6eeb Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 6 Feb 2018 02:20:26 -0800 Subject: [PATCH 06/20] formatting bit for u_on_rndspot() Something trivial I noticed while looking into the stuck-in-wall situation. --- src/dungeon.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dungeon.c b/src/dungeon.c index ca3f7c32d..bb7bce9b1 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dungeon.c $NHDT-Date: 1491958681 2017/04/12 00:58:01 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.79 $ */ +/* NetHack 3.6 dungeon.c $NHDT-Date: 1517912411 2018/02/06 10:20:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.83 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1220,16 +1220,16 @@ int upflag; destination instead of its enclosing region. Note: up vs down doesn't matter in this case because both specify the same exclusion area. */ - place_lregion(dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy, 0, 0, 0, - 0, LR_DOWNTELE, (d_level *) 0); + place_lregion(dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy, + 0, 0, 0, 0, LR_DOWNTELE, (d_level *) 0); else if (up) - place_lregion(updest.lx, updest.ly, updest.hx, updest.hy, updest.nlx, - updest.nly, updest.nhx, updest.nhy, LR_UPTELE, - (d_level *) 0); + place_lregion(updest.lx, updest.ly, updest.hx, updest.hy, + updest.nlx, updest.nly, updest.nhx, updest.nhy, + LR_UPTELE, (d_level *) 0); else - place_lregion(dndest.lx, dndest.ly, dndest.hx, dndest.hy, dndest.nlx, - dndest.nly, dndest.nhx, dndest.nhy, LR_DOWNTELE, - (d_level *) 0); + place_lregion(dndest.lx, dndest.ly, dndest.hx, dndest.hy, + dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy, + LR_DOWNTELE, (d_level *) 0); } /* place you on the special staircase */ From 1b8df876c347475384d6d140569dc750c471ec25 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 6 Feb 2018 02:41:31 -0800 Subject: [PATCH 07/20] some more reformatting, dig.c A bit more ambitious this time, but not much. --- src/dig.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/dig.c b/src/dig.c index 497de8cd4..0886ed477 100644 --- a/src/dig.c +++ b/src/dig.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dig.c $NHDT-Date: 1449269915 2015/12/04 22:58:35 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.103 $ */ +/* NetHack 3.6 dig.c $NHDT-Date: 1517913682 2018/02/06 10:41:22 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.108 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -708,8 +708,8 @@ int ttyp; } if (mtmp->isshk) make_angry_shk(mtmp, 0, 0); - migrate_to_level(mtmp, ledger_no(&tolevel), MIGR_RANDOM, - (coord *) 0); + migrate_to_level(mtmp, ledger_no(&tolevel), + MIGR_RANDOM, (coord *) 0); } } } @@ -842,7 +842,7 @@ coord *cc; "As you dig, the hole fills with %s!"); return TRUE; - /* the following two are here for the wand of digging */ + /* the following two are here for the wand of digging */ } else if (IS_THRONE(lev->typ)) { pline_The("throne is too hard to break apart."); @@ -914,9 +914,8 @@ coord *cc; case 0: case 1: You("unearth a corpse."); - if (!!(otmp = mk_tt_object(CORPSE, dig_x, dig_y))) + if ((otmp = mk_tt_object(CORPSE, dig_x, dig_y)) != 0) otmp->age -= 100; /* this is an *OLD* corpse */ - ; break; case 2: if (!Blind) @@ -1069,13 +1068,14 @@ struct obj *obj; } else if (lev->typ == IRONBARS) { pline("Clang!"); wake_nearby(); - } else if (IS_TREE(lev->typ)) + } else if (IS_TREE(lev->typ)) { You("need an axe to cut down a tree."); - else if (IS_ROCK(lev->typ)) + } else if (IS_ROCK(lev->typ)) { You("need a pick to dig rock."); - else if (!ispick && (sobj_at(STATUE, rx, ry) - || sobj_at(BOULDER, rx, ry))) { + } else if (!ispick && (sobj_at(STATUE, rx, ry) + || sobj_at(BOULDER, rx, ry))) { boolean vibrate = !rn2(3); + pline("Sparks fly as you whack the %s.%s", sobj_at(STATUE, rx, ry) ? "statue" : "boulder", vibrate ? " The axe-handle vibrates violently!" : ""); @@ -1087,6 +1087,7 @@ struct obj *obj; && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) && !conjoined_pits(trap, trap_with_u, FALSE)) { int idx; + for (idx = 0; idx < 8; idx++) { if (xdir[idx] == u.dx && ydir[idx] == u.dy) break; @@ -1094,6 +1095,7 @@ struct obj *obj; /* idx is valid if < 8 */ if (idx < 8) { int adjidx = (idx + 4) % 8; + trap_with_u->conjoined |= (1 << idx); trap->conjoined |= (1 << adjidx); pline("You clear some debris from between the pits."); @@ -1102,21 +1104,24 @@ struct obj *obj; && (trap_with_u = t_at(u.ux, u.uy))) { You("swing %s, but the rubble has no place to go.", yobjnam(obj, (char *) 0)); - } else + } else { You("swing %s through thin air.", yobjnam(obj, (char *) 0)); + } } else { static const char *const d_action[6] = { "swinging", "digging", "chipping the statue", "hitting the boulder", "chopping at the door", "cutting the tree" }; + did_dig_msg = FALSE; context.digging.quiet = FALSE; if (context.digging.pos.x != rx || context.digging.pos.y != ry || !on_level(&context.digging.level, &u.uz) || context.digging.down) { if (flags.autodig && dig_target == DIGTYP_ROCK - && !context.digging.down && context.digging.pos.x == u.ux + && !context.digging.down + && context.digging.pos.x == u.ux && context.digging.pos.y == u.uy && (moves <= context.digging.lastdigtime + 2 && moves >= context.digging.lastdigtime)) { @@ -1271,8 +1276,9 @@ register struct monst *mtmp; newsym(mtmp->mx, mtmp->my); draft_message(FALSE); /* "You feel a draft." */ return FALSE; - } else if (!IS_ROCK(here->typ) && !IS_TREE(here->typ)) /* no dig */ + } else if (!IS_ROCK(here->typ) && !IS_TREE(here->typ)) { /* no dig */ return FALSE; + } /* Only rock, trees, and walls fall through to this point. */ if ((here->wall_info & W_NONDIGGABLE) != 0) { From b5b513fb444b6a3001b90e6373fbe488e437c392 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 7 Feb 2018 17:31:44 -0800 Subject: [PATCH 08/20] 'Iu' vs unknown container contents An inventory of unpaid items where more than one was present would show |> bag's contents N zorkmids if any of the items were inside a container whose contents aren't known. But if there was only one item (so container must be owned by hero) the 'Iu' output menu was skipped for pline and yielded |> scroll of magic mapping 133 zorkmids Force the menu display if the lone unpaid item is inside a container whose contents are unknown. I'm not sure whether a hero-owned container can have both unknown contents and an unpaid item in normal play. I managed it while trying to fix a reported problem--except I can no longer find the relevant report--where itemized shop billing also revealed unseen container contents (for any number of items, not just 1). That isn't fixed yet, but I want to get the simpler 'Iu' part out of the way. --- doc/fixes36.1 | 2 ++ include/extern.h | 3 ++- src/invent.c | 14 +++++++++----- src/mkobj.c | 19 ++++++++++++++++++- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 9e430def8..9b8633956 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -507,6 +507,8 @@ shopkeepers in their own shop and priests in their own temple are no longer frightened by hero standing on scroll of scare monster 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 Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index afbf4e498..24a0c06cd 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1517128658 2018/01/28 08:37:38 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.624 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1518053385 2018/02/08 01:29:45 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.625 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1284,6 +1284,7 @@ E struct obj *FDECL(splitobj, (struct obj *, long)); E struct obj *FDECL(unsplitobj, (struct obj *)); E void NDECL(clear_splitobjs); E void FDECL(replace_object, (struct obj *, struct obj *)); +E struct obj *FDECL(unknwn_contnr_contents, (struct obj *)); E void FDECL(bill_dummy_object, (struct obj *)); E void FDECL(costly_alteration, (struct obj *, int)); E struct obj *FDECL(mksobj, (int, BOOLEAN_P, BOOLEAN_P)); diff --git a/src/invent.c b/src/invent.c index 89d823eec..828a947df 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 invent.c $NHDT-Date: 1512473628 2017/12/05 11:33:48 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.223 $ */ +/* NetHack 3.6 invent.c $NHDT-Date: 1518053384 2018/02/08 01:29:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.224 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2541,22 +2541,26 @@ STATIC_OVL void dounpaid() { winid win; - struct obj *otmp, *marker; + struct obj *otmp, *marker, *contnr; register char ilet; char *invlet = flags.inv_order; int classcount, count, num_so_far; long cost, totcost; count = count_unpaid(invent); + otmp = marker = contnr = (struct obj *) 0; if (count == 1) { - marker = (struct obj *) 0; otmp = find_unpaid(invent, &marker); + contnr = unknwn_contnr_contents(otmp); + } + if (otmp && !contnr) { + /* 1 item; use pline instead of popup menu */ cost = unpaid_cost(otmp, FALSE); iflags.suppress_price++; /* suppress "(unpaid)" suffix */ pline1(xprname(otmp, distant_name(otmp, doname), - carried(otmp) ? otmp->invlet : CONTAINED_SYM, TRUE, - cost, 0L)); + carried(otmp) ? otmp->invlet : CONTAINED_SYM, + TRUE, cost, 0L)); iflags.suppress_price--; return; } diff --git a/src/mkobj.c b/src/mkobj.c index 567b84528..ee6928111 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1513298759 2017/12/15 00:45:59 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.129 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1518053380 2018/02/08 01:29:40 $ $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. */ @@ -579,6 +579,23 @@ struct obj *otmp; } } +/* is 'obj' inside a container whose contents aren't known? + if so, return the outermost container meeting that criterium */ +struct obj * +unknwn_contnr_contents(obj) +struct obj *obj; +{ + struct obj *result = 0, *parent; + + while (obj->where == OBJ_CONTAINED) { + parent = obj->ocontainer; + if (!parent->cknown) + result = parent; + obj = parent; + } + return result; +} + /* * Create a dummy duplicate to put on shop bill. The duplicate exists * only in the billobjs chain. This function is used when a shop object From e181f1acf9524b502df8bcdf9c4fa8346ec2f317 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 9 Feb 2018 18:57:43 -0500 Subject: [PATCH 09/20] command line Makefile update for vs compiler --- sys/winnt/Makefile.msc | 163 ++++++++++++++++++++++++----------------- 1 file changed, 97 insertions(+), 66 deletions(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index f34fb4027..588a393b2 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -1,5 +1,5 @@ -# NetHack 3.6 Makefile.msc $NHDT-Date: 1451610993 2016/01/01 01:16:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.101 $ */ -# Copyright (c) NetHack PC Development Team 1993-2017 +# NetHack 3.6 Makefile.msc $NHDT-Date: 1518220654 2018/02/09 23:57:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.105 $ */ +# Copyright (c) NetHack PC Development Team 1993-2018 # #============================================================================== # Build Tools Environment @@ -29,70 +29,38 @@ # # If you have any questions read the sys/winnt/Install.nt file included # with the distribution. -#============================================================================== -# Before we get started, this section is used to determine the version of -# Visual Studio we are using. We set VSVER to 0000 to flag any version that -# is too old or untested. -# - -!IF "$(_NMAKE_VER)" == "14.11.25547.0" -VSVER=2017 -!ELSEIF "$(_NMAKE_VER)" == "14.00.22310.1" -VSVER=2015 -!ELSEIF "$(_NMAKE_VER)" == "12.00.21005.1" -VSVER=2013 -!ELSEIF "$(_NMAKE_VER)" == "11.00.50727.1" -VSVER=2012 -!ELSEIF "$(_NMAKE_VER)" == "10.00.40219.01" -VSVER=2010 -!ELSE -VSVER=0000 #untested version -!ENDIF - -#============================================================================== +#======================================================================================== # BUILD DECISIONS SECTION # -# There are currently only 3 decisions that you have to make. -# 1. 32-bit or 64-bit? -# 2. Where do you want your build to end up? -# 3. Do you want debug information in the executable? +# There are currently only 3 decisions that you can choose to make, and none are +# required: +# 1. Where do you want your build to end up? +# 2. Do you want debug information in the executable? +# 3. Do you want to explicitly override auto-detection of a 32-bit or 64-bit target? # +#----------------------------------------------------------------------------------------- +#========================================================================================= + #--------------------------------------------------------------- -#============================================================================== -# 1. 32-bit or 64-bit? (comment/uncomment appropriate TARGET_CPU line) -# +# 1. Where do you want the game to be built (which folder)? -!IF ($(VSVER) >= 2012) -# -# 64 bit -#TARGET_CPU=x64 -# -# 32 bit -TARGET_CPU=x86 - -!ELSE -!IF ($(VSVER) == 0000) -!ERROR Unsupported and untested version of Visual Studio -!ELSE -# For VS2010 use "setenv /x86" or "setenv /x64" before invoking make process -# DO NOT DELETE THE FOLLOWING LINE -!include -!ENDIF -!ENDIF -# +GAMEDIR = ..\binary # Default game build directory + #--------------------------------------------------------------- -# 2. Where do you want the game to be built (which folder)? -# - -GAMEDIR = ..\binary # Game directory - -# -#--------------------------------------------------------------- -# 3. Do you want debug information in the executable? -# +# 2. Do you want debug information available to the executable? DEBUGINFO = Y +#--------------------------------------------------------------- +# 3. This Makefile will attempt to auto-detect your selected target architecture +# based on Visual Studio command prompt configuration settins etc. +# However, if you want to manually override generation of a +# 32-bit or 64-bit build target, you can uncomment the apppropriate +# TARGET_CPU line below. +# +#TARGET_CPU=x64 +#TARGET_CPU=x86 + #============================================================================== # This marks the end of the BUILD DECISIONS section. #============================================================================== @@ -181,6 +149,76 @@ DLBFLG = #========================================== #========================================== +# Before we get started, this section is used to determine the version of +# Visual Studio we are using. We set VSVER to 0000 to flag any version that +# is too old or untested. +# + +#!MESSAGE $(MAKEFLAGS) +#!MESSAGE $(MAKEDIR) +#!MESSAGE $(MAKE) + +MAKEVERSION=$(_NMAKE_VER:.= ) +MAKEVERSION=$(MAKEVERSION: =) +#!MESSAGE $(_NMAKE_VER) +#!MESSAGE $(MAKEVERSION) + +VSNEWEST=2017 +!IF ($(MAKEVERSION) < 1000000000) +VSVER=0000 #untested ancient version +!ELSEIF ($(MAKEVERSION) > 1000000000) && ($(MAKEVERSION) < 1100000000) +VSVER=2010 +!ELSEIF ($(MAKEVERSION) > 1100000000) && ($(MAKEVERSION) < 1200000000) +VSVER=2012 +!ELSEIF ($(MAKEVERSION) > 1200000000) && ($(MAKEVERSION) < 1400000000) +VSVER=2013 +!ELSEIF ($(MAKEVERSION) > 1400000000) && ($(MAKEVERSION) < 1411000000) +VSVER=2015 +!ELSEIF ($(MAKEVERSION) > 1411000000) && ($(MAKEVERSION) < 1412258351) +VSVER=$(VSNEWEST) +!ELSEIF ($(MAKEVERSION) > 1412258350) +VSVER=2999 #untested future version +!ENDIF + +!IF ($(VSVER) >= 2012) +!MESSAGE Autodetected Visual Studio $(VSVER) +!ELSEIF ($(VSVER) == 2999 +!MESSAGE The version of Visual Studio is newer than the most recent at +!MESSAGE the time this Makefile was crafted (Visual Studio $(VSNEWEST)). +!MESSAGE Because it is newer we'll proceed expecting that the +!MESSAGE VS$(VSNEWEST) processing will still work. +!ELSEIF ($(VSVER) == 0000) +!MESSAGE The version of Visual Studio appears to be quite old, older +!MESSAGE than VS2010 which is the oldest supported version by this +!MESSAGE Makefile, so we'll stop now. +!ERROR Untested old Visual Studio version with NMAKE $(_NMAKE_VER). +!ENDIF + +!IF ($(VSVER) == 2010) +# For VS2010 use "setenv /x86" or "setenv /x64" before invoking make process +# DO NOT DELETE THE FOLLOWING LINE +!include +! ENDIF + +#---------------------------------------------------------------- + +#These will be in the environment variables with one of the VS2017 +#developer command prompts. +#VSCMD_ARG_HOST_ARCH=x64 +#VSCMD_ARG_TGT_ARCH=x86 + +!IFDEF VSCMD_ARG_HOST_ARCH +!MESSAGE Host architecture is $(VSCMD_ARG_HOST_ARCH) +!MESSAGE Target architecture is $(VSCMD_ARG_TGT_ARCH) +! IFNDEF TARGET_CPU +! IF "$(VSCMD_ARG_TGT_ARCH)"=="x64" +TARGET_CPU=x64 +! ELSE +TARGET_CPU=x86 +! ENDIF +! ENDIF +!ENDIF + !IF "$(TARGET_CPU)" == "" TARGET_CPU=x86 !ENDIF @@ -937,22 +975,15 @@ $(O)obj.tag: #========================================== envchk: -! IF ($(VSVER) < 2010) - @echo Your Visual Studio version is too old or untested ($(_NMAKE_VER)) -!ERROR Your Visual Studio version is too old or untested ($(_NMAKE_VER)) -! ENDIF ! IF "$(TARGET_CPU)"=="x64" - @echo Windows x64 64-bit build + @echo Windows x64 64-bit target build ! ELSE - @echo Windows x86 32-bit build + @echo Windows x86 32-bit target build ! ENDIF ! IF "$(CL)"!="" # @echo Warning, the CL Environment variable is defined: # @echo CL=$(CL) ! ENDIF - @echo ---- - @echo NOTE: This build will include tile support. - @echo ---- #========================================== #=========== SECONDARY TARGETS ============ From 687902d3ff9b85c58ec7ec6651c877fa7ae68d98 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 14 Feb 2018 18:38:35 -0800 Subject: [PATCH 10/20] fix #H4240 - linking on VAX/VMS First reported two years ago, then again this week by someone else who didn't go through the web contact page (so no new #H number or bugzilla entry). Using vmsbuild.com to build on VAX complains about not being able to resolve a bunch of functions--it's basically trying to build the full program using only the code supplied by sys/vms/vmsmain.c. The original report mentioned a workaround and was also dealing with a second issue (already fixed post-3.6.0) that I incorrectly guessed was responsible for the linking problem. This report had the correct linker magic to fix the linking issue. I'm still not sure whether the order of /Library and /Include after the name of an object library file on a LINK command line matters. In a linker options file, which vmsbuild.com constructs and uses, /Include needs to come first so that the contents of the library are searched after the explicitly included object modules are processed. Building with the Makefiles (using DEC's MMS or some versions of freeware MMK) doesn't collect the object files into a library so was never affected by this. And the linker options ordering issue is apparently specific to the VAX/VMS linker; vmsbuild.com run on Alpha and on IA64 linked 3.6.0 successfully without this fix. --- sys/vms/vmsbuild.com | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/vms/vmsbuild.com b/sys/vms/vmsbuild.com index 069af041b..c49329dd8 100755 --- a/sys/vms/vmsbuild.com +++ b/sys/vms/vmsbuild.com @@ -1,6 +1,6 @@ $ ! vms/vmsbuild.com -- compile and link NetHack 3.6.* [pr] $ version_number = "3.6.1" -$ ! $NHDT-Date: 1465133393 2016/06/05 13:29:53 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.15 $ +$ ! $NHDT-Date: 1518661015 2018/02/15 02:16:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.16 $ $ ! $ ! usage: $ ! $ set default [.src] !or [-.-.src] if starting from [.sys.vms] @@ -175,7 +175,7 @@ $ ! final setup $ nethacklib = "[-.src]nethack.olb" $ create nethack.opt ! nethack.opt -nethack.olb/Library/Include=(vmsmain) +nethack.olb/Include=(vmsmain)/Library sys$library:starlet.olb/Include=(lib$initialize) psect_attr=lib$initialize, Con,Usr,noPic,Rel,Gbl,noShr,noExe,Rd,noWrt,Long iosegment=128 From 2c21399a7e7d30cfb7ac3f46c2d5c329169d6dc4 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 15 Feb 2018 10:13:42 -0800 Subject: [PATCH 11/20] place_lregion() bug Noticed while looking into the TROUBLE_STUCK_IN_WALL prayer bug, place_lregion() has been using the wrong row for 'low y' in its whole-level handling, presumeably ever since it was first introduced. 3.4.3 definitely had the same bug; I didn't check any further back. For maze levels which only consider every other row and every other column to be viable locations this probably didn't matter. And even non-maze levels usually don't have anything on row 0, so this fix isn't likely to be noticeable. --- src/mkmaze.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/mkmaze.c b/src/mkmaze.c index 03d993590..b7a33a748 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkmaze.c $NHDT-Date: 1469930897 2016/07/31 02:08:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.50 $ */ +/* NetHack 3.6 mkmaze.c $NHDT-Date: 1518718417 2018/02/15 18:13:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.55 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -287,9 +287,9 @@ d_level *lev; return; } - lx = 1; + lx = 1; /* column 0 is not used */ hx = COLNO - 1; - ly = 1; + ly = 0; /* 3.6.0 and earlier erroneously had 1 here */ hy = ROWNO - 1; } @@ -305,11 +305,9 @@ d_level *lev; /* then a deterministic one */ - oneshot = TRUE; for (x = lx; x <= hx; x++) for (y = ly; y <= hy; y++) - if (put_lregion_here(x, y, nlx, nly, nhx, nhy, rtype, oneshot, - lev)) + if (put_lregion_here(x, y, nlx, nly, nhx, nhy, rtype, TRUE, lev)) return; impossible("Couldn't place lregion type %d!", rtype); From 12530cb155ec25295215853de80011f4a44e4e5b Mon Sep 17 00:00:00 2001 From: keni Date: Fri, 16 Feb 2018 12:07:37 -0500 Subject: [PATCH 12/20] infrastructure fixes: - fix bug in git hooks that loses file permissions when doing variable expansion - fix execute permissions on sys/unix/hints/macosx.sh - explicitly call out perl as required for hooks in Developer.txt --- DEVEL/Developer.txt | 11 +++++++---- DEVEL/hooksdir/nhsub | 5 ++++- sys/unix/hints/macosx.sh | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) mode change 100644 => 100755 sys/unix/hints/macosx.sh diff --git a/DEVEL/Developer.txt b/DEVEL/Developer.txt index b30fa06c9..1267ac073 100644 --- a/DEVEL/Developer.txt +++ b/DEVEL/Developer.txt @@ -4,7 +4,7 @@ |___/\___|\_/\___|_\___/ .__/\___|_| |_| -$NHDT-Date: 1447180052 2015/11/10 18:27:32 $ +$NHDT-Date: 1518800857 2018/02/16 17:07:37 $ Welcome to the NetHack Infrastructure Developer's Guide. @@ -43,12 +43,15 @@ us an email if that's more appropriate). ------------------------------------------------------------------------------ 4. git configuration -NOTE: These instructions assume you are on the default branch ("master"); - this _is_ where you want to be for setting things up. This may or may - not be the branch you want to use for your changes; see the appropriate +NOTE: These instructions assume you are on the default branch; this _is_ + where you want to be for setting things up. This may or may not be + the branch you want to use for your changes; see the appropriate project private documentation for more information (if you are working alone we suggest using branch names starting with "LOCAL-"). +NOTE: The following instructions require perl. If you do not have perl on + your system, please install it before proceeding. + A. If you have never set up git on this machine before: (This assumes you will only be using git for NetHack. If you are going to use it for other projects as well, think before you type.) diff --git a/DEVEL/hooksdir/nhsub b/DEVEL/hooksdir/nhsub index a1686bd24..f17322516 100644 --- a/DEVEL/hooksdir/nhsub +++ b/DEVEL/hooksdir/nhsub @@ -1,6 +1,6 @@ #!/usr/bin/perl # nhsub -# $NHDT-Date: 1427408239 2015/03/26 22:17:19 $ +# $NHDT-Date: 1518800857 2018/02/16 17:07:37 $ # Note: was originally called nhdate; the rename is not reflected in the code. @@ -245,6 +245,7 @@ my $count = s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\x24]+))?)\$/&handlevar($2 # XXX had o modifier, why? return unless($count>0); return if($opt{n}); + my $mode = 0777 & (stat($file))[2]; my $ofile = $file . ".nht"; open(TOUT, ">", $ofile) or die "Can't open $ofile"; @@ -263,6 +264,8 @@ my $count = s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\x24]+))?)\$/&handlevar($2 } close TOUT or die "Can't close $ofile"; + # Do the right thing for *nix and hope for the best elsewhere: + chmod($mode, $ofile)==1 or warn "Can't set filemode on $ofile"; rename $ofile, $file or die "Can't rename $ofile to $file"; } diff --git a/sys/unix/hints/macosx.sh b/sys/unix/hints/macosx.sh old mode 100644 new mode 100755 index 2bf2360d9..93e28ca51 --- 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: 1515549543 2018/01/10 01:59:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.18 $ +# NetHack 3.6 macosx.sh $NHDT-Date: 1518800856 2018/02/16 17:07:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.19 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # From 1eb5919a85cbd1c30b0c4fc86473807b8e7199ca Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 16 Feb 2018 14:52:02 -0500 Subject: [PATCH 13/20] I noticed makedefs was segfaulting when argc == 1 --- util/makedefs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/util/makedefs.c b/util/makedefs.c index f9bab0ef1..f3f7135be 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -256,11 +256,12 @@ main(argc, argv) int argc; char *argv[]; { - if ((argc != 2) + if ((argc == 1) || + ((argc != 2) #ifdef FILE_PREFIX && (argc != 3) #endif - && !(argv[1][0] == '-' && argv[1][1] == '-')) { + && !(argv[1][0] == '-' && argv[1][1] == '-'))) { Fprintf(stderr, "Bad arg count (%d).\n", argc - 1); (void) fflush(stderr); return 1; From 544b9015ff78a73ac91b5e76f6c3a1405e6f703f Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 17 Feb 2018 01:58:14 -0800 Subject: [PATCH 14/20] comment formatting Fix a few mis-indented comments I stumbled across. --- src/cmd.c | 6 +++--- src/hack.c | 21 ++++++++++----------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/cmd.c b/src/cmd.c index dc62c0ed3..da690f23e 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1513130017 2017/12/13 01:53:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.277 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1518861485 2018/02/17 09:58:05 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.278 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2767,7 +2767,7 @@ int final; if (!u.uconduct.food) enl_msg(You_, "have gone", "went", " without food", ""); - /* But beverages are okay */ + /* but beverages are okay */ else if (!u.uconduct.unvegan) you_have_X("followed a strict vegan diet"); else if (!u.uconduct.unvegetarian) @@ -4246,7 +4246,7 @@ register char *cmd; } else if (*cmd == ' ' && !flags.rest_on_space) { bad_command = TRUE; /* skip cmdlist[] loop */ - /* handle all other commands */ + /* handle all other commands */ } else { register const struct ext_func_tab *tlist; int res, NDECL((*func)); diff --git a/src/hack.c b/src/hack.c index f16ed1bf2..873f7549b 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 hack.c $NHDT-Date: 1512771130 2017/12/08 22:12:10 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.181 $ */ +/* NetHack 3.6 hack.c $NHDT-Date: 1518861490 2018/02/17 09:58:10 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.182 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1614,9 +1614,9 @@ domove() newsym(x, y); glyph = glyph_at(x, y); /* might have just changed */ - if (boulder) + if (boulder) { Strcpy(buf, ansimpleoname(boulder)); - else if (Underwater && !is_pool(x, y)) + } else if (Underwater && !is_pool(x, y)) { /* Underwater, targetting non-water; the map just shows blank because you don't see remembered terrain while underwater; although the hero can attack an adjacent monster this way, @@ -1624,21 +1624,20 @@ domove() Sprintf(buf, (Is_waterlevel(&u.uz) && levl[x][y].typ == AIR) ? "an air bubble" : "nothing"); - else if (solid) + } else if (solid) { /* glyph might indicate unseen terrain if hero is blind; unlike searching, this won't reveal what that terrain is (except for solid rock, where the glyph would otherwise yield ludicrous "dark part of a room") */ - Strcpy(buf, - (levl[x][y].typ == STONE) - ? "solid rock" - : glyph_is_cmap(glyph) + Strcpy(buf, (levl[x][y].typ == STONE) ? "solid rock" + : glyph_is_cmap(glyph) ? the(defsyms[glyph_to_cmap(glyph)].explanation) : (const char *) "an unknown obstacle"); - /* note: 'solid' is misleadingly named and catches pools - of water and lava as well as rock and walls */ - else + /* note: 'solid' is misleadingly named and catches pools + of water and lava as well as rock and walls */ + } else { Strcpy(buf, "thin air"); + } You("%s%s %s.", !(boulder || solid) ? "" : !explo ? "harmlessly " : "futilely ", explo ? "explode at" : "attack", buf); From 48af4fa25969df9b6bcdb211b01c6cc53094279f Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 17 Feb 2018 18:54:52 -0800 Subject: [PATCH 15/20] static analyzer bit I can't find the original message at the moment, but one of the things that an analyzer complained about was the *s='\0' possibly assigning to a Null pointer. The superfluous test of 's' in the while condition has fooled it into thinking that's possible when it's not. if (s) { while (s && ...) { *s++ = ... } *s = '\0'; } --- src/hacklib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hacklib.c b/src/hacklib.c index a5d9d0c15..382551822 100644 --- a/src/hacklib.c +++ b/src/hacklib.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 hacklib.c $NHDT-Date: 1496860756 2017/06/07 18:39:16 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.50 $ */ +/* NetHack 3.6 hacklib.c $NHDT-Date: 1518922474 2018/02/18 02:54:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.54 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Robert Patrick Rankin, 1991 */ /* NetHack may be freely redistributed. See license for details. */ @@ -451,7 +451,7 @@ const char *stuff_to_strip, *orig; char *s = bp; if (s) { - while (s && *orig && i < (BUFSZ - 1)) { + while (*orig && i < (BUFSZ - 1)) { if (!index(stuff_to_strip, *orig)) { *s++ = *orig; i++; From 0301420fcbf77c7e2a2d3f75073243b0000f25a9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 19 Feb 2018 10:19:44 -0500 Subject: [PATCH 16/20] fix reported stack corruption bug during Call Fix an issue reported as github #74. Some guard code was required to prevent writing past end of qbuf via a sprintf. --- src/do_name.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/do_name.c b/src/do_name.c index 6e3bfd981..db226a548 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1415,12 +1415,19 @@ register struct obj *obj; otemp.quan = 1L; otemp.oextra = (struct oextra *) 0; - if (objects[otemp.otyp].oc_class == POTION_CLASS && otemp.fromsink) + if (objects[otemp.otyp].oc_class == POTION_CLASS && otemp.fromsink) { /* kludge, meaning it's sink water */ Sprintf(qbuf, "Call a stream of %s fluid:", - OBJ_DESCR(objects[otemp.otyp])); - else - Sprintf(qbuf, "Call %s:", an(xname(&otemp))); + 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); + } + } getlin(qbuf, buf); if (!*buf || *buf == '\033') return; From 7a0ad0ff21958924805cf8d0419d73a4e42d97d6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 19 Feb 2018 11:18:57 -0500 Subject: [PATCH 17/20] sync README and DEVEL/Developer re: repositories --- DEVEL/Developer.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/DEVEL/Developer.txt b/DEVEL/Developer.txt index 1267ac073..334ac3d56 100644 --- a/DEVEL/Developer.txt +++ b/DEVEL/Developer.txt @@ -32,8 +32,11 @@ while. Please do not send save files, binary screen grabs, or other large things. ------------------------------------------------------------------------------ 2. git repositories -The public NetHack git repository is available (read-only) on SourceForge at: - git://git.code.sf.net/p/nethack/NHsource +A public repository of the latest NetHack code that we've made +available can be obtained via git from either of two locations: + https://github.com/NetHack/NetHack + or + https://sourceforge.net/p/nethack/NetHack/ XXX need to discuss what branches are available ------------------------------------------------------------------------------ From 859ef823d6ae78401ae12c5628e6811a675a47b0 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 19 Feb 2018 11:59:14 -0800 Subject: [PATCH 18/20] fix #H6867 - mail buffer overrun Web contact report of a github pull request. A previous fix from same user dealt with potential crash caused by freeing mailbox data when the mailbox came from getenv("MAIL"). getenv() doesn't return a value obtained by malloc so freeing it was bad. The fix was to allocate memory to hold a copy of getenv("MAIL") so that free() was valid. Unfortunately it didn't allocate enough space to hold the terminating '\0' so potentially corrupted malloc/free bookkeeping data. And the alloc+copy was being performed every time the mailbox was checked, resulting in leaked memory from the previous check (if MAIL came from player's environment). Fortunately the recheck only takes place after new mail is actually detected and reported to the player so the leak was probably small for most folks. This compiles for the set of conditionals that apply to me (after taking out -DNOMAIL that the hints put in my Makefile) but I can't test that it actually works since mail is never delivered to this machine. --- doc/fixes36.1 | 5 +++++ src/mail.c | 44 +++++++++++++++++++++++++------------------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 9b8633956..0ce719fe4 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -577,6 +577,11 @@ the fix for secret doors on special levels always having vertical orientation 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 +unix: freeing mailbox data at game end crashed if MAIL came from environment +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 Platform- and/or Interface-Specific Fixes diff --git a/src/mail.c b/src/mail.c index 9d8986db9..af5773af1 100644 --- a/src/mail.c +++ b/src/mail.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mail.c $NHDT-Date: 1464222344 2016/05/26 00:25:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.27 $ */ +/* NetHack 3.6 mail.c $NHDT-Date: 1519070343 2018/02/19 19:59:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.31 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -90,38 +90,44 @@ free_maildata() void getmailstatus() { - char *emailbox; - if ((emailbox = nh_getenv("MAIL")) != 0) { - mailbox = (char *) alloc((unsigned) strlen(emailbox)); - Strcpy(mailbox, emailbox); - } - if (!mailbox) { + if (mailbox) { + ; /* no need to repeat the setup */ + } else if ((mailbox = nh_getenv("MAIL")) != 0) { + mailbox = dupstr(mailbox); #ifdef MAILPATH + } else { #ifdef AMS struct passwd ppasswd; - (void) memcpy(&ppasswd, getpwuid(getuid()), sizeof(struct passwd)); + (void) memcpy(&ppasswd, getpwuid(getuid()), sizeof (struct passwd)); if (ppasswd.pw_dir) { - mailbox = (char *) alloc((unsigned) strlen(ppasswd.pw_dir) - + sizeof(AMS_MAILBOX)); + /* note: 'sizeof "LITERAL"' includes +1 for terminating '\0' */ + mailbox = (char *) alloc((unsigned) (strlen(ppasswd.pw_dir) + + sizeof AMS_MAILBOX)); Strcpy(mailbox, ppasswd.pw_dir); Strcat(mailbox, AMS_MAILBOX); - } else - return; + } #else const char *pw_name = getpwuid(getuid())->pw_name; - mailbox = (char *) alloc(sizeof(MAILPATH) + strlen(pw_name)); + + /* note: 'sizeof "LITERAL"' includes +1 for terminating '\0' */ + mailbox = (char *) alloc((unsigned) (strlen(pw_name) + + sizeof MAILPATH)); Strcpy(mailbox, MAILPATH); Strcat(mailbox, pw_name); #endif /* AMS */ -#else - return; -#endif +#endif /* MAILPATH */ } - if (stat(mailbox, &omstat)) { + + debugpline3("mailbox=%c%s%c", + mailbox ? '\"' : '<', + mailbox ? mailbox : "null", + mailbox ? '\"' : '>'); + + if (mailbox && stat(mailbox, &omstat)) { #ifdef PERMANENT_MAILBOX pline("Cannot get status of MAIL=\"%s\".", mailbox); - mailbox = 0; + free_maildata(); /* set 'mailbox' to Null */ #else omstat.st_mtime = 0; #endif @@ -495,7 +501,7 @@ ckmailstatus() if (stat(mailbox, &nmstat)) { #ifdef PERMANENT_MAILBOX pline("Cannot get status of MAIL=\"%s\" anymore.", mailbox); - mailbox = 0; + free_maildata(); #else nmstat.st_mtime = 0; #endif From f72f72f8637c0fa92b65c528b6f1b9bcde05acb8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 19 Feb 2018 15:42:18 -0500 Subject: [PATCH 19/20] update fixes36.1 with the docall() prompt string overrun --- doc/fixes36.1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 0ce719fe4..4d30dce6d 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -509,6 +509,8 @@ 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 Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository From 25d17eb62cdf12e290497505b26fe0c0c262f84f Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 19 Feb 2018 21:32:54 -0500 Subject: [PATCH 20/20] fix some typos mentioned downstream --- DEVEL/Developer.txt | 8 ++++---- doc/fixes36.1 | 2 +- include/config.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/DEVEL/Developer.txt b/DEVEL/Developer.txt index 334ac3d56..1316f23e0 100644 --- a/DEVEL/Developer.txt +++ b/DEVEL/Developer.txt @@ -1,8 +1,8 @@ - ___ _ - | \ _____ _____| |___ _ __ ___ _ _ + ___ _ + | \ _____ _____| |___ _ __ ___ _ _ | |) / -_) V / -_) / _ \ '_ \/ -_) '_| - |___/\___|\_/\___|_\___/ .__/\___|_| - |_| + |___/\___|\_/\___|_\___/ .__/\___|_| + |_| $NHDT-Date: 1518800857 2018/02/16 17:07:37 $ diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 4d30dce6d..2e697c5ab 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -277,7 +277,7 @@ when getpos was picking a location, typing '^' to move to the next known trap skipped some detected traps if their location was unseen describe detected door traps and chest traps as trapped door and trapped chest instead of bear trap; bear trap tile is still used on map though -thrown potion that killed peaceful monster would cause "the gets argry" +thrown potion that killed peaceful monster would cause "the gets angry" after the message about it being killed when poly'd into a hider and engulfed, attempt to hide via #monster was blocked but feedback said "can't hide while held" rather than "while engulfed" diff --git a/include/config.h b/include/config.h index 5cae0fa9f..d695c40d2 100644 --- a/include/config.h +++ b/include/config.h @@ -11,7 +11,7 @@ * For "UNIX" select BSD, ULTRIX, SYSV, or HPUX in unixconf.h. * A "VMS" option is not needed since the VMS C-compilers * provide it (no need to change sec#1, vmsconf.h handles it). - * MacOSX uses the UNIX configruation, not the old MAC one. + * MacOSX uses the UNIX configuration, not the old MAC one. */ #define UNIX /* delete if no fork(), exec() available */