From d6ed41339edb7e7d875e1fc6ff343989f43fa7f7 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 22 Dec 2018 16:35:15 -0800 Subject: [PATCH 1/7] fix #H7749 - "you detect it" 'Detect' is used for observing a vampire shape change without being able to see the vampire. The problem here is that it changed from bat form to fog cloud form in order to pass under a closed door, and the message was being delivered when it was already at the door location instead of before the move from a visible spot to that door. I'm not happy with this fix, but any other alternative I considered seemed to be worse. Having the shape change use up the monster's move is probably a better way to go. Then on its next move it will be in the right form to make a normal flow-under-door move. --- doc/fixes36.2 | 2 ++ src/monmove.c | 58 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index d891d6e63..c719349ac 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -300,6 +300,8 @@ identifying or forgetting gem types now adjusts prices for gems already on when fire converts an ice location into a water location, dunk any monster on that spot immediately instead of waiting until its next move training riding skill had an off-by-one bug when counting turns riding +message sequencing when vampire shifts to fog cloud to pass under closed door: + when in sight, give form change message before moving to door spot Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/src/monmove.c b/src/monmove.c index fbc2d419d..37b752346 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 monmove.c $NHDT-Date: 1544442712 2018/12/10 11:51:52 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.109 $ */ +/* NetHack 3.6 monmove.c $NHDT-Date: 1545525307 2018/12/23 00:35:07 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.110 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -896,7 +896,7 @@ register int after; mmoved = 1; goto postmov; } -not_special: + not_special: if (u.uswallow && !mtmp->mflee && u.ustuck != mtmp) return 1; omx = mtmp->mx; @@ -1157,7 +1157,7 @@ not_special: chi = i; mmoved = 1; } - nxti: + nxti: ; } } @@ -1201,6 +1201,7 @@ not_special: if ((info[chi] & ALLOW_M) || (nix == mtmp->mux && niy == mtmp->muy)) { struct monst *mtmp2; int mstatus; + mtmp2 = m_at(nix, niy); notonhead = mtmp2 && (nix != mtmp2->mx || niy != mtmp2->my); @@ -1224,6 +1225,7 @@ not_special: if ((info[chi] & ALLOW_MDISP)) { struct monst *mtmp2; int mstatus; + mtmp2 = m_at(nix, niy); mstatus = mdisplacem(mtmp, mtmp2, FALSE); if ((mstatus & MM_AGR_DIED) || (mstatus & MM_DEF_DIED)) @@ -1235,6 +1237,7 @@ not_special: if (!m_in_out_region(mtmp, nix, niy)) return 3; + remove_monster(omx, omy); place_monster(mtmp, nix, niy); for (j = MTSZ - 1; j > 0; j--) @@ -1252,18 +1255,49 @@ not_special: if (mtmp->wormno) worm_nomove(mtmp); } -postmov: + postmov: if (mmoved == 1 || mmoved == 3) { boolean canseeit = cansee(mtmp->mx, mtmp->my); if (mmoved == 1) { + /* normal monster move will already have , + but pet dog_move() with 'goto postmov' won't */ + nix = mtmp->mx, niy = mtmp->my; + /* sequencing issue: when monster movement decides that a + monster can move to a door location, it moves the monster + there before dealing with the door rather than after; + so a vampire/bat that is going to shift to fog cloud and + pass under the door is already there but transformation + into fog form--and its message, when in sight--has not + happened yet; we have to move monster back to previous + location before performing the vamp_shift() to make the + message happen at right time, then back to the door again + [if we did the shift above, before moving the monster, + we would need to duplicate it in dog_move()...] */ + if (is_vampshifter(mtmp) && !amorphous(mtmp->data) + && IS_DOOR(levl[nix][niy].typ) + && ((levl[nix][niy].doormask & (D_LOCKED | D_CLOSED)) != 0) + && can_fog(mtmp)) { + if (sawmon) { + remove_monster(nix, niy), place_monster(mtmp, omx, omy); + newsym(nix, niy), newsym(omx, omy); + } + if (vamp_shift(mtmp, &mons[PM_FOG_CLOUD], sawmon)) { + ptr = mtmp->data; /* update cached value */ + } + if (sawmon) { + remove_monster(omx, omy), place_monster(mtmp, nix, niy); + newsym(omx, omy), newsym(nix, niy); + } + } + newsym(omx, omy); /* update the old position */ if (mintrap(mtmp) >= 2) { if (mtmp->mx) newsym(mtmp->mx, mtmp->my); return 2; /* it died */ } - ptr = mtmp->data; + ptr = mtmp->data; /* in case mintrap() caused polymorph */ /* open a door, or crash through it, if 'mtmp' can */ if (IS_DOOR(levl[mtmp->mx][mtmp->my].typ) @@ -1284,18 +1318,11 @@ postmov: btrapped = FALSE; } if ((here->doormask & (D_LOCKED | D_CLOSED)) != 0 - && (amorphous(ptr) - || (can_fog(mtmp) - && vamp_shift(mtmp, &mons[PM_FOG_CLOUD], - sawmon)))) { - /* update cached value for vamp_shift() case */ - ptr = mtmp->data; + && amorphous(ptr)) { if (flags.verbose && canseemon(mtmp)) pline("%s %s under the door.", Monnam(mtmp), (ptr == &mons[PM_FOG_CLOUD] - || ptr->mlet == S_LIGHT) - ? "flows" - : "oozes"); + || ptr->mlet == S_LIGHT) ? "flows" : "oozes"); } else if (here->doormask & D_LOCKED && can_unlock) { if (btrapped) { here->doormask = D_NODOOR; @@ -1684,6 +1711,9 @@ boolean domsg; pline("You %s %s where %s was.", !canseemon(mon) ? "now detect" : "observe", noname_monnam(mon, ARTICLE_A), oldmtype); + /* this message is given when it turns into a fog cloud + in order to move under a closed door */ + display_nhwindow(WIN_MESSAGE, FALSE); } return reslt; From 0eb11aa718b2796205aeeb825ed01b0a342d085b Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 22 Dec 2018 18:09:44 -0800 Subject: [PATCH 2/7] fix github issue #155 - encumbrance vs water Fixes #155 When drowning, you need to be unencumbered in order to crawl out of water. When not drowing, you don't, but put a limit on how much can be carried. If polymorphed into a swimming creature, allow stressed or less; otherwise (magical breathing), burdened or less. (Doesn't apply on the Plane of Water since there's no climb from water to land involved.) --- doc/fixes36.2 | 1 + src/hack.c | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index c719349ac..e08f5de5c 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -302,6 +302,7 @@ when fire converts an ice location into a water location, dunk any monster on training riding skill had an off-by-one bug when counting turns riding message sequencing when vampire shifts to fog cloud to pass under closed door: when in sight, give form change message before moving to door spot +limit carrying heavy loads from water to land Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/src/hack.c b/src/hack.c index 362a4c78a..0e3f3f6f2 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 hack.c $NHDT-Date: 1544401269 2018/12/10 00:21:09 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.201 $ */ +/* NetHack 3.6 hack.c $NHDT-Date: 1545530973 2018/12/23 02:09:33 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.202 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1429,6 +1429,19 @@ domove() } x = u.ux + u.dx; y = u.uy + u.dy; + + /* are we trying to move out of water while carrying too much? */ + if (isok(x, y) && !is_pool(x, y) && !Is_waterlevel(&u.uz) + && wtcap > (Swimming ? MOD_ENCUMBER : SLT_ENCUMBER)) { + /* when escaping from drowning you need to be unencumbered + in order to crawl out of water, but when not drowning, + doing so while encumbered is feasible; if in an aquatic + form, stressed or less is allowed; otherwise (magical + breathing), only burdened is allowed */ + You("are carrying too much to climb out of the water."); + nomul(0); + return; + } } if (!isok(x, y)) { nomul(0); @@ -1441,6 +1454,7 @@ domove() if (iflags.mention_walls) { if (trap && trap->tseen) { int tt = what_trap(trap->ttyp); + You("stop in front of %s.", an(defsyms[trap_to_defsym(tt)].explanation)); } else if (is_pool_or_lava(x,y) && levl[x][y].seenv) { From 95acf0d93a3fc65e5e7c745e53875a2170868673 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 23 Dec 2018 12:03:53 -0800 Subject: [PATCH 3/7] avoid checkfile() segfault Recent change for "pair of lenses names The Eyes of the Overworld" triggered a segfault if item was neither named nor called. --- doc/fixes36.2 | 1 + src/pager.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index e08f5de5c..01b2f33b7 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -336,6 +336,7 @@ a config file line with OPTIONS=symset:default, roguesymset:RogueEpyx meant to have color; that was due to an errant init_symbols() call during the processing of symset:default done after RogueEpyx had already been processed +avoid potential segfault when doing 'more information' lookup tty: turn off an optimization that is the suspected cause of Windows reported partial status lines following level changes tty: ensure that current status fields are always copied to prior status diff --git a/src/pager.c b/src/pager.c index f15c40f59..e8748452e 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pager.c $NHDT-Date: 1545361111 2018/12/21 02:58:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.143 $ */ +/* NetHack 3.6 pager.c $NHDT-Date: 1545595360 2018/12/23 20:02:40 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.144 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -646,9 +646,9 @@ char *supplemental_name; The Eyes of the Overworld" simplified above to "lenses named The Eyes of the Overworld", now reduced to "The Eyes of the Overworld", skip "The" as with base name processing) */ - if (!strncmpi(alt, "a ", 2) - || !strncmpi(alt, "an ", 3) - || !strncmpi(alt, "the ", 4)) + if (alt && (!strncmpi(alt, "a ", 2) + || !strncmpi(alt, "an ", 3) + || !strncmpi(alt, "the ", 4))) alt = index(alt, ' ') + 1; /* remove charges or "(lit)" or wizmode "(N aum)" */ if ((ep = strstri(dbase_str, " (")) != 0 && ep > dbase_str) From df5dc6050d09652e201bfadbb92f80053ab6b76a Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 23 Dec 2018 12:13:37 -0800 Subject: [PATCH 4/7] EXTRA_SANITY_CHECKS build fix is if/else friendly and semi-colon friendly, but not comma friendly. --- src/monmove.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/monmove.c b/src/monmove.c index 37b752346..305ba4cbb 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 monmove.c $NHDT-Date: 1545525307 2018/12/23 00:35:07 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.110 $ */ +/* NetHack 3.6 monmove.c $NHDT-Date: 1545596010 2018/12/23 20:13:30 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.111 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1279,14 +1279,16 @@ register int after; && ((levl[nix][niy].doormask & (D_LOCKED | D_CLOSED)) != 0) && can_fog(mtmp)) { if (sawmon) { - remove_monster(nix, niy), place_monster(mtmp, omx, omy); + remove_monster(nix, niy); + place_monster(mtmp, omx, omy); newsym(nix, niy), newsym(omx, omy); } if (vamp_shift(mtmp, &mons[PM_FOG_CLOUD], sawmon)) { ptr = mtmp->data; /* update cached value */ } if (sawmon) { - remove_monster(omx, omy), place_monster(mtmp, nix, niy); + remove_monster(omx, omy); + place_monster(mtmp, nix, niy); newsym(omx, omy), newsym(nix, niy); } } From 7bc36ddef41f0bf58ab5440c8d5e4c3892614e2c Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 23 Dec 2018 12:37:26 -0800 Subject: [PATCH 5/7] fix #H6942 - dropx vs hold_another_object Dropping an existing fragile item while levitating will usually break it. Getting a new wished-for fragile item and dropping it because of fumbling or overfull inventory never would. Some callers of hold_another_object() held on to its return value, others discarded that. That return value was unsafe if the item was dropped and fell down a hole (or broke [after this change]). Return Null if we can't be sure of the value, and make sure all callers are prepared to deal with Null. --- doc/fixes36.2 | 1 + include/extern.h | 4 ++-- src/artifact.c | 8 +++++--- src/do.c | 4 ++-- src/dothrow.c | 22 +++++++++++----------- src/invent.c | 24 +++++++++++++++++------- src/mail.c | 16 +++++++++------- src/mkobj.c | 23 +++++++++++++---------- src/pickup.c | 5 +++-- src/potion.c | 3 ++- src/uhitm.c | 5 +++-- 11 files changed, 68 insertions(+), 47 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 01b2f33b7..7be5fc556 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -303,6 +303,7 @@ training riding skill had an off-by-one bug when counting turns riding message sequencing when vampire shifts to fog cloud to pass under closed door: when in sight, give form change message before moving to door spot limit carrying heavy loads from water to land +failing to carry a wished-for item behaved differenctly from dropping one Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 78c7647da..7a239f127 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1545383614 2018/12/21 09:13:34 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.675 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1545597403 2018/12/23 20:36:43 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.676 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -536,7 +536,7 @@ E void FDECL(impact_drop, (struct obj *, XCHAR_P, XCHAR_P, XCHAR_P)); E int NDECL(dothrow); E int NDECL(dofire); E void FDECL(endmultishot, (BOOLEAN_P)); -E void FDECL(hitfloor, (struct obj *)); +E void FDECL(hitfloor, (struct obj *, BOOLEAN_P)); E void FDECL(hurtle, (int, int, int, BOOLEAN_P)); E void FDECL(mhurtle, (struct monst *, int, int, int)); E boolean FDECL(throwing_weapon, (struct obj *)); diff --git a/src/artifact.c b/src/artifact.c index 80332f325..2a641b8d7 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 artifact.c $NHDT-Date: 1543745353 2018/12/02 10:09:13 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.127 $ */ +/* NetHack 3.6 artifact.c $NHDT-Date: 1545597414 2018/12/23 20:36:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.128 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1479,6 +1479,7 @@ struct obj *obj; } case ENERGY_BOOST: { int epboost = (u.uenmax + 1 - u.uen) / 2; + if (epboost > 120) epboost = 120; /* arbitrary */ else if (epboost < 12) @@ -1598,6 +1599,7 @@ struct obj *obj; otmp->owt = weight(otmp); otmp = hold_another_object(otmp, "Suddenly %s out.", aobjnam(otmp, "fall"), (char *) 0); + nhUse(otmp); break; } } @@ -1621,7 +1623,7 @@ struct obj *obj; } if ((eprop & ~W_ARTI) || iprop) { - nothing_special: + nothing_special: /* you had the property from some other source too */ if (carried(obj)) You_feel("a surge of power, but nothing seems to happen."); @@ -1975,7 +1977,7 @@ boolean loseit; /* whether to drop it if hero can longer touch it */ if (loseit && obj) { if (Levitation) { freeinv(obj); - hitfloor(obj); + hitfloor(obj, TRUE); } else { /* dropx gives a message iff item lands on an altar */ if (!IS_ALTAR(levl[u.ux][u.uy].typ)) diff --git a/src/do.c b/src/do.c index 3438a44b1..b05339df4 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do.c $NHDT-Date: 1545043771 2018/12/17 10:49:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.181 $ */ +/* NetHack 3.6 do.c $NHDT-Date: 1545597418 2018/12/23 20:36:58 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.182 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -612,7 +612,7 @@ register struct obj *obj; if (obj->oclass == COIN_CLASS) context.botl = 1; freeinv(obj); - hitfloor(obj); + hitfloor(obj, TRUE); if (levhack) float_down(I_SPECIAL | TIMEOUT, W_ARTI | W_ART); return 1; diff --git a/src/dothrow.c b/src/dothrow.c index b3a2f8ba4..de1afca9c 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dothrow.c $NHDT-Date: 1545044705 2018/12/17 11:05:05 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.154 $ */ +/* NetHack 3.6 dothrow.c $NHDT-Date: 1545597420 2018/12/23 20:37:00 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.155 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -415,21 +415,21 @@ boolean verbose; } } -/* - * Object hits floor at hero's feet. Called from drop() and throwit(). - */ +/* Object hits floor at hero's feet. + Called from drop(), throwit(), hold_another_object(). */ void -hitfloor(obj) -register struct obj *obj; +hitfloor(obj, verbosely) +struct obj *obj; +boolean verbosely; /* usually True; False if caller has given drop message */ { - if (IS_SOFT(levl[u.ux][u.uy].typ) || u.uinwater) { + if (IS_SOFT(levl[u.ux][u.uy].typ) || u.uinwater || u.uswallow) { dropy(obj); return; } if (IS_ALTAR(levl[u.ux][u.uy].typ)) doaltarobj(obj); - else - pline("%s hit%s the %s.", Doname2(obj), (obj->quan == 1L) ? "s" : "", + else if (verbosely) + pline("%s %s the %s.", Doname2(obj), otense(obj, "hit"), surface(u.ux, u.uy)); if (hero_breaks(obj, u.ux, u.uy, TRUE)) @@ -1047,7 +1047,7 @@ boolean hitsroof; done(STONING); return obj ? TRUE : FALSE; } - hitfloor(obj); + hitfloor(obj, TRUE); thrownobj = 0; losehp(Maybe_Half_Phys(dmg), "falling object", KILLED_BY_AN); } @@ -1168,7 +1168,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */ for dealing with cursed saddle: throw holy water > */ potionhit(u.usteed, obj, POTHIT_HERO_THROW); } else { - hitfloor(obj); + hitfloor(obj, TRUE); } thrownobj = (struct obj *) 0; return; diff --git a/src/invent.c b/src/invent.c index 93939ad86..62ec70401 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 invent.c $NHDT-Date: 1545043772 2018/12/17 10:49:32 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.244 $ */ +/* NetHack 3.6 invent.c $NHDT-Date: 1545597422 2018/12/23 20:37:02 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.245 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -975,9 +975,9 @@ const char *drop_fmt, *drop_arg, *hold_msg; } } if (Fumbling) { - if (drop_fmt) - pline(drop_fmt, drop_arg); - dropy(obj); + obj->nomerge = 1; + obj = addinv(obj); /* dropping expects obj to be in invent */ + goto drop_it; } else { long oquan = obj->quan; int prev_encumbr = near_capacity(); /* before addinv() */ @@ -994,12 +994,10 @@ const char *drop_fmt, *drop_arg, *hold_msg; obj = addinv(obj); if (inv_cnt(FALSE) > 52 || ((obj->otyp != LOADSTONE || !obj->cursed) && near_capacity() > prev_encumbr)) { - if (drop_fmt) - pline(drop_fmt, drop_arg); /* undo any merge which took place */ if (obj->quan > oquan) obj = splitobj(obj, oquan); - dropx(obj); + goto drop_it; } else { if (flags.autoquiver && !uquiver && !obj->owornmask && (is_missile(obj) || ammo_and_launcher(obj, uwep) @@ -1010,6 +1008,18 @@ const char *drop_fmt, *drop_arg, *hold_msg; } } return obj; + + drop_it: + if (drop_fmt) + pline(drop_fmt, drop_arg); + obj->nomerge = 0; + if (can_reach_floor(TRUE)) { + dropx(obj); + } else { + freeinv(obj); + hitfloor(obj, FALSE); + } + return (struct obj *) 0; /* might be gone */ } /* useup() all of an item regardless of its quantity */ diff --git a/src/mail.c b/src/mail.c index b3f8e97c6..63142ad51 100644 --- a/src/mail.c +++ b/src/mail.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mail.c $NHDT-Date: 1542765359 2018/11/21 01:55:59 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.37 $ */ +/* NetHack 3.6 mail.c $NHDT-Date: 1545597424 2018/12/23 20:37:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.39 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -186,7 +186,7 @@ coord *startp; */ lax = 0; /* be picky */ max_distance = -1; -retry: + retry: for (row = 0; row < ROWNO; row++) { if (viz_rmin[row] < viz_rmax[row]) { /* There are valid positions on this row. */ @@ -418,15 +418,17 @@ struct mail_info *info; display_nhwindow(WIN_MESSAGE, FALSE); obj = hold_another_object(obj, "Oops!", (const char *) 0, (const char *) 0); + nhUse(obj); } -/* zip back to starting location */ -go_back: + go_back: + /* zip back to starting location */ if (!md_rush(md, start.x, start.y)) md->mx = md->my = 0; /* for mongone, md is not on map */ mongone(md); -/* deliver some classes of messages even if no daemon ever shows up */ -give_up: + + give_up: + /* deliver some classes of messages even if no daemon ever shows up */ if (!message_seen && info->message_typ == MSG_OTHER) pline("Hark! \"%s.\"", info->display_txt); } @@ -609,7 +611,7 @@ boolean adminmsg; else unlink(mailbox); return; -bail: + bail: /* bail out _professionally_ */ if (!adminmsg) pline("It appears to be all gibberish."); diff --git a/src/mkobj.c b/src/mkobj.c index 9a0ec48f2..50140fe1f 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1542798624 2018/11/21 11:10:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.136 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1545597425 2018/12/23 20:37:05 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.137 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2168,18 +2168,21 @@ boolean tipping; /* caller emptying entire contents; affects shop handling */ being included in its formatted name during next message */ iflags.suppress_price++; if (!tipping) { - obj = hold_another_object( - obj, u.uswallow ? "Oops! %s out of your reach!" - : (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) - || levl[u.ux][u.uy].typ < IRONBARS - || levl[u.ux][u.uy].typ >= ICE) - ? "Oops! %s away from you!" - : "Oops! %s to the floor!", - The(aobjnam(obj, "slip")), (const char *) 0); + obj = hold_another_object(obj, + u.uswallow + ? "Oops! %s out of your reach!" + : (Is_airlevel(&u.uz) + || Is_waterlevel(&u.uz) + || levl[u.ux][u.uy].typ < IRONBARS + || levl[u.ux][u.uy].typ >= ICE) + ? "Oops! %s away from you!" + : "Oops! %s to the floor!", + The(aobjnam(obj, "slip")), (char *) 0); + nhUse(obj); } else { /* assumes this is taking place at hero's location */ if (!can_reach_floor(TRUE)) { - hitfloor(obj); /* does altar check, message, drop */ + hitfloor(obj, TRUE); /* does altar check, message, drop */ } else { if (IS_ALTAR(levl[u.ux][u.uy].typ)) doaltarobj(obj); /* does its own drop message */ diff --git a/src/pickup.c b/src/pickup.c index 65a541d12..a8b611454 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pickup.c $NHDT-Date: 1543188989 2018/11/25 23:36:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.220 $ */ +/* NetHack 3.6 pickup.c $NHDT-Date: 1545597427 2018/12/23 20:37:07 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.221 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2023,6 +2023,7 @@ boolean *prev_loot; } otmp = hold_another_object(otmp, "You drop %s!", doname(otmp), (const char *) 0); + nhUse(otmp); timepassed = rnd(3); if (prev_loot) *prev_loot = TRUE; @@ -3188,7 +3189,7 @@ struct obj *box; /* or bag */ if (highdrop) { /* might break or fall down stairs; handles altars itself */ - hitfloor(otmp); + hitfloor(otmp, TRUE); } else { if (altarizing) { doaltarobj(otmp); diff --git a/src/potion.c b/src/potion.c index a6bf5f656..482321692 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 potion.c $NHDT-Date: 1545182147 2018/12/19 01:15:47 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.156 $ */ +/* NetHack 3.6 potion.c $NHDT-Date: 1545597429 2018/12/23 20:37:09 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.157 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2237,6 +2237,7 @@ more_dips: singlepotion = hold_another_object(singlepotion, "You juggle and drop %s!", doname(singlepotion), (const char *) 0); + nhUse(singlepotion); update_inventory(); return 1; } diff --git a/src/uhitm.c b/src/uhitm.c index 01c423593..fa50677dc 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 uhitm.c $NHDT-Date: 1544840256 2018/12/15 02:17:36 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.196 $ */ +/* NetHack 3.6 uhitm.c $NHDT-Date: 1545597432 2018/12/23 20:37:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.197 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1546,7 +1546,8 @@ struct attack *mattk; /* give the object to the character */ otmp = hold_another_object(otmp, "You snatched but dropped %s.", doname(otmp), "You steal: "); - if (otmp->where != OBJ_INVENT) + /* might have dropped otmp, and it might have broken or left level */ + if (!otmp || otmp->where != OBJ_INVENT) continue; if (theft_petrifies(otmp)) break; /* stop thieving even though hero survived */ From f6d5862c0d384489b5ec41249802bb4831ce4e8b Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 23 Dec 2018 17:25:14 -0800 Subject: [PATCH 6/7] implement #H6051 - fake players resist Conflict The rationale is that since the player character resists conflict, fake players should too. [I'm not sure that I buy that. Player character is always the one *causing* conflict and it doesn't affect self. But this is simple as long as no other resistance checks are against attack-by-ring.] --- doc/fixes36.2 | 8 +++++--- src/zap.c | 7 ++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 7be5fc556..aa0a07c87 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -156,9 +156,6 @@ a wand of polymorph lost its magical ability for the turn just because the much sense floating eye is classified as a flyer but flying is blocked while levitating, so don't set intrinsic flying if hero is polymorphed into one -being trapped (bear trap, web, molten or solidified lava, chained to buried - iron ball) blocks both levitation and flight (note: being stuck in a - pit ends when either of those starts so doesn't apply) change default value for the 'autodescribe' option to 'on' Elbereth hypocrisy penalty doesn't apply if attacking a monster which isn't frightened by Elbereth; normal scuffing of engravings still applies @@ -452,6 +449,11 @@ for ^X and enlightenment, display the information in a menu rather than a needed for interfaces (tty) without text popup scrollbar support; end of game disclosure of attributes remains single-forward-pass for ^X, include current state of 'autopickup' +being trapped (bear trap, web, molten or solidified lava, chained to buried + iron ball) blocks both levitation and flight (note: being stuck in a + pit ends when either of those starts so doesn't apply) +early level traps are sometimes covered by the remains of fake players +fake player characters resist Conflict NetHack Community Patches (or Variation) Included diff --git a/src/zap.c b/src/zap.c index eb61a261c..ba90e34c3 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 zap.c $NHDT-Date: 1545431660 2018/12/21 22:34:20 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.303 $ */ +/* NetHack 3.6 zap.c $NHDT-Date: 1545614662 2018/12/24 01:24:22 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.304 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -5090,6 +5090,11 @@ int damage, tell; int resisted; int alev, dlev; + /* fake players always pass resistance test against Conflict + (this doesn't guarantee that they're never affected by it) */ + if (oclass == RING_CLASS && !damage && !tell && is_mplayer(mtmp->data)) + return 1; + /* attack level */ switch (oclass) { case WAND_CLASS: From e2852f25fd02bb5a1205b2a4f9af5b3ee41ba06f Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 24 Dec 2018 02:08:44 -0800 Subject: [PATCH 7/7] fix temporary strength loss that was permanent Watching the fuzzer, I saw hero's strength plummet to 3 again and not rise above 5 after that. It turns out to be due to life-saving, which was fixing severe hunger but was not restoring the point of strength that's lost when you go from hungry to weak. I'm not sure whether this was caused by 3.6.1's commit 024e9e122576db664e37df0937cfb4c06c436e0c or already behaved that way. Another fuzzer bit: the monk I was watching was bitten by a wererat early on and was still inflicted with lycanthropy when he reached level 19. (I've no idea how his level got to be so high; it jumped from 14 to 19 while I wasn't paying attention.) Extend the earlier hack for drinking a blessed potion of restore ability to recover lost characteristcs to sometimes drink a potion of holy water instead. --- doc/fixes36.2 | 2 ++ src/end.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index aa0a07c87..dbe5691c9 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -301,6 +301,8 @@ message sequencing when vampire shifts to fog cloud to pass under closed door: when in sight, give form change message before moving to door spot limit carrying heavy loads from water to land failing to carry a wished-for item behaved differenctly from dropping one +life-saving while weak/starving/fainting boosted nutrition without restoring + lost point of strength, making temporary loss be permanent Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/src/end.c b/src/end.c index b89eee7e9..3803a4366 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 end.c $NHDT-Date: 1545172226 2018/12/18 22:30:26 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.159 $ */ +/* NetHack 3.6 end.c $NHDT-Date: 1545646111 2018/12/24 10:08:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.160 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -859,16 +859,13 @@ int how; u.uhp = u.uhpmax; if (Upolyd) /* Unchanging, or death which bypasses losing hit points */ u.mh = u.mhmax; - if (u.uhunger < 500) { - u.uhunger = 500; - newuhs(FALSE); + if (u.uhunger < 500 || how == CHOKING) { + init_uhunger(); } /* cure impending doom of sickness hero won't have time to fix */ if ((Sick & TIMEOUT) == 1L) { make_sick(0L, (char *) 0, FALSE, SICK_ALL); } - if (how == CHOKING) - init_uhunger(); nomovemsg = "You survived that attempt on your life."; context.move = 0; if (multi > 0) @@ -1060,9 +1057,12 @@ int how; if (iflags.debug_fuzzer) { if (!(program_state.panicking || how == PANICKED)) { savelife(how); - /* periodically restore characteristics and lost exp levels */ + /* periodically restore characteristics and lost exp levels + or cure lycanthropy */ if (!rn2(10)) { - struct obj *potion = mksobj(POT_RESTORE_ABILITY, TRUE, FALSE); + struct obj *potion = mksobj((u.ulycn > LOW_PM && !rn2(3)) + ? POT_WATER : POT_RESTORE_ABILITY, + TRUE, FALSE); bless(potion); (void) peffects(potion); /* always -1 for restore ability */