diff --git a/dat/data.base b/dat/data.base index f098dd7c7..4046259a2 100644 --- a/dat/data.base +++ b/dat/data.base @@ -4384,7 +4384,7 @@ dwarven root are greedy and thriftless, and would not spare till all the plants had perished; whereas now they pass them by as they go blundering in the wild. No more will you learn of me; but you - may have enough of my bounty, as long as you speak fair and + may have enough of my bounty, as long as you speak fair and do not spy or steal." Then again he laughed in his throat. "They are of great worth." he said. "More than gold in the @@ -5344,11 +5344,26 @@ valkyrie vampire ~vampire bat vampire lord + He can transform himself to wolf, as we gather from the ship + arrival in Whitby, when he tear open the dog; he can be as + bat, as Madam Mina saw him on the window at Whitby, and as + friend John saw him fly from this so near house, and as my + friend Quincey saw him at the window of Miss Lucy. He can come + in mist which he create--that noble ship's captain proved him + of this; but, from what we know, the distance he can make this + mist is limited, and it can only be round himself. He come on + moonlight rays as elemental dust--as again Jonathan saw those + sisters in the castle of Dracula. He become so small--we + ourselves saw Miss Lucy, ere she was at peace, slip through a + hairbreadth space at the tomb door. + [ Dracula, by Bram Stoker ] + The Oxford English Dictionary is quite unequivocal: _vampire_ - "a preternatural being of a malignant nature (in the original and usual form of the belief, a reanimated corpse), supposed to seek nourishment, or do harm, by sucking the blood of sleeping persons. ..." + [] venus Venus, the goddess of love and beauty, was the daughter of Jupiter and Dione. Others say that Venus sprang from the @@ -5374,8 +5389,8 @@ vlad* *vortex vortices Swirling clouds of pure elemental energies, the vortices are - thought to be related to the larger elementals. They are - noted for being able to envelop unwary travellers. The + thought to be related to the larger elementals. They are + noted for being able to envelop unwary travellers. The hapless fool thus swallowed by a vortex will soon perish from exposure to the element the vortex is composed of. vrock diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 82ada4627..2bebd4e0f 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.31 $ $NHDT-Date: 1559422205 2019/06/01 20:50:05 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.41 $ $NHDT-Date: 1559733390 2019/06/05 11:16:30 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -38,6 +38,25 @@ on the Plane of Air, make clouds disrupt line of sight along the edges have '&' (whatdoes) command describe movement keystrokes instead of reporting them as unknown or showing their number_pad action when that is Off some improvement to the handling of endgame levels filling up with monsters +if you survive turning into green slime due to life-saving (surviving as a + green slime) then die again due to green slimes having been genocided, + the feedback was strange because it assumed that the prior message + came from answering No to "Really die?" in explore or wizard mode +various cases where objects had their bless/curse state become known weren't + updating persistent inventory window, when enabled, to reflect changes + (cited case was trying to remove cursed armor and being told of the + curse but there were lots of other situations with the same issue) +similar perm_invent issue when lock state known and/or contents known become + set for carried container +blessed scroll of remove curse read while confused might be shown to operate + on itself by perm_invent after player is told that it has disappeared +fix memory leak if corpse auto-revival attempt failed ("you feel less hassled") +allow a parent function to issue an an unplacebc() call that restricts + subsequent placebc() calls to that parent only +flying monsters could enter water on the Plane of Water but then they'd drown + unless they could also swim or else didn't need to breathe +when finding a place to put a monster on the Plane of Water, don't pick a + water location for flyers or floaters (levitate) or clingers (ceiling) Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository @@ -60,6 +79,7 @@ curses: if message window is only one line, cancelling some prompts with ESC left the prompts visible on the message line instead of erasing them curses: support EDIT_GETLIN (but like with tty, it's disabled by default) to pre-load an earlier response as the default answer for some prompts + (however, it's skipped if the 'popup_dialog' option is On) curses: when display windows get reconfigured (after setting align_status, align_message, statuslines, windowborders or due to external resize), the message window was being refreshed with the oldest available N @@ -91,4 +111,6 @@ add a couple of engraving suggestions in pull request #79 Code Cleanup and Reorganization ------------------------------- +began to add some function caller BREADCRUMBS to aid debugging + diff --git a/include/config.h b/include/config.h index 1fa760d90..d12576f9d 100644 --- a/include/config.h +++ b/include/config.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 config.h $NHDT-Date: 1558248715 2019/05/19 06:51:55 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.122 $ */ +/* NetHack 3.6 config.h $NHDT-Date: 1559601008 2019/06/03 22:30:08 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.123 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -526,6 +526,12 @@ typedef unsigned char uchar; * probably not useful for normal play */ /* #define EXTRA_SANITY_CHECKS */ +/* BREADCRUMBS employs the use of predefined compiler macros + * __FUNCTION__ and __LINE__ to store some caller breadcrumbs + * for use during heavy debugging sessions. Only define if your + * compiler supports those predefined macros and you are debugging */ +/* #define BREADCRUMBS */ + /* EDIT_GETLIN makes the string input in TTY, curses, Qt4, and X11 for some prompts be pre-loaded with previously input text (from a previous instance of the same prompt) as the default response. diff --git a/include/decl.h b/include/decl.h index 497463ae4..d07cc3ef4 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 decl.h $NHDT-Date: 1547025154 2019/01/09 09:12:34 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.147 $ */ +/* NetHack 3.6 decl.h $NHDT-Date: 1559601011 2019/06/03 22:30:11 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.150 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ @@ -380,6 +380,13 @@ struct plinemsg_type { /* bitmask for callers of hide_unhide_msgtypes() */ #define MSGTYP_MASK_REP_SHOW ((1 << MSGTYP_NOREP) | (1 << MSGTYP_NOSHOW)) + +enum bcargs {override_restriction = -1}; +struct breadcrumbs { + const char *funcnm; + int linenum; + boolean in_effect; +}; #ifdef PANICTRACE E const char *ARGV0; #endif diff --git a/include/extern.h b/include/extern.h index 281e87b32..508627de9 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1559422206 2019/06/01 20:50:06 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.707 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1559670600 2019/06/04 17:50:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.709 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -128,8 +128,23 @@ E void FDECL(uchangealign, (int, int)); E void FDECL(ballrelease, (BOOLEAN_P)); E void NDECL(ballfall); +#ifndef BREADCRUMBS E void NDECL(placebc); E void NDECL(unplacebc); +E int NDECL(unplacebc_and_covet_placebc); +E void FDECL(lift_covet_and_placebc, (int)); +#else +E void FDECL(Placebc, (const char *, int)); +E void FDECL(Unplacebc, (const char *, int)); +E int FDECL(Unplacebc_and_covet_placebc, (const char *, int)); +E void FDECL(Lift_covet_and_placebc, (int, const char *, int)); +#define placebc() Placebc(__FUNCTION__, __LINE__) +#define unplacebc() Unplacebc(__FUNCTION__, __LINE__) +#define unplacebc_and_covet_placebc() \ + Unplacebc_and_covet_placebc(__FUNCTION__, __LINE__) +#define lift_covet_and_placebc(x) \ + Lift_covet_and_placebc(x, __FUNCTION__, __LINE__) +#endif E void FDECL(set_bc, (int)); E void FDECL(move_bc, (int, int, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P)); E boolean FDECL(drag_ball, (XCHAR_P, XCHAR_P, int *, xchar *, xchar *, @@ -1331,6 +1346,7 @@ E void FDECL(unbless, (struct obj *)); E void FDECL(curse, (struct obj *)); E void FDECL(uncurse, (struct obj *)); E void FDECL(blessorcurse, (struct obj *, int)); +E void FDECL(set_bknown, (struct obj *, unsigned)); E boolean FDECL(is_flammable, (struct obj *)); E boolean FDECL(is_rottable, (struct obj *)); E void FDECL(place_object, (struct obj *, int, int)); diff --git a/include/flag.h b/include/flag.h index ea69ba239..5163f58a7 100644 --- a/include/flag.h +++ b/include/flag.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 flag.h $NHDT-Date: 1554155745 2019/04/01 21:55:45 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.150 $ */ +/* NetHack 3.6 flag.h $NHDT-Date: 1559664948 2019/06/04 16:15:48 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.151 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -484,7 +484,8 @@ enum plnmsg_types { PLNMSG_TOWER_OF_FLAME, /* scroll of fire */ PLNMSG_CAUGHT_IN_EXPLOSION, /* explode() feedback */ PLNMSG_OBJ_GLOWS, /* "the glows " */ - PLNMSG_OBJNAM_ONLY /* xname/doname only, for #tip */ + PLNMSG_OBJNAM_ONLY, /* xname/doname only, for #tip */ + PLNMSG_OK_DONT_DIE /* overriding death in explore/wizard mode */ }; /* runmode options */ diff --git a/src/apply.c b/src/apply.c index 25f1ebe5e..f7eae32e6 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 apply.c $NHDT-Date: 1553363415 2019/03/23 17:50:15 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.272 $ */ +/* NetHack 3.6 apply.c $NHDT-Date: 1559670602 2019/06/04 17:50:02 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.274 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -662,7 +662,7 @@ struct obj *obj; pline("This leash is not attached to that creature."); } else if (obj->cursed) { pline_The("leash would not come off!"); - obj->bknown = 1; + set_bknown(obj, 1); } else { mtmp->mleashed = 0; obj->leashmon = 0; @@ -2744,7 +2744,7 @@ struct obj *obj; pline("%s welded to %s %s%c", (otmp->quan == 1L) ? "It is" : "They are", mhis(mtmp), mon_hand, !otmp->bknown ? '!' : '.'); - otmp->bknown = 1; + set_bknown(otmp, 1); gotit = FALSE; /* can't pull it free */ } if (gotit) { @@ -3597,7 +3597,7 @@ doapply() if (!rn2(49)) { if (!Blind) { pline("%s %s.", Yobjnam2(obj, "glow"), hcolor("brown")); - obj->bknown = 1; + set_bknown(obj, 1); } unbless(obj); } diff --git a/src/ball.c b/src/ball.c index 39ccbdac4..77fa5ecf0 100644 --- a/src/ball.c +++ b/src/ball.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 ball.c $NHDT-Date: 1558920171 2019/05/27 01:22:51 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.38 $ */ +/* NetHack 3.6 ball.c $NHDT-Date: 1559601027 2019/06/03 22:30:27 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.40 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) David Cohrs, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -10,6 +10,14 @@ STATIC_DCL int NDECL(bc_order); STATIC_DCL void NDECL(litter); +STATIC_OVL void NDECL(placebc_core); +STATIC_OVL void NDECL(unplacebc_core); +STATIC_DCL boolean FDECL(check_restriction, (int)); + +static int bcrestriction = 0; +#ifdef BREADCRUMBS +static struct breadcrumbs bcpbreadcrumbs = {0}, bcubreadcrumbs = {0}; +#endif void ballrelease(showmsg) @@ -106,8 +114,8 @@ ballfall() * * Should not be called while swallowed except on waterlevel. */ -void -placebc() +STATIC_OVL void +placebc_core() { if (!uchain || !uball) { impossible("Where are your ball and chain?"); @@ -130,10 +138,11 @@ placebc() u.bglyph = u.cglyph = levl[u.ux][u.uy].glyph; /* pick up glyph */ newsym(u.ux, u.uy); + bcrestriction = 0; } -void -unplacebc() +STATIC_OVL void +unplacebc_core() { if (u.uswallow) { if (Is_waterlevel(&u.uz)) { @@ -164,6 +173,191 @@ unplacebc() u.bc_felt = 0; /* feel nothing */ } +STATIC_OVL boolean +check_restriction(restriction) +int restriction; +{ + boolean ret = FALSE; + + if (!bcrestriction || (restriction == override_restriction)) + ret = TRUE; + else + ret = (bcrestriction == restriction) ? TRUE : FALSE; + return ret; +} + +#ifndef BREADCRUMBS +void +placebc() +{ + if (!check_restriction(0)) { +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) + char panicbuf[BUFSZ]; + + Sprintf(panicbuf, + "placebc denied, restriction in effect"); + paniclog("placebc", panicbuf); +#endif + return; + } + if (uchain && uchain->where != OBJ_FREE) { + impossible("bc already placed?"); + return; + } + placebc_core(); +} + +void +unplacebc() +{ + if (bcrestriction) { + impossible("unplacebc denied, restriction in place"); + return; + } + unplacebc_core(); +} + +int +unplacebc_and_covet_placebc() +{ + int restriction = 0; + + if (bcrestriction) { + impossible("unplacebc_and_covet_placebc denied, already restricted"); + } else { + restriction = bcrestriction = rnd(400); + unplacebc_core(); + } + return restriction; +} + +void +lift_covet_and_placebc(pin) +int pin; +{ + if (!check_restriction(pin)) { +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) + char panicbuf[BUFSZ]; + + Sprintf(panicbuf, + "lift_covet_and_placebc denied, %s", + (pin != bcrestriction) ? + "pin mismatch" : "restriction in effect"); + paniclog("placebc", panicbuf); +#endif + return; + } + if (uchain && uchain->where != OBJ_FREE) { + impossible("bc already placed?"); + return; + } + placebc_core(); +} + +#else /* BREADCRUMBS */ + +void +Placebc(funcnm, linenum) +const char *funcnm; +int linenum; +{ + if (!check_restriction(0)) { +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) + char panicbuf[BUFSZ]; + + Sprintf(panicbuf, + "Placebc denied to %s:%d, restricted by %s:%d", + funcnm, linenum, + bcpbreadcrumbs.funcnm, bcpbreadcrumbs.linenum); + paniclog("Placebc", panicbuf); +#endif + return; + } + if ((uchain && uchain->where != OBJ_FREE) + && bcpbreadcrumbs.in_effect) { + impossible("Placebc collision at %s:%d, already placed by %s:%d", + funcnm, linenum, + bcpbreadcrumbs.funcnm, bcpbreadcrumbs.linenum); + return; + } + bcpbreadcrumbs.in_effect = TRUE; + bcubreadcrumbs.in_effect = FALSE; + bcpbreadcrumbs.funcnm = funcnm; + bcpbreadcrumbs.linenum = linenum; + placebc_core(); +} + +void +Unplacebc(funcnm, linenum) +const char *funcnm; +int linenum; +{ + + if (bcrestriction) { + char panicbuf[BUFSZ]; + + Sprintf(panicbuf, + "Unplacebc from %s:%d, when restricted to %s:%d", + funcnm, linenum, + bcubreadcrumbs.funcnm, bcubreadcrumbs.linenum); + paniclog("Unplacebc", panicbuf); + } + bcpbreadcrumbs.in_effect = FALSE; + bcubreadcrumbs.in_effect = TRUE; + bcubreadcrumbs.funcnm = funcnm; + bcubreadcrumbs.linenum = linenum; + unplacebc_core(); +} + +int +Unplacebc_and_covet_placebc(funcnm, linenum) +const char *funcnm; +int linenum; +{ + int restriction = 0; + + if (bcrestriction) { + impossible( + "Unplacebc_and_covet_placebc denied to %s:%d, restricted by %s:%d", + funcnm, linenum, + bcubreadcrumbs.funcnm, bcubreadcrumbs.linenum); + } else { + restriction = bcrestriction = rnd(400); + bcpbreadcrumbs.in_effect = FALSE; + bcubreadcrumbs.in_effect = TRUE; + bcubreadcrumbs.funcnm = funcnm; + bcubreadcrumbs.linenum = linenum; + unplacebc_core(); + } + return restriction; +} + +void +Lift_covet_and_placebc(pin, funcnm, linenum) +int pin; +char *funcnm; +int linenum; +{ + if (!check_restriction(pin)) { +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) + char panicbuf[BUFSZ]; + + Sprintf(panicbuf, + "Lift_covet_and_placebc denied to %s:%d, restricted by %s:%d", + funcnm, linenum, + bcpbreadcrumbs.funcnm, bcpbreadcrumbs.linenum); + paniclog("Lift_covet_and_placebc", panicbuf); +#endif + return; + } + if (uchain && uchain->where != OBJ_FREE) { + impossible("bc already placed?"); + return; + } + placebc_core(); +} +#endif /* BREADCRUMBS */ + /* * Return the stacking of the hero's ball & chain. This assumes that the * hero is being punished. @@ -853,7 +1047,7 @@ drag_down() void bc_sanity_check() { - int otyp; + int otyp, freeball, freechain; const char *onam; if (Punished && (!uball || !uchain)) { @@ -867,11 +1061,18 @@ bc_sanity_check() (uchain && uball) ? " and " : "", uball ? "iron ball" : ""); } - /* ball is free when swallowed, changing levels, other times? */ + /* ball is free when swallowed, when changing levels or during air bubble + management on Plane of Water (both of which start and end in between + sanity checking cycles, so shouldn't be relevant), other times? */ + freechain = (!uchain || uchain->where == OBJ_FREE); + freeball = (!uball || uball->where == OBJ_FREE + /* lie to simplify the testing logic */ + || (freechain && uball->where == OBJ_INVENT)); if (uball && (uball->otyp != HEAVY_IRON_BALL || (uball->where != OBJ_FLOOR && uball->where != OBJ_INVENT && uball->where != OBJ_FREE) + || (freeball ^ freechain) || (uball->owornmask & W_BALL) == 0L || (uball->owornmask & ~(W_BALL | W_WEAPON)) != 0L)) { otyp = uball->otyp; @@ -883,6 +1084,7 @@ bc_sanity_check() if (uchain && (uchain->otyp != IRON_CHAIN || (uchain->where != OBJ_FLOOR && uchain->where != OBJ_FREE) + || (freechain ^ freeball) /* [could simplify this to owornmask != W_CHAIN] */ || (uchain->owornmask & W_CHAIN) == 0L || (uchain->owornmask & ~W_CHAIN) != 0L)) { @@ -891,6 +1093,25 @@ bc_sanity_check() impossible("uchain: type %d (%s), where %d, wornmask=0x%08lx", otyp, onam, uchain->where, uchain->owornmask); } + if (uball && uchain && !(freeball && freechain)) { + int bx, by, cx, cy, bdx, bdy, cdx, cdy; + + /* non-free chain should be under or next to the hero; + non-free ball should be on or next to the chain or else carried */ + cx = uchain->ox, cy = uchain->oy; + cdx = cx - u.ux, cdy = cy - u.uy; + cdx = abs(cdx), cdy = abs(cdy); + if (uball->where == OBJ_INVENT) /* carried(uball) */ + bx = u.ux, by = u.uy; /* get_obj_location() */ + else + bx = uball->ox, by = uball->oy; + bdx = bx - cx, bdy = by - cy; + bdx = abs(bdx), bdy = abs(bdy); + if (cdx > 1 || cdy > 1 || bdx > 1 || bdy > 1) + impossible( + "b&c distance: you@<%d,%d>, chain@<%d,%d>, ball@<%d,%d>", + u.ux, u.uy, cx, cy, bx, by); + } /* [check bc_order too?] */ } diff --git a/src/do.c b/src/do.c index dbf41fc8e..1c9f9ad34 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do.c $NHDT-Date: 1559299314 2019/05/31 10:41:54 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.191 $ */ +/* NetHack 3.6 do.c $NHDT-Date: 1559670603 2019/06/04 17:50:03 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.192 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -284,11 +284,11 @@ register struct obj *obj; an(hcolor(obj->blessed ? NH_AMBER : NH_BLACK)), doname(obj), otense(obj, "hit")); if (!Hallucination) - obj->bknown = 1; + obj->bknown = 1; /* ok to bypass set_bknown() */ } else { pline("%s %s on the altar.", Doname2(obj), otense(obj, "land")); if (obj->oclass != COIN_CLASS) - obj->bknown = 1; + obj->bknown = 1; /* ok to bypass set_bknown() */ } } @@ -573,7 +573,7 @@ const char *word; obj->corpsenm ? " any of" : "", plur(obj->quan)); } obj->corpsenm = 0; /* reset */ - obj->bknown = 1; + set_bknown(obj, 1); return FALSE; } if (obj->otyp == LEASH && obj->leashmon != 0) { diff --git a/src/do_wear.c b/src/do_wear.c index f71c6819d..20702cb87 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_wear.c $NHDT-Date: 1551138255 2019/02/25 23:44:15 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.108 $ */ +/* NetHack 3.6 do_wear.c $NHDT-Date: 1559670603 2019/06/04 17:50:03 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.109 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1511,7 +1511,7 @@ doremring() /* Check if something worn is cursed _and_ unremovable. */ int cursed(otmp) -register struct obj *otmp; +struct obj *otmp; { if (!otmp) { impossible("cursed without otmp"); @@ -1523,7 +1523,7 @@ register struct obj *otmp; || otmp->otyp == LENSES || otmp->quan > 1L); You("can't. %s cursed.", use_plural ? "They are" : "It is"); - otmp->bknown = TRUE; + set_bknown(otmp, 1); return 1; } return 0; @@ -1531,7 +1531,7 @@ register struct obj *otmp; int armoroff(otmp) -register struct obj *otmp; +struct obj *otmp; { register int delay = -objects[otmp->otyp].oc_delay; @@ -1855,7 +1855,7 @@ struct obj *obj; } if (uarmg && uarmg->cursed) { res = !uarmg->bknown; - uarmg->bknown = 1; + set_bknown(uarmg, 1); You("cannot remove your gloves to put on the ring."); return res; /* uses move iff we learned gloves are cursed */ } @@ -2245,7 +2245,7 @@ register struct obj *otmp; } if (why) { You("cannot %s to remove the ring.", buf); - why->bknown = TRUE; + set_bknown(why, 1); return 0; } } @@ -2254,7 +2254,7 @@ register struct obj *otmp; if (welded(uwep)) { You("are unable to take off your %s while wielding that %s.", c_gloves, is_sword(uwep) ? c_sword : c_weapon); - uwep->bknown = TRUE; + set_bknown(uwep, 1); return 0; } else if (Glib) { You_cant("take off the slippery %s with your slippery %s.", @@ -2292,7 +2292,7 @@ register struct obj *otmp; } if (why) { You("cannot %s to take off %s.", buf, the(xname(otmp))); - why->bknown = TRUE; + set_bknown(why, 1); return 0; } } diff --git a/src/eat.c b/src/eat.c index fb14f1fc2..6ba9718e8 100644 --- a/src/eat.c +++ b/src/eat.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 eat.c $NHDT-Date: 1542765357 2018/11/21 01:55:57 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.197 $ */ +/* NetHack 3.6 eat.c $NHDT-Date: 1559670604 2019/06/04 17:50:04 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.202 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2498,7 +2498,7 @@ doeat() * against the possibility just in case. */ if (welded(otmp) || (otmp->cursed && (otmp->owornmask & W_RING))) { - otmp->bknown = 1; /* for ring; welded() does this for weapon */ + set_bknown(otmp, 1); /* for ring; welded() does this for weapon */ You("spit out %s.", the(xname(otmp))); } else { You("spit %s out onto the %s.", the(xname(otmp)), diff --git a/src/end.c b/src/end.c index daebeb9e2..059ba74ce 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 end.c $NHDT-Date: 1558921075 2019/05/27 01:37:55 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.174 $ */ +/* NetHack 3.6 end.c $NHDT-Date: 1559675615 2019/06/04 19:13:35 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.176 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1018,7 +1018,8 @@ done_object_cleanup() swallowed, uball and uchain will be in limbo; put them on floor so bones will have them and object list cleanup finds them */ if (uchain && uchain->where == OBJ_FREE) { - placebc(); + /* placebc(); */ + lift_covet_and_placebc(override_restriction); } return; } @@ -1154,6 +1155,7 @@ int how; if (!survive && (wizard || discover) && how <= GENOCIDED && !paranoid_query(ParanoidDie, "Die?")) { pline("OK, so you don't %s.", (how == CHOKING) ? "choke" : "die"); + iflags.last_msg = PLNMSG_OK_DONT_DIE; savelife(how); survive = TRUE; } @@ -1597,9 +1599,12 @@ boolean identified, all_containers, reportempty; for (box = list; box; box = box->nobj) { if (Is_container(box) || box->otyp == STATUE) { - box->cknown = 1; /* we're looking at the contents now */ - if (identified) - box->lknown = 1; + if (!box->cknown || (identified && !box->lknown)) { + box->cknown = 1; /* we're looking at the contents now */ + if (identified) + box->lknown = 1; + update_inventory(); + } if (box->otyp == BAG_OF_TRICKS) { continue; /* wrong type of container */ } else if (box->cobj) { diff --git a/src/files.c b/src/files.c index c7b81b2e0..d56e10496 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 files.c $NHDT-Date: 1546144856 2018/12/30 04:40:56 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.249 $ */ +/* NetHack 3.6 files.c $NHDT-Date: 1559670605 2019/06/04 17:50:05 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.250 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2889,7 +2889,7 @@ struct obj *obj; /* subset of starting inventory pre-ID */ obj->dknown = 1; if (Role_if(PM_PRIEST)) - obj->bknown = 1; + obj->bknown = 1; /* ok to bypass set_bknown() */ /* same criteria as lift_object()'s check for available inventory slot */ if (obj->oclass != COIN_CLASS && inv_cnt(FALSE) >= 52 && !merge_choice(g.invent, obj)) { diff --git a/src/hack.c b/src/hack.c index 1bbaf44d9..9c08be267 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 hack.c $NHDT-Date: 1559313320 2019/05/31 14:35:20 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.212 $ */ +/* NetHack 3.6 hack.c $NHDT-Date: 1559664951 2019/06/04 16:15:51 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.213 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2900,8 +2900,16 @@ const char *msg_override; g.nomovemsg = msg_override; else if (!g.nomovemsg) g.nomovemsg = You_can_move_again; - if (*g.nomovemsg) + if (*g.nomovemsg) { pline("%s", g.nomovemsg); + /* follow "you survived that attempt on your life" with a message + about current form if it's not the default; primarily for + life-saving while turning into green slime but is also a reminder + if life-saved while poly'd and Unchanging (explore or wizard mode + declining to die since can't be both Unchanging and Lifesaved) */ + if (Upolyd && !strncmpi(g.nomovemsg, "You survived that ", 18)) + You("are %s", an(mons[u.umonnum].mname)); /* (ignore Hallu) */ + } g.nomovemsg = 0; u.usleep = 0; g.multi_reason = NULL; diff --git a/src/makemon.c b/src/makemon.c index b5af919cd..9d36a3835 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 makemon.c $NHDT-Date: 1556150377 2019/04/24 23:59:37 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.134 $ */ +/* NetHack 3.6 makemon.c $NHDT-Date: 1559733390 2019/06/05 11:16:30 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.137 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1120,6 +1120,7 @@ int mmflags; struct monst fakemon; cc.x = cc.y = 0; /* lint suppression */ + fakemon = cg.zeromonst; fakemon.data = ptr; /* set up for goodpos */ if (!makemon_rnd_goodpos(ptr ? &fakemon : (struct monst *)0, gpflags, &cc)) diff --git a/src/mkmaze.c b/src/mkmaze.c index 9b157750e..5f09d1bb3 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -1390,7 +1390,7 @@ movebubbles() struct bubble *b; struct container *cons; struct trap *btrap; - int x, y, i, j; + int x, y, i, j, bcpin; /* set up the portal the first time bubbles are moved */ if (!g.wportal) @@ -1401,7 +1401,7 @@ movebubbles() if (Is_waterlevel(&u.uz)) { /* keep attached ball&chain separate from bubble objects */ if (Punished) - unplacebc(); + bcpin = unplacebc_and_covet_placebc(); /* * Pick up everything inside of a bubble then fill all bubble @@ -1518,7 +1518,7 @@ movebubbles() /* put attached ball&chain back */ if (Is_waterlevel(&u.uz) && Punished) - placebc(); + lift_covet_and_placebc(bcpin); g.vision_full_recalc = 1; } diff --git a/src/mkobj.c b/src/mkobj.c index 7501158f8..1cdf8426f 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1559476922 2019/06/02 12:02:02 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.149 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1559670606 2019/06/04 17:50:06 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.150 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -698,7 +698,7 @@ int alter_type; { xchar ox, oy; char objroom; - boolean set_bknown; + boolean learn_bknown; const char *those, *them; struct monst *shkp = 0; @@ -738,21 +738,21 @@ int alter_type; /* when shopkeeper describes the object as being uncursed or unblessed hero will know that it is now uncursed; will also make the feedback from `I x' after bill_dummy_object() be more specific for this item */ - set_bknown = (alter_type == COST_UNCURS || alter_type == COST_UNBLSS); + learn_bknown = (alter_type == COST_UNCURS || alter_type == COST_UNBLSS); switch (obj->where) { case OBJ_FREE: /* obj_no_longer_held() */ case OBJ_INVENT: - if (set_bknown) - obj->bknown = 1; + if (learn_bknown) + set_bknown(obj, 1); verbalize("You %s %s %s, you pay for %s!", alteration_verbs[alter_type], those, simpleonames(obj), them); bill_dummy_object(obj); break; case OBJ_FLOOR: - if (set_bknown) - obj->bknown = 1; + if (learn_bknown) + obj->bknown = 1; /* ok to bypass set_bknown() here */ if (costly_spot(u.ux, u.uy) && objroom == *u.ushops) { verbalize("You %s %s, you pay for %s!", alteration_verbs[alter_type], those, them); @@ -1389,6 +1389,19 @@ register struct obj *otmp; return (!!otmp->blessed - !!otmp->cursed); } +/* set the object's bless/curse-state known flag */ +void +set_bknown(obj, onoff) +struct obj *obj; +unsigned onoff; /* 1 or 0 */ +{ + if (obj->bknown != onoff) { + obj->bknown = onoff; + if (obj->where == OBJ_INVENT && g.moves > 1L) + update_inventory(); + } +} + /* * Calculate the weight of the given object. This will recursively follow * and calculate the weight of any containers. diff --git a/src/mon.c b/src/mon.c index a385eb7a4..670a8945a 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mon.c $NHDT-Date: 1559422247 2019/06/01 20:50:47 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.287 $ */ +/* NetHack 3.6 mon.c $NHDT-Date: 1559733390 2019/06/05 11:16:30 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.292 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -491,7 +491,7 @@ register struct monst *mtmp; { boolean inpool, inlava, infountain; - /* [what about ceiling clingers?] */ + /* [ceiling clingers are handled below] */ inpool = (is_pool(mtmp->mx, mtmp->my) && (!(is_flyer(mtmp->data) || is_floater(mtmp->data)) /* there's no "above the surface" on the plane of water */ @@ -1324,10 +1324,16 @@ long flag; nowtyp = levl[x][y].typ; nodiag = NODIAG(mdat - mons); - wantpool = mdat->mlet == S_EEL; - poolok = (is_flyer(mdat) || is_clinger(mdat) + wantpool = (mdat->mlet == S_EEL); + poolok = ((!Is_waterlevel(&u.uz) + && (is_flyer(mdat) || is_floater(mdat) || is_clinger(mdat))) || (is_swimmer(mdat) && !wantpool)); - lavaok = (is_flyer(mdat) || is_clinger(mdat) || likes_lava(mdat)); + /* note: floating eye is the only is_floater() so this could be + simplified, but then adding another floater would be error prone */ + lavaok = (is_flyer(mdat) || is_floater(mdat) || is_clinger(mdat) + || likes_lava(mdat)); + if (mdat == &mons[PM_FLOATING_EYE]) /* prefers to avoid heat */ + lavaok = FALSE; thrudoor = ((flag & (ALLOW_WALL | BUSTDOOR)) != 0L); poisongas_ok = ((nonliving(mdat) || is_vampshifter(mon) || breathless(mdat)) || resists_poison(mon)); @@ -2615,7 +2621,8 @@ struct monst *mtmp; * here (return FALSE). */ if (mtmp->data == &mons[PM_WIZARD_OF_YENDOR] || is_rider(mtmp->data) - || has_emin(mtmp) || has_epri(mtmp) || has_eshk(mtmp)) + || has_emin(mtmp) || has_epri(mtmp) || has_eshk(mtmp) + || (u.ustuck == mtmp) || (u.usteed == mtmp)) return FALSE; return TRUE; } @@ -2683,7 +2690,8 @@ struct monst *mon; rloc_to(mon, mx, my); /* note: mon, not mtmp */ } else { /* last resort - migrate mon to the next plane */ - if (Is_waterlevel(&u.uz) || Is_firelevel(&u.uz) || Is_earthlevel(&u.uz)) { + if (Is_waterlevel(&u.uz) || Is_firelevel(&u.uz) + || Is_earthlevel(&u.uz)) { /* try sending mon on to the next plane */ xchar target_lev = 0, xyloc = 0; struct trap *trap = g.ftrap; diff --git a/src/objnam.c b/src/objnam.c index b74ffafdf..73f1dc7d4 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1558485650 2019/05/22 00:40:50 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.241 $ */ +/* NetHack 3.6 objnam.c $NHDT-Date: 1559670607 2019/06/04 17:50:07 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.242 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -445,9 +445,12 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ if (!nn && ocl->oc_uses_known && ocl->oc_unique) obj->known = 0; if (!Blind && !g.distantname) - obj->dknown = TRUE; + obj->dknown = 1; if (Role_if(PM_PRIEST)) - obj->bknown = TRUE; + obj->bknown = 1; /* actively avoid set_bknown(); + * we mustn't call update_inventory() now because + * it would call xname() (via doname()) recursively + * and could end up clobbering all the obufs... */ if (iflags.override_ID) { known = dknown = bknown = TRUE; diff --git a/src/pickup.c b/src/pickup.c index 19be7a71b..123fb7065 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pickup.c $NHDT-Date: 1559130050 2019/05/29 11:40:50 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.226 $ */ +/* NetHack 3.6 pickup.c $NHDT-Date: 1559675617 2019/06/04 19:13:37 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.228 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -396,8 +396,8 @@ struct obj *obj; ? TRUE : FALSE) : TRUE; /* catchall: no filters specified, so accept */ - if (Role_if(PM_PRIEST)) - obj->bknown = TRUE; + if (Role_if(PM_PRIEST) && !obj->bknown) + set_bknown(obj, 1); /* * There are three types of filters possible and the first and @@ -1691,7 +1691,7 @@ int cindex, ccount; /* index of this container (1..N), number of them (N) */ cobj->lknown = 1; return 0; } - cobj->lknown = 1; + cobj->lknown = 1; /* floor container, so no need for update_inventory() */ if (cobj->otyp == BAG_OF_TRICKS) { int tmp; @@ -2100,7 +2100,7 @@ register struct obj *obj; Icebox ? "refrigerate" : "stash", something); return 0; } else if ((obj->otyp == LOADSTONE) && obj->cursed) { - obj->bknown = 1; + set_bknown(obj, 1); pline_The("stone%s won't leave your person.", plur(obj->quan)); return 0; } else if (obj->otyp == AMULET_OF_YENDOR @@ -2480,16 +2480,19 @@ boolean more_containers; /* True iff #loot multiple and this isn't last one */ if (!u_handsy()) return 0; + if (!obj->lknown) { /* do this in advance */ + obj->lknown = 1; + if (held) + update_inventory(); + } if (obj->olocked) { pline("%s locked.", Tobjnam(obj, "are")); if (held) You("must put it down to unlock."); - obj->lknown = 1; return 0; } else if (obj->otrapped) { if (held) You("open %s...", the(xname(obj))); - obj->lknown = 1; (void) chest_trap(obj, HAND, FALSE); /* even if the trap fails, you've used up this turn */ if (g.multi >= 0) { /* in case we didn't become paralyzed */ @@ -2500,7 +2503,6 @@ boolean more_containers; /* True iff #loot multiple and this isn't last one */ g.abort_looting = TRUE; return 1; } - obj->lknown = 1; g.current_container = obj; /* for use by in/out_container */ /* @@ -3092,7 +3094,11 @@ struct obj *box; /* or bag */ /* caveat: this assumes that cknown, lknown, olocked, and otrapped fields haven't been overloaded to mean something special for the non-standard "container" horn of plenty */ - box->lknown = 1; + if (!box->lknown) { + box->lknown = 1; + if (carried(box)) + update_inventory(); /* jumping the gun slightly; hope that's ok */ + } if (box->olocked) { pline("It's locked."); } else if (box->otrapped) { @@ -3213,6 +3219,8 @@ struct obj *box; /* or bag */ if (held) (void) encumber_msg(); } + if (carried(box)) /* box is now empty with cknown set */ + update_inventory(); } /*pickup.c*/ diff --git a/src/polyself.c b/src/polyself.c index eb5d10326..87143cb61 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 polyself.c $NHDT-Date: 1556497911 2019/04/29 00:31:51 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.132 $ */ +/* NetHack 3.6 polyself.c $NHDT-Date: 1559664952 2019/06/04 16:15:52 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.133 $ */ /* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -159,7 +159,7 @@ polyman(fmt, arg) const char *fmt, *arg; { boolean sticky = (sticks(g.youmonst.data) && u.ustuck && !u.uswallow), - was_mimicking = (U_AP_TYPE == M_AP_OBJECT); + was_mimicking = (U_AP_TYPE != M_AP_NOTHING); boolean was_blind = !!Blind; if (Upolyd) { @@ -182,6 +182,7 @@ const char *fmt, *arg; if (g.multi < 0) unmul(""); g.youmonst.m_ap_type = M_AP_NOTHING; + g.youmonst.mappearance = 0; } newsym(u.ux, u.uy); @@ -629,6 +630,7 @@ int mntmp; if (mons[mntmp].mlet != S_MIMIC) { /* as in polyman() */ g.youmonst.m_ap_type = M_AP_NOTHING; + g.youmonst.mappearance = 0; } if (is_male(&mons[mntmp])) { if (flags.female) diff --git a/src/potion.c b/src/potion.c index e80d3a068..e6891ffdb 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 potion.c $NHDT-Date: 1549074254 2019/02/02 02:24:14 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.160 $ */ +/* NetHack 3.6 potion.c $NHDT-Date: 1559664951 2019/06/04 16:15:51 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.161 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -182,8 +182,15 @@ const char *msg; if (msg) pline("%s", msg); } - if (!Slimed) + if (!Slimed) { dealloc_killer(find_delayed_killer(SLIMED)); + /* fake appearance is set late in turn-to-slime countdown */ + if (g.youmonst.m_ap_type == M_AP_MONSTER + && g.youmonst.mappearance == PM_GREEN_SLIME) { + g.youmonst.m_ap_type = M_AP_NOTHING; + g.youmonst.mappearance = 0; + } + } } /* start or stop petrification */ diff --git a/src/pray.c b/src/pray.c index e933c604c..f1e959052 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pray.c $NHDT-Date: 1549074257 2019/02/02 02:24:17 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.110 $ */ +/* NetHack 3.6 pray.c $NHDT-Date: 1559670608 2019/06/04 17:50:08 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.112 $ */ /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -494,7 +494,7 @@ int trouble; what ? what : (const char *) Yobjnam2(otmp, "softly glow"), hcolor(NH_AMBER)); iflags.last_msg = PLNMSG_OBJ_GLOWS; - otmp->bknown = !Hallucination; + otmp->bknown = !Hallucination; /* ok to skip set_bknown() */ } uncurse(otmp); update_inventory(); @@ -553,7 +553,7 @@ int trouble; otmp = which_armor(u.usteed, W_SADDLE); if (!Blind) { pline("%s %s.", Yobjnam2(otmp, "softly glow"), hcolor(NH_AMBER)); - otmp->bknown = TRUE; + set_bknown(otmp, 1); } uncurse(otmp); break; @@ -800,7 +800,7 @@ gcrownu() make_splbk: obj = mksobj(class_gift, TRUE, FALSE); bless(obj); - obj->bknown = TRUE; + obj->bknown = 1; /* ok to skip set_bknown() */ at_your_feet("A spellbook"); dropy(obj); u.ugifts++; @@ -887,7 +887,7 @@ gcrownu() bless(obj); obj->oeroded = obj->oeroded2 = 0; obj->oerodeproof = TRUE; - obj->bknown = obj->rknown = TRUE; + obj->bknown = obj->rknown = 1; /* ok to skip set_bknown() */ if (obj->spe < 1) obj->spe = 1; /* acquire skill in this weapon */ @@ -1019,7 +1019,7 @@ aligntyp g_align; You_feel("the power of %s over %s.", u_gname(), yname(uwep)); uncurse(uwep); - uwep->bknown = TRUE; + uwep->bknown = 1; /* ok to bypass set_bknown() */ *repair_buf = '\0'; } else if (!uwep->blessed) { if (!Blind) { @@ -1031,7 +1031,7 @@ aligntyp g_align; You_feel("the blessing of %s over %s.", u_gname(), yname(uwep)); bless(uwep); - uwep->bknown = TRUE; + uwep->bknown = 1; /* ok to bypass set_bknown() */ *repair_buf = '\0'; } @@ -1122,7 +1122,7 @@ aligntyp g_align; pline("%s %s.", Yobjnam2(otmp, "softly glow"), hcolor(NH_AMBER)); iflags.last_msg = PLNMSG_OBJ_GLOWS; - otmp->bknown = TRUE; + otmp->bknown = 1; /* ok to bypass set_bknown() */ ++any; } uncurse(otmp); @@ -1229,7 +1229,7 @@ boolean bless_water; && (bless_water ? !otmp->blessed : !otmp->cursed)) { otmp->blessed = bless_water; otmp->cursed = !bless_water; - otmp->bknown = bc_known; + otmp->bknown = bc_known; /* ok to bypass set_bknown() */ changed += otmp->quan; } else if (otmp->oclass == POTION_CLASS) other = TRUE; diff --git a/src/read.c b/src/read.c index 12f31e17d..70452abcc 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 read.c $NHDT-Date: 1546465285 2019/01/02 21:41:25 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.164 $ */ +/* NetHack 3.6 read.c $NHDT-Date: 1559679496 2019/06/04 20:18:16 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.165 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1283,6 +1283,10 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ /* gold isn't subject to cursing and blessing */ if (obj->oclass == COIN_CLASS) continue; + /* hide current scroll from itself so that perm_invent won't + show known blessed scroll losing bknown when confused */ + if (obj == sobj && obj->quan == 1L) + continue; wornmask = (obj->owornmask & ~(W_BALL | W_ART | W_ARTI)); if (wornmask && !sblessed) { /* handle a couple of special cases; we don't diff --git a/src/sit.c b/src/sit.c index b4e9d32ea..7fd1b0764 100644 --- a/src/sit.c +++ b/src/sit.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 sit.c $NHDT-Date: 1544442714 2018/12/10 11:51:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.59 $ */ +/* NetHack 3.6 sit.c $NHDT-Date: 1559670609 2019/06/04 17:50:09 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.61 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -392,7 +392,7 @@ rndcurse() if (!Blind) { pline("%s %s.", Yobjnam2(otmp, "glow"), hcolor(otmp->cursed ? NH_BLACK : (const char *) "brown")); - otmp->bknown = TRUE; + otmp->bknown = 1; /* ok to bypass set_bknown() here */ } } } diff --git a/src/steed.c b/src/steed.c index 9d5ec9da8..eca69c407 100644 --- a/src/steed.c +++ b/src/steed.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 steed.c $NHDT-Date: 1559422254 2019/06/01 20:50:54 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.64 $ */ +/* NetHack 3.6 steed.c $NHDT-Date: 1559670610 2019/06/04 17:50:10 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.66 $ */ /* Copyright (c) Kevin Hugo, 1998-1999. */ /* NetHack may be freely redistributed. See license for details. */ @@ -525,7 +525,7 @@ int reason; /* Player was thrown off etc. */ if (otmp && otmp->cursed) { You("can't. The saddle %s cursed.", otmp->bknown ? "is" : "seems to be"); - otmp->bknown = TRUE; + otmp->bknown = 1; /* ok to skip set_bknown() here */ return; } if (!have_spot) { diff --git a/src/teleport.c b/src/teleport.c index 24a4bd186..4ed074c41 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 teleport.c $NHDT-Date: 1559227830 2019/05/30 14:50:30 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.87 $ */ +/* NetHack 3.6 teleport.c $NHDT-Date: 1559733391 2019/06/05 11:16:31 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.88 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -59,16 +59,26 @@ unsigned gpflags; mdat = mtmp->data; if (is_pool(x, y) && !ignorewater) { + /* [what about Breathless?] */ if (mtmp == &g.youmonst) - return (Levitation || Flying || Wwalking || Swimming - || Amphibious); + return (Swimming || Amphibious + || (!Is_waterlevel(&u.uz) + /* water on the Plane of Water has no surface + so there's no way to be on or above that */ + && (Levitation || Flying || Wwalking))); else - return (is_floater(mdat) || is_flyer(mdat) || is_swimmer(mdat) - || is_clinger(mdat)); + return (is_swimmer(mdat) + || (!Is_waterlevel(&u.uz) + && (is_floater(mdat) || is_flyer(mdat) + || is_clinger(mdat)))); } else if (mdat->mlet == S_EEL && rn2(13) && !ignorewater) { return FALSE; } else if (is_lava(x, y)) { - if (mtmp == &g.youmonst) + /* 3.6.3: floating eye can levitate over lava but it avoids + that due the effect of the heat causing it to dry out */ + if (mdat == &mons[PM_FLOATING_EYE]) + return FALSE; + else if (mtmp == &g.youmonst) return (Levitation || Flying || (Fire_resistance && Wwalking && uarmf && uarmf->oerodeproof) diff --git a/src/timeout.c b/src/timeout.c index 971503d73..05f14fa92 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 timeout.c $NHDT-Date: 1545182148 2018/12/19 01:15:48 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.89 $ */ +/* NetHack 3.6 timeout.c $NHDT-Date: 1559664953 2019/06/04 16:15:53 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.90 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -403,6 +403,7 @@ struct kinfo *kptr; del_light_source(LS_MONSTER, monst_to_any(&g.youmonst)); save_mvflags = g.mvitals[PM_GREEN_SLIME].mvflags; g.mvitals[PM_GREEN_SLIME].mvflags = save_mvflags & ~G_GENOD; + /* become a green slime; also resets youmonst.m_ap_type+.mappearance */ (void) polymon(PM_GREEN_SLIME); g.mvitals[PM_GREEN_SLIME].mvflags = save_mvflags; done(TURNED_SLIME); @@ -410,10 +411,20 @@ struct kinfo *kptr; /* life-saved; even so, hero still has turned into green slime; player may have genocided green slimes after being infected */ if ((g.mvitals[PM_GREEN_SLIME].mvflags & G_GENOD) != 0) { + char slimebuf[BUFSZ]; + g.killer.format = KILLED_BY; Strcpy(g.killer.name, "slimicide"); - /* immediately follows "OK, so you don't die." */ - pline("Yes, you do. Green slime has been genocided..."); + /* vary the message depending upon whether life-save was due to + amulet or due to declining to die in explore or wizard mode */ + Strcpy(slimebuf, "green slime has been genocided..."); + if (iflags.last_msg == PLNMSG_OK_DONT_DIE) + /* follows "OK, so you don't die." and arg is second sentence */ + pline("Yes, you do. %s", upstart(slimebuf)); + else + /* follows "The medallion crumbles to dust." */ + pline("Unfortunately, %s", slimebuf); + /* die again; no possibility of amulet this time */ done(GENOCIDED); /* could be life-saved again (only in explore or wizard mode) but green slimes are gone; just stay in current form */ diff --git a/src/wield.c b/src/wield.c index 39c942e5a..784f71f14 100644 --- a/src/wield.c +++ b/src/wield.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 wield.c $NHDT-Date: 1543492132 2018/11/29 11:48:52 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.58 $ */ +/* NetHack 3.6 wield.c $NHDT-Date: 1559670611 2019/06/04 17:50:11 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.59 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -171,7 +171,7 @@ struct obj *wep; (wep->quan == 1L) ? "itself" : "themselves", /* a3 */ bimanual(wep) ? (const char *) makeplural(body_part(HAND)) : body_part(HAND)); - wep->bknown = TRUE; + set_bknown(wep, 1); } else { /* The message must be printed before setuwep (since * you might die and be revived from changing weapons), @@ -628,7 +628,7 @@ can_twoweapon() ; /* must be life-saved to reach here; return FALSE */ } else if (Glib || uswapwep->cursed) { if (!Glib) - uswapwep->bknown = TRUE; + set_bknown(uswapwep, 1); drop_uswapwep(); } else return TRUE; @@ -736,7 +736,7 @@ register int amount; if (!Blind) { Sprintf(buf, "%s with %s aura.", Yobjnam2(uwep, "glow"), an(hcolor(NH_AMBER))); - uwep->bknown = !Hallucination; + uwep->bknown = !Hallucination; /* ok to bypass set_bknown() */ } else { /* cursed tin opener is wielded in right hand */ Sprintf(buf, "Your right %s tingles.", body_part(HAND)); @@ -859,7 +859,7 @@ welded(obj) register struct obj *obj; { if (obj && obj == uwep && will_weld(obj)) { - obj->bknown = TRUE; + set_bknown(obj, 1); return 1; } return 0; diff --git a/src/zap.c b/src/zap.c index 755fcc4d2..aa53e0f84 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 zap.c $NHDT-Date: 1551395521 2019/02/28 23:12:01 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.307 $ */ +/* NetHack 3.6 zap.c $NHDT-Date: 1559685281 2019/06/04 21:54:41 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.310 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -118,6 +118,7 @@ struct obj *obj; if (obj->dknown) makeknown(obj->otyp); } + update_inventory(); } } @@ -575,11 +576,8 @@ struct obj *obj; coord *cc; boolean adjacentok; /* False: at obj's spot only, True: nearby is allowed */ { - struct monst *mtmp = (struct monst *) 0; - struct monst *mtmp2 = (struct monst *) 0; + struct monst *mtmp, *mtmp2 = has_omonst(obj) ? get_mtraits(obj, TRUE) : 0; - if (has_omonst(obj)) - mtmp2 = get_mtraits(obj, TRUE); if (mtmp2) { /* save_mtraits() validated mtmp2->mnum */ mtmp2->data = &mons[mtmp2->mnum]; @@ -588,8 +586,12 @@ boolean adjacentok; /* False: at obj's spot only, True: nearby is allowed */ mtmp = makemon(mtmp2->data, cc->x, cc->y, (NO_MINVENT | MM_NOWAIT | MM_NOCOUNTBIRTH | (adjacentok ? MM_ADJACENTOK : 0))); - if (!mtmp) - return mtmp; + if (!mtmp) { + /* mtmp2 is a copy of obj's object->oextra->omonst extension + and is not on the map or on any monst lists */ + dealloc_monst(mtmp2); + return (struct monst *) 0; + } /* heal the monster */ if (mtmp->mhpmax > mtmp2->mhpmax && is_rider(mtmp2->data)) @@ -1891,9 +1893,9 @@ struct obj *obj, *otmp; (void) boxlock(obj, otmp); if (obj_shudders(obj)) { - boolean cover = - ((obj == g.level.objects[u.ux][u.uy]) && u.uundetected - && hides_under(g.youmonst.data)); + boolean cover = ((obj == g.level.objects[u.ux][u.uy]) + && u.uundetected + && hides_under(g.youmonst.data)); if (cansee(obj->ox, obj->oy)) learn_it = TRUE; @@ -1926,6 +1928,7 @@ struct obj *obj, *otmp; obj->cknown = 0; } else { struct obj *o; + /* view contents (not recursively) */ for (o = obj->cobj; o; o = o->nobj) o->dknown = 1; /* "seen", even if blind */ @@ -2486,22 +2489,39 @@ boolean ordinary; learn_it = TRUE; unpunish(); } - if (u.utrap) { /* escape web or bear trap */ - (void) openholdingtrap(&g.youmonst, &learn_it); - } else { + /* invent is hit iff hero doesn't escape from a trap */ + if (!u.utrap || !openholdingtrap(&g.youmonst, &learn_it)) { struct obj *otmp; + boolean boxing = FALSE; + /* unlock carried boxes */ for (otmp = g.invent; otmp; otmp = otmp->nobj) - if (Is_box(otmp)) + if (Is_box(otmp)) { (void) boxlock(otmp, obj); + boxing = TRUE; + } + if (boxing) + update_inventory(); /* in case any box->lknown has changed */ + /* trigger previously escaped trapdoor */ (void) openfallingtrap(&g.youmonst, TRUE, &learn_it); } break; case WAN_LOCKING: case SPE_WIZARD_LOCK: - if (!u.utrap) { - (void) closeholdingtrap(&g.youmonst, &learn_it); + /* similar logic to opening; invent is hit iff no trap triggered */ + if (u.utrap || !closeholdingtrap(&g.youmonst, &learn_it)) { + struct obj *otmp; + boolean boxing = FALSE; + + /* lock carried boxes */ + for (otmp = g.invent; otmp; otmp = otmp->nobj) + if (Is_box(otmp)) { + (void) boxlock(otmp, obj); + boxing = TRUE; + } + if (boxing) + update_inventory(); /* in case any box->lknown has changed */ } break; case WAN_DIGGING: @@ -2520,6 +2540,7 @@ boolean ordinary; otmp->cknown = 1; } } + update_inventory(); learn_it = TRUE; ustatusline(); break; diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index b4755e55d..00e9e8a00 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -924,7 +924,7 @@ $(O)makedefs.o: $(CONFIG_H) $(INCL)\monattk.h $(INCL)\monflag.h $(INCL)\objcla $(U)makedefs.c @if not exist $(OBJ)\*.* echo creating directory $(OBJ:\=/) @if not exist $(OBJ)\*.* mkdir $(OBJ) - @$(cc) $(cflagsBuild) -Fo$@ $(U)makedefs.c + @$(cc) -DENUM_PM $(cflagsBuild) -Fo$@ $(U)makedefs.c # # date.h should be remade every time any of the source or include diff --git a/util/makedefs.c b/util/makedefs.c index bc0f559c6..cf7782592 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -217,6 +217,13 @@ static int FDECL(case_insensitive_comp, (const char *, const char *)); /* input, output, tmp */ static FILE *ifp, *ofp, *tfp; +static boolean use_enum = +#ifdef ENUM_PM + TRUE; +#else + FALSE; +#endif + #if defined(__BORLANDC__) && !defined(_WIN32) extern unsigned _stklen = STKSIZ; #endif @@ -2324,10 +2331,20 @@ do_permonst() Fprintf(ofp, "%s", Dont_Edit_Code); Fprintf(ofp, "#ifndef PM_H\n#define PM_H\n"); + if (use_enum) { + Fprintf(ofp, "\nenum monnums {"); +#if 0 + /* need #define ENUM_PM for the full NetHack build to include these */ + Fprintf(ofp, "\n NON_PM = -1,"); + Fprintf(ofp, "\n LOW_PM = 0,"); +#endif + } for (i = 0; mons[i].mlet; i++) { SpinCursor(3); - - Fprintf(ofp, "\n#define\tPM_"); + if (use_enum) + Fprintf(ofp, "\n PM_"); + else + Fprintf(ofp, "\n#define\tPM_"); if (mons[i].mlet == S_HUMAN && !strncmp(mons[i].mname, "were", 4)) Fprintf(ofp, "HUMAN_"); for (nam = c = tmpdup(mons[i].mname); *c; c++) @@ -2335,9 +2352,17 @@ do_permonst() *c -= (char) ('a' - 'A'); else if (*c < 'A' || *c > 'Z') *c = '_'; - Fprintf(ofp, "%s\t%d", nam, i); + if (use_enum) + Fprintf(ofp, "%s = %d,", nam, i); + else + Fprintf(ofp, "%s\t%d", nam, i); + } + if (use_enum) { + Fprintf(ofp, "\n\n NUMMONS = %d", i); + Fprintf(ofp, "\n};\n"); + } else { + Fprintf(ofp, "\n\n#define\tNUMMONS\t%d\n", i); } - Fprintf(ofp, "\n\n#define\tNUMMONS\t%d\n", i); Fprintf(ofp, "\n#endif /* PM_H */\n"); Fclose(ofp); return; diff --git a/win/win32/vs2017/makedefs.vcxproj b/win/win32/vs2017/makedefs.vcxproj index 708802ec9..1f6c1c49f 100644 --- a/win/win32/vs2017/makedefs.vcxproj +++ b/win/win32/vs2017/makedefs.vcxproj @@ -26,7 +26,7 @@ $(IncDir);$(SysWinntDir);%(AdditionalIncludeDirectories) - WIN32CON;DLB;MSWIN_GRAPHICS;%(PreprocessorDefinitions) + WIN32CON;DLB;MSWIN_GRAPHICS;ENUM_PM;%(PreprocessorDefinitions) @@ -59,4 +59,4 @@ - \ No newline at end of file +