]> granicus.if.org Git - nethack/commitdiff
pull request #386 - discovering teleport scroll
authorPatR <rankin@nethack.org>
Fri, 18 Sep 2020 22:34:29 +0000 (15:34 -0700)
committerPatR <rankin@nethack.org>
Fri, 18 Sep 2020 22:34:29 +0000 (15:34 -0700)
Since teleporation gives a "you matrialize" message even when
arriving close by, the old behavior of not learning a scroll of
teleportation when you land quite close to your original spot
no longer made sense.  Always [almost] discover teleport scroll
when reading it.

Also adds one-shot teleport control when reading a blessed scroll
of teleportation.  I changed that to be prevented when hero is
stunned, same as with full-fledged teleport control.

I reworded or reformatted several of the comments.  And removed
the EDITLEVEL increment in patchlevel.h; save and bones file
contents are not affected.

I've also added an unrelated comment about reading mechanics to
doread().

Closes #386

doc/fixes37.0
include/decl.h
include/extern.h
src/decl.c
src/read.c
src/teleport.c

index 4e7535c4d72a42590367bd11150f2eaca40fea2a..f510733201b4de1571fcc27f86e3ccf4841425dd 100644 (file)
@@ -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
index 453b450ae603d5ebfae70a38c7a0e3f8cd6c4b90..be1d583ac1fea05fa16b8063094915d8f84ca7d7 100644 (file)
@@ -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 */
index c1f2ae298c3f223dc34c8cce9949498ec4f3101b..121117674217b9e0ccccfa4ee4451f964ef3e672 100644 (file)
@@ -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);
index 7bcf2501a1ef5976e68273bf3d4540d0a746f5bd..4c836bbdeff17c8abe3e02e42ac60201ebad3c6d 100644 (file)
@@ -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 */
index fb2c1ced17e6b5503b0887a3c46b313a173bae81..42b1040a2e060ee3b46e49e652d50fa9642f4a53 100644 (file)
@@ -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:
index 9f291af99d475e93a3c7eb7238c07801151cfc40..f51001a7e8345de294dabb2ee03bd84eeec5a434 100644 (file)
@@ -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 */