fix #H5547 - named vampire shapeshifting message
authorPatR <rankin@nethack.org>
Sat, 3 Jun 2017 23:05:23 +0000 (16:05 -0700)
committerPatR <rankin@nethack.org>
Sat, 3 Jun 2017 23:05:23 +0000 (16:05 -0700)
Report was about "Pet vampire" but the relevant aspect was that the
vampire had been assigned a name, not that it was tame:
You observe a Hilda where a Hilda was.

Investigating this has uncovered two other bugs, one potentially
serious.  m_monnam() overrides hallucination but seems to be getting
used to some situations where hallucination should be honored (several
instances).  Dynamically constructed format strings are including
monster or object names in the format (rather than the usual use as
arguments), so player assigned names containing percent signs could
cause havoc (a few instances).  This fixes some of the former and one
of the latter, but doesn't deal with various other cases revealed by
grep.

doc/fixes36.1
include/decl.h
include/extern.h
src/do_name.c
src/mon.c
src/monmove.c

index 3206662399a36becf56895feb177d4b78d87fdad..5f13a649c8961315fb5f1bbfbe78b7207a403d42 100644 (file)
@@ -389,6 +389,8 @@ poor message when shape-shifted vampire reverts if cause of 'death' was
        The vampire bat is disintegrated.  The vampire bat suddenly transforms
        and rises as a vampire.  (fix: switch to existing alternate phrasing
        used for amorphous form, "reconstitute" rather than "transform")
+poor message when named vampire shifts shape within view:
+       You observe a Dracula where a Dracula was.
 adult green dragons and the Chromatic Dragon were blinded by gas clouds
 
 
index 21edb3cac0909c22832854cbc1a2bb255ba17aa5..811324abb1eb8f2973d2762b4f322ef8401d8134 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6  decl.h  $NHDT-Date: 1432512782 2015/05/25 00:13:02 $  $NHDT-Branch: master $:$NHDT-Revision: 1.76 $ */
+/* NetHack 3.6  decl.h  $NHDT-Date: 1496531104 2017/06/03 23:05:04 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.82 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -317,6 +317,7 @@ E const char *materialnm[];
 #define SUPPRESS_HALLUCINATION 0x04
 #define SUPPRESS_SADDLE 0x08
 #define EXACT_NAME 0x0F
+#define SUPPRESS_NAME 0x10
 
 /* Vision */
 E NEARDATA boolean vision_full_recalc; /* TRUE if need vision recalc */
index cabdb51b0459dc23df7e7cc383c18373c4cbe72a..98a258cef0183b8da5dfec8be0c6dcdaa024eaf9 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 extern.h        $NHDT-Date: 1495346095 2017/05/21 05:54:55 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.588 $ */
+/* NetHack 3.6 extern.h        $NHDT-Date: 1496531111 2017/06/03 23:05:11 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.589 $ */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -404,6 +404,7 @@ E char *FDECL(mon_nam, (struct monst *));
 E char *FDECL(noit_mon_nam, (struct monst *));
 E char *FDECL(Monnam, (struct monst *));
 E char *FDECL(noit_Monnam, (struct monst *));
+E char *FDECL(noname_monnam, (struct monst *, int));
 E char *FDECL(m_monnam, (struct monst *));
 E char *FDECL(y_monnam, (struct monst *));
 E char *FDECL(Adjmonnam, (struct monst *, const char *));
index aa8bdf1e97c40f5f6699252efb44088292ddf409..452f6c555b8b057303985a42a00ba8f53afc36ee 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 do_name.c       $NHDT-Date: 1495494156 2017/05/22 23:02:36 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.118 $ */
+/* NetHack 3.6 do_name.c       $NHDT-Date: 1496531112 2017/06/03 23:05:12 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.119 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -1392,6 +1392,8 @@ rndghostname()
  * a_monnam:    a newt          it      an invisible orc        Fido
  * m_monnam:    newt            xan     orc                     Fido
  * y_monnam:    your newt     your xan  your invisible orc      Fido
+ * noname_monnam(mon,article):
+ *              article newt    art xan art invisible orc       art dog
  */
 
 /* Bug: if the monster is a priest or shopkeeper, not every one of these
@@ -1412,13 +1414,14 @@ const char *adjective;
 int suppress;
 /* SUPPRESS_IT, SUPPRESS_INVISIBLE, SUPPRESS_HALLUCINATION, SUPPRESS_SADDLE.
  * EXACT_NAME: combination of all the above
+ * SUPPRESS_NAME: omit monster's assigned name (unless uniq w/ pname).
  */
 boolean called;
 {
     char *buf = nextmbuf();
     struct permonst *mdat = mtmp->data;
     const char *pm_name = mdat->mname;
-    boolean do_hallu, do_invis, do_it, do_saddle;
+    boolean do_hallu, do_invis, do_it, do_saddle, do_name;
     boolean name_at_start, has_adjectives;
     char *bp;
 
@@ -1433,6 +1436,7 @@ boolean called;
             && !program_state.gameover && mtmp != u.usteed
             && !(u.uswallow && mtmp == u.ustuck) && !(suppress & SUPPRESS_IT);
     do_saddle = !(suppress & SUPPRESS_SADDLE);
+    do_name = !(suppress & SUPPRESS_NAME) || type_is_pname(mdat);
 
     buf[0] = '\0';
 
@@ -1513,7 +1517,7 @@ boolean called;
 
         Strcat(buf, rname);
         name_at_start = bogon_is_pname(rnamecode);
-    } else if (has_mname(mtmp)) {
+    } else if (do_name && has_mname(mtmp)) {
         char *name = MNAME(mtmp);
 
         if (mdat == &mons[PM_GHOST]) {
@@ -1608,7 +1612,7 @@ struct monst *mtmp;
 {
     return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
                     (has_mname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT)
-                                       : SUPPRESS_IT,
+                                      : SUPPRESS_IT,
                     FALSE);
 }
 
@@ -1632,7 +1636,17 @@ struct monst *mtmp;
     return  bp;
 }
 
