diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 4e7535c4d..f51073320 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.302 $ $NHDT-Date: 1600179998 2020/09/15 14:26:38 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.303 $ $NHDT-Date: 1600468452 2020/09/18 22:34:12 $ General Fixes and Modified Features ----------------------------------- @@ -330,6 +330,8 @@ change default for lit attribute in special level des.terrain directives to 'unchanged' instead of 'unlit' replace worm tail placement code that reportedly led to a sanity_check warning [no actual code problem found; might be compiler bug for 'xchar'] +learn scroll of teleportation after reading even when random destination is + right by starting spot curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support @@ -524,6 +526,7 @@ add section marker [] support to run-time config file; CHOOSE section1,section2 for the remainder of the file render the color names in the corresponding color when using the pick-a-color menu for adding status highlights or menu colors via 'O' +reading blessed scroll of teleportation confers one-shot teleport control Platform- and/or Interface-Specific New Features diff --git a/include/decl.h b/include/decl.h index 453b450ae..be1d583ac 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.h $NHDT-Date: 1599778430 2020/09/10 22:53:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.241 $ */ +/* NetHack 3.7 decl.h $NHDT-Date: 1600468452 2020/09/18 22:34:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.242 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1147,7 +1147,6 @@ struct instance_globals { unsigned int stealmid; /* monster doing the stealing */ /* teleport.c */ - struct obj *telescroll; /* non-null when teleporting via this scroll */ /* timeout.c */ /* ordered timer list */ diff --git a/include/extern.h b/include/extern.h index c1f2ae298..121117674 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1599559379 2020/09/08 10:02:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.856 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1600468452 2020/09/18 22:34:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.857 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2586,7 +2586,7 @@ E void FDECL(teleds, (int, int, int)); E boolean FDECL(safe_teleds, (int)); E boolean FDECL(teleport_pet, (struct monst *, BOOLEAN_P)); E void NDECL(tele); -E boolean FDECL(scrolltele, (struct obj *)); +E void FDECL(scrolltele, (struct obj *)); E int NDECL(dotelecmd); E int FDECL(dotele, (BOOLEAN_P)); E void NDECL(level_tele); diff --git a/src/decl.c b/src/decl.c index 7bcf2501a..4c836bbde 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.c $NHDT-Date: 1599778430 2020/09/10 22:53:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.217 $ */ +/* NetHack 3.7 decl.c $NHDT-Date: 1600468453 2020/09/18 22:34:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.218 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -646,7 +646,6 @@ const struct instance_globals g_init = { 0, /* stealmid */ /* teleport.c */ - NULL, /* telescroll */ /* timeout.c */ UNDEFINED_PTR, /* timer_base */ diff --git a/src/read.c b/src/read.c index fb2c1ced1..42b1040a2 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 read.c $NHDT-Date: 1596498202 2020/08/03 23:43:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.201 $ */ +/* NetHack 3.7 read.c $NHDT-Date: 1600468453 2020/09/18 22:34:13 $ $NHDT-Branch: NetHack-3.7 $:$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. */ @@ -217,9 +217,27 @@ doread() register struct obj *scroll; boolean confused, nodisappear; + /* + * Reading while blind is allowed in most cases, including the + * Book of the Dead but not regular spellbooks. For scrolls, the + * description has to have been seen or magically learned (so only + * when scroll->dknown is true): hero recites the label while + * holding the unfurled scroll. We deliberately don't require + * free hands because that would cripple scroll of remove curse, + * but we ought to be requiring hands or at least limbs. The + * recitation could be sub-vocal; actual speech isn't required. + * + * Reading while confused is allowed and can produce alternate + * outcome. + * + * Reading while stunned is currently allowed but probably should + * be prevented.... + */ + g.known = FALSE; if (check_capacity((char *) 0)) return 0; + scroll = getobj(readable, "read"); if (!scroll) return 0; @@ -1358,8 +1376,14 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ case SCR_TELEPORTATION: if (confused || scursed) { level_tele(); + /* gives "materialize on different/same level!" message, must + be a teleport scroll */ + g.known = TRUE; } else { - g.known = scrolltele(sobj); + scrolltele(sobj); + /* this will call learnscroll() as appropriate, and has results + which maybe shouldn't result in the scroll becoming known; + either way, no need to set g.known here */ } break; case SCR_GOLD_DETECTION: diff --git a/src/teleport.c b/src/teleport.c index 9f291af99..f51001a7e 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 teleport.c $NHDT-Date: 1596498216 2020/08/03 23:43:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.126 $ */ +/* NetHack 3.7 teleport.c $NHDT-Date: 1600468454 2020/09/18 22:34:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -401,15 +401,6 @@ int teleds_flags; been updated for new location instead of right after u_on_newpos() */ if (levl[u.ux][u.uy].typ != levl[u.ux0][u.uy0].typ) switch_terrain(); - if (g.telescroll) { - /* when teleporting by scroll, we need to handle discovery - now before getting feedback about any objects at our - destination since we might land on another such scroll */ - if (distu(u.ux0, u.uy0) >= 16 || !couldsee(u.ux0, u.uy0)) - learnscroll(g.telescroll); - else - g.telescroll = 0; /* no discovery by scrolltele()'s caller */ - } /* sequencing issue: we want guard's alarm, if any, to occur before room entry message, if any, so need to check for vault exit prior to spoteffects; but spoteffects() sets up new value for u.urooms @@ -493,26 +484,22 @@ boolean force_it; void tele() { - (void) scrolltele((struct obj *) 0); + scrolltele((struct obj *) 0); } -/* teleport the hero; return true if scroll of teleportation should become - discovered; teleds() will usually do the actual discovery, since the - outcome sometimes depends upon destination and discovery needs to be - performed before arrival, in case we land on another teleport scroll */ -boolean +/* teleport the hero; usually discover scroll of teleporation if via scroll */ +void scrolltele(scroll) struct obj *scroll; { coord cc; - boolean result = FALSE; /* don't learn scroll */ /* Disable teleportation in stronghold && Vlad's Tower */ - if (noteleport_level(&g.youmonst)) { - if (!wizard) { - pline("A mysterious force prevents you from teleporting!"); - return TRUE; - } + if (noteleport_level(&g.youmonst) && !wizard) { + pline("A mysterious force prevents you from teleporting!"); + if (scroll) + learnscroll(scroll); /* this is obviously a teleport scroll */ + return; } /* don't show trap if "Sorry..." */ @@ -521,11 +508,13 @@ struct obj *scroll; if ((u.uhave.amulet || On_W_tower_level(&u.uz)) && !rn2(3)) { You_feel("disoriented for a moment."); + /* don't discover the scroll [at least not yet for wizard override]; + disorientation doesn't reveal that this is a teleport attempt */ if (!wizard || yn("Override?") != 'y') - return FALSE; + return; } - if ((Teleport_control && !Stunned) || (scroll && scroll->blessed) - || wizard) { + if (((Teleport_control || (scroll && scroll->blessed)) && !Stunned) + || wizard) { if (unconscious()) { pline("Being unconscious, you cannot control your teleport."); } else { @@ -535,32 +524,31 @@ struct obj *scroll; if (u.usteed) Sprintf(eos(whobuf), " and %s", mon_nam(u.usteed)); pline("Where do %s want to be teleported?", whobuf); + if (scroll) + learnscroll(scroll); cc.x = u.ux; cc.y = u.uy; if (getpos(&cc, TRUE, "the desired position") < 0) - return TRUE; /* abort */ + return; /* abort */ /* possible extensions: introduce a small error if magic power is low; allow transfer to solid rock */ if (teleok(cc.x, cc.y, FALSE)) { /* for scroll, discover it regardless of destination */ - if (scroll) - learnscroll(scroll); teleds(cc.x, cc.y, TELEDS_TELEPORT); - return TRUE; + return; } pline("Sorry..."); - result = TRUE; } } - g.telescroll = scroll; + /* we used to suppress discovery if hero teleported to a nearby + spot which was already within view, but now there is always a + "materialize" message regardless of how far you teleported so + discovery of scroll type is unconditional */ + if (scroll) + learnscroll(scroll); + (void) safe_teleds(TELEDS_TELEPORT); - /* teleds() will leave g.telescroll intact iff random destination - is far enough away for scroll discovery to be warranted */ - if (g.telescroll) - result = TRUE; - g.telescroll = 0; /* reset */ - return result; } /* ^T command; 'm ^T' == choose among several teleport modes */