pull request #386 - discovering teleport scroll

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
This commit is contained in:
PatR
2020-09-18 15:34:29 -07:00
parent 7592eebdf6
commit 81ec2bfa2a
6 changed files with 59 additions and 46 deletions
+4 -1
View 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 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' 'unchanged' instead of 'unlit'
replace worm tail placement code that reportedly led to a sanity_check warning replace worm tail placement code that reportedly led to a sanity_check warning
[no actual code problem found; might be compiler bug for 'xchar'] [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 curses: 'msg_window' option wasn't functional for curses unless the binary
also included tty support 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 for the remainder of the file
render the color names in the corresponding color when using the pick-a-color render the color names in the corresponding color when using the pick-a-color
menu for adding status highlights or menu colors via 'O' 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 Platform- and/or Interface-Specific New Features
+1 -2
View 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) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2007. */ /*-Copyright (c) Michael Allison, 2007. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1147,7 +1147,6 @@ struct instance_globals {
unsigned int stealmid; /* monster doing the stealing */ unsigned int stealmid; /* monster doing the stealing */
/* teleport.c */ /* teleport.c */
struct obj *telescroll; /* non-null when teleporting via this scroll */
/* timeout.c */ /* timeout.c */
/* ordered timer list */ /* ordered timer list */
+2 -2
View 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. */ /* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */ /* 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(safe_teleds, (int));
E boolean FDECL(teleport_pet, (struct monst *, BOOLEAN_P)); E boolean FDECL(teleport_pet, (struct monst *, BOOLEAN_P));
E void NDECL(tele); E void NDECL(tele);
E boolean FDECL(scrolltele, (struct obj *)); E void FDECL(scrolltele, (struct obj *));
E int NDECL(dotelecmd); E int NDECL(dotelecmd);
E int FDECL(dotele, (BOOLEAN_P)); E int FDECL(dotele, (BOOLEAN_P));
E void NDECL(level_tele); E void NDECL(level_tele);
+1 -2
View 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) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2009. */ /*-Copyright (c) Michael Allison, 2009. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -646,7 +646,6 @@ const struct instance_globals g_init = {
0, /* stealmid */ 0, /* stealmid */
/* teleport.c */ /* teleport.c */
NULL, /* telescroll */
/* timeout.c */ /* timeout.c */
UNDEFINED_PTR, /* timer_base */ UNDEFINED_PTR, /* timer_base */
+26 -2
View 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) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -217,9 +217,27 @@ doread()
register struct obj *scroll; register struct obj *scroll;
boolean confused, nodisappear; 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; g.known = FALSE;
if (check_capacity((char *) 0)) if (check_capacity((char *) 0))
return 0; return 0;
scroll = getobj(readable, "read"); scroll = getobj(readable, "read");
if (!scroll) if (!scroll)
return 0; return 0;
@@ -1358,8 +1376,14 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */
case SCR_TELEPORTATION: case SCR_TELEPORTATION:
if (confused || scursed) { if (confused || scursed) {
level_tele(); level_tele();
/* gives "materialize on different/same level!" message, must
be a teleport scroll */
g.known = TRUE;
} else { } 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; break;
case SCR_GOLD_DETECTION: case SCR_GOLD_DETECTION:
+25 -37
View 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) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */ /* 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() */ 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) if (levl[u.ux][u.uy].typ != levl[u.ux0][u.uy0].typ)
switch_terrain(); 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 /* 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 room entry message, if any, so need to check for vault exit prior
to spoteffects; but spoteffects() sets up new value for u.urooms to spoteffects; but spoteffects() sets up new value for u.urooms
@@ -493,26 +484,22 @@ boolean force_it;
void void
tele() tele()
{ {
(void) scrolltele((struct obj *) 0); scrolltele((struct obj *) 0);
} }
/* teleport the hero; return true if scroll of teleportation should become /* teleport the hero; usually discover scroll of teleporation if via scroll */
discovered; teleds() will usually do the actual discovery, since the void
outcome sometimes depends upon destination and discovery needs to be
performed before arrival, in case we land on another teleport scroll */
boolean
scrolltele(scroll) scrolltele(scroll)
struct obj *scroll; struct obj *scroll;
{ {
coord cc; coord cc;
boolean result = FALSE; /* don't learn scroll */
/* Disable teleportation in stronghold && Vlad's Tower */ /* Disable teleportation in stronghold && Vlad's Tower */
if (noteleport_level(&g.youmonst)) { if (noteleport_level(&g.youmonst) && !wizard) {
if (!wizard) { pline("A mysterious force prevents you from teleporting!");
pline("A mysterious force prevents you from teleporting!"); if (scroll)
return TRUE; learnscroll(scroll); /* this is obviously a teleport scroll */
} return;
} }
/* don't show trap if "Sorry..." */ /* 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)) { if ((u.uhave.amulet || On_W_tower_level(&u.uz)) && !rn2(3)) {
You_feel("disoriented for a moment."); 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') if (!wizard || yn("Override?") != 'y')
return FALSE; return;
} }
if ((Teleport_control && !Stunned) || (scroll && scroll->blessed) if (((Teleport_control || (scroll && scroll->blessed)) && !Stunned)
|| wizard) { || wizard) {
if (unconscious()) { if (unconscious()) {
pline("Being unconscious, you cannot control your teleport."); pline("Being unconscious, you cannot control your teleport.");
} else { } else {
@@ -535,32 +524,31 @@ struct obj *scroll;
if (u.usteed) if (u.usteed)
Sprintf(eos(whobuf), " and %s", mon_nam(u.usteed)); Sprintf(eos(whobuf), " and %s", mon_nam(u.usteed));
pline("Where do %s want to be teleported?", whobuf); pline("Where do %s want to be teleported?", whobuf);
if (scroll)
learnscroll(scroll);
cc.x = u.ux; cc.x = u.ux;
cc.y = u.uy; cc.y = u.uy;
if (getpos(&cc, TRUE, "the desired position") < 0) if (getpos(&cc, TRUE, "the desired position") < 0)
return TRUE; /* abort */ return; /* abort */
/* possible extensions: introduce a small error if /* possible extensions: introduce a small error if
magic power is low; allow transfer to solid rock */ magic power is low; allow transfer to solid rock */
if (teleok(cc.x, cc.y, FALSE)) { if (teleok(cc.x, cc.y, FALSE)) {
/* for scroll, discover it regardless of destination */ /* for scroll, discover it regardless of destination */
if (scroll)
learnscroll(scroll);
teleds(cc.x, cc.y, TELEDS_TELEPORT); teleds(cc.x, cc.y, TELEDS_TELEPORT);
return TRUE; return;
} }
pline("Sorry..."); 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); (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 */ /* ^T command; 'm ^T' == choose among several teleport modes */