-/* monster's own name */
+/* return "a dog" rather than "Fido", honoring hallucination and visibility */
+char *
+noname_monnam(mtmp, article)
+struct monst *mtmp;
+int article;
+{
+    return x_monnam(mtmp, article, (char *) 0, SUPPRESS_NAME, FALSE);
+}
+
+/* monster's own name -- overrides hallucination and [in]visibility
+   so shouldn't be used in ordinary messages (mainly for disclosure) */
 char *
 m_monnam(mtmp)
 struct monst *mtmp;
index ddd8e3a8a67bdd2c1da7832a776040a987552949..33a84372e2049823416d7a11ab8f0a9f4f5e2907 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -1,4 +1,4 @@
-/* NetHack 3.6 mon.c   $NHDT-Date: 1495849874 2017/05/27 01:51:14 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.239 $ */
+/* NetHack 3.6 mon.c   $NHDT-Date: 1496531114 2017/06/03 23:05:14 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.240 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -3458,7 +3458,7 @@ boolean msg;      /* "The oldmon turns into a newmon!" */
 
                     if (is_vampshifter(mtmp)) {
                         Sprintf(msgtrail, " which was a shapeshifted %s",
-                                m_monnam(mtmp));
+                                noname_monnam(mtmp, ARTICLE_NONE));
                     } else if (is_animal(mdat)) {
                         Strcpy(msgtrail, "'s stomach");
                     } else {
@@ -3500,16 +3500,7 @@ boolean msg;      /* "The oldmon turns into a newmon!" */
     newsym(mtmp->mx, mtmp->my);
 
     if (msg) {
-        char *save_mname = 0;
-
-        if (has_mname(mtmp)) {
-            save_mname = MNAME(mtmp);
-            MNAME(mtmp) = (char *) 0;
-        }
-        Strcpy(newname, (mdat == &mons[PM_GREEN_SLIME])
-                            ? "slime"
-                            : x_monnam(mtmp, ARTICLE_A, (char *) 0,
-                                       SUPPRESS_SADDLE, FALSE));
+        Strcpy(newname, noname_monnam(mtmp, ARTICLE_A));
         /* oldname was capitalized above; newname will be lower case */
         if (!strcmpi(newname, "it")) { /* can't see or sense it now */
             if (!!strcmpi(oldname, "it")) /* could see or sense it before */
@@ -3521,8 +3512,6 @@ boolean msg;      /* "The oldmon turns into a newmon!" */
             else
                 pline("%s turns into %s!", oldname, newname);
         }
-        if (save_mname)
-            MNAME(mtmp) = save_mname;
     }
 
     /* when polymorph trap/wand/potion produces a vampire, turn in into
index 0b60d0c1545b2149da081172a3b9a81b12269bb4..ece138bba80c7a2385d779fb5fd32a74f1d54bd3 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 monmove.c       $NHDT-Date: 1463704424 2016/05/20 00:33:44 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.87 $ */
+/* NetHack 3.6 monmove.c       $NHDT-Date: 1496531115 2017/06/03 23:05:15 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.90 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -1625,13 +1625,11 @@ struct permonst *ptr;
 boolean domsg;
 {
     int reslt = 0;
-    char fmtstr[BUFSZ];
+    char oldmtype[BUFSZ];
+
+    /* remember current monster type before shapechange */
+    Strcpy(oldmtype, domsg ? noname_monnam(mon, ARTICLE_THE) : "");
 
-    if (domsg) {
-        Sprintf(fmtstr, "You %s %%s where %s was.",
-                sensemon(mon) ? "now detect" : "observe",
-                an(m_monnam(mon)));
-    }
     if (mon->data == ptr) {
         /* already right shape */
         reslt = 1;
@@ -1639,9 +1637,13 @@ boolean domsg;
     } else if (is_vampshifter(mon)) {
         reslt = newcham(mon, ptr, FALSE, FALSE);
     }
+
     if (reslt && domsg) {
-        pline(fmtstr, an(m_monnam(mon)));
+        pline("You %s %s where %s was.",
+              !canseemon(mon) ? "now detect" : "observe",
+              noname_monnam(mon, ARTICLE_A), oldmtype);
     }
+
     return reslt;
 }