]> granicus.if.org Git - nethack/commitdiff
randomized trap names
authorPatR <rankin@nethack.org>
Fri, 10 Jan 2020 02:45:06 +0000 (18:45 -0800)
committerPatR <rankin@nethack.org>
Fri, 10 Jan 2020 02:45:06 +0000 (18:45 -0800)
Use trapname() in several more places.  I wasn't systematic about it.

trapname() could generate a random value of 0 and attempt to use
"real trap #0" but 0 is NO_TRAP.  So it ended up with "water" from
the preceding block of entries in defsyms[].  Treat 0 as an extra
chance for the actual trap instead of an hallucinatory one.

Add a couple more hallucinatory traps.  "Roach Motel" is trademarked
but like Spam and Band-Aid, general usage has trampled over it.  I
included "(tm)" anyway.  Also, sometimes generate "<role> trap" or
"<rank> trap" on the fly.  Why should tourists get all the fun?

doc/fixes37.0
src/trap.c

index cdbb584d3a5eac5f4d48e525c9cf9aa4c13fd736..54669c251d2bd137947323857f28a2d4cb4be74a 100644 (file)
@@ -1,4 +1,4 @@
-$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ $NHDT-Date: 1578400811 2020/01/07 12:40:11 $
+$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.58 $ $NHDT-Date: 1578624299 2020/01/10 02:44:59 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -55,6 +55,7 @@ autounlock picked Rogue's artifact key over lock-pick or credit card (or
        ordinary key depending upon invent order) even for non-rogues who
        would be blasted when touching it
 wielded aklys had its "(tethered weapon...)" description scrambled
+randomized trap name could pick trap #0 which isn't a trap and yielded "water"
 
 
 Platform- and/or Interface-Specific Fixes
index 8d25a8b77128c08d1c1753187edf916755245649..7eeded57a1177512e8f9207eb2faa42bed3c81c5 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 trap.c  $NHDT-Date: 1577759854 2019/12/31 02:37:34 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.348 $ */
+/* NetHack 3.6 trap.c  $NHDT-Date: 1578624299 2020/01/10 02:44:59 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.349 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2013. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -954,6 +954,14 @@ unsigned trflags;
             steed_article = ARTICLE_NONE;
     }
 
+    /*
+     * Note:
+     *  Most references to trap types here don't use trapname() for
+     *  hallucination.  This could be considered to be a bug but doing
+     *  that would hide the actual trap situation from the player which
+     *  would be somewhat harsh for what's usually a minor impairment.
+     */
+
     switch (ttype) {
     case ARROW_TRAP:
         if (trap->once && trap->tseen && !rn2(15)) {
@@ -2831,7 +2839,7 @@ float_up()
     if (u.utrap) {
         if (u.utraptype == TT_PIT) {
             reset_utrap(FALSE);
-            You("float up, out of the pit!");
+            You("float up, out of the %s!", trapname(PIT, FALSE));
             g.vision_full_recalc = 1; /* vision limits change */
             fill_pit(u.ux, u.uy);
         } else if (u.utraptype == TT_LAVA /* molten lava */
@@ -2852,7 +2860,8 @@ float_up()
                 body_part(LEG),
                 IS_ROOM(levl[cc.x][cc.y].typ) ? "floor" : "ground");
         } else if (u.utraptype == WEB) {
-            You("float up slightly, but you are still stuck in the web.");
+            You("float up slightly, but you are still stuck in the %s.",
+                trapname(WEB, FALSE));
         } else { /* bear trap */
             You("float up slightly, but your %s is still stuck.",
                 body_part(LEG));
@@ -3068,12 +3077,15 @@ long hmask, emask; /* might cancel timeout */
 void
 climb_pit()
 {
+    const char *pitname;
+
     if (!u.utrap || u.utraptype != TT_PIT)
         return;
 
+    pitname = trapname(PIT, FALSE);
     if (Passes_walls) {
         /* marked as trapped so they can pick things up */
-        You("ascend from the pit.");
+        You("ascend from the %s.", pitname);
         reset_utrap(FALSE);
         fill_pit(u.ux, u.uy);
         g.vision_full_recalc = 1; /* vision limits change */
@@ -3085,19 +3097,24 @@ climb_pit()
     } else if ((Flying || is_clinger(g.youmonst.data)) && !Sokoban) {
         /* eg fell in pit, then poly'd to a flying monster;
            or used '>' to deliberately enter it */
-        You("%s from the pit.", Flying ? "fly" : "climb");
+        You("%s from the %s.", Flying ? "fly" : "climb", pitname);
         reset_utrap(FALSE);
         fill_pit(u.ux, u.uy);
         g.vision_full_recalc = 1; /* vision limits change */
     } else if (!(--u.utrap)) {
         reset_utrap(FALSE);
-        You("%s to the edge of the pit.",
+        You("%s to the edge of the %s.",
             (Sokoban && Levitation)
                 ? "struggle against the air currents and float"
-                : u.usteed ? "ride" : "crawl");
+                : u.usteed ? "ride" : "crawl",
+            pitname);
         fill_pit(u.ux, u.uy);
         g.vision_full_recalc = 1; /* vision limits change */
     } else if (u.dz || flags.verbose) {
+        /* these should use 'pitname' rather than "pit" for hallucination
+           but that would nullify Norep (this message can be repeated
+           many times without further user intervention by using a run
+           attempt to keep retrying to escape from the pit) */
         if (u.usteed)
             Norep("%s is still in a pit.", upstart(y_monnam(u.usteed)));
         else
@@ -5455,9 +5472,6 @@ maybe_finish_sokoban()
  * If the second argument is true, return the correct trap name even when
  * hallucinating (for things like wizard mode wishing for traps and impossible
  * calls).
- * Originally I had intended for messages like "You begin setting the bear trap"
- * to override as well, but the context in those bits of code indicated that it
- * was meant to take a random name if the hero was hallucinating.
  */
 const char *
 trapname(ttyp, override)
@@ -5469,6 +5483,7 @@ boolean override;
         "bottomless pit", "polymorphism trap", "devil teleporter",
         "falling boulder trap", "anti-anti-magic field", "weeping gas trap",
         "queasy board", "electrified web", "owlbear trap", "sand mine",
+        "vacillating triangle",
         /* some traps found in nethack variants */
         "death trap", "disintegration trap", "ice trap", "monochrome trap",
         /* plausible real-life traps */
@@ -5476,7 +5491,7 @@ boolean override;
         "field of caltrops", "buzzsaw trap", "spiked floor", "revolving wall",
         "uneven floor", "finger trap", "jack-in-a-box", "yellow snow",
         "booby trap", "rat trap", "poisoned nail", "snare", "whirlpool",
-        "trip wire",
+        "trip wire", "roach motel (tm)",
         /* sci-fi */
         "negative space", "tensor field", "singularity", "imperial fleet",
         "black hole", "thermal detonator", "event horizon",
@@ -5484,22 +5499,33 @@ boolean override;
         /* miscellaneous suggestions */
         "sweet-smelling gas vent", "phone booth", "exploding runes",
         "never-ending elevator", "slime pit", "warp zone", "illusory floor",
-        "pile of poo", "honey trap", "tourist trap"
+        "pile of poo", "honey trap", "tourist trap",
     };
-    int total_names, nameidx;
-
-    if (override || !Hallucination) {
-        return defsyms[trap_to_defsym(ttyp)].explanation;
-    }
-    total_names = TRAPNUM + SIZE(halu_trapnames);
-    nameidx = rn2_on_display_rng(total_names);
-    if (nameidx < TRAPNUM) {
-        /* random but real trap name */
-        return defsyms[trap_to_defsym(nameidx)].explanation;
-    } else {
-        nameidx -= TRAPNUM;
-        return halu_trapnames[nameidx];
-    }
+    static char roletrap[33]; /* [17 + 5 + 1] should suffice */
+
+    if (Hallucination && !override) {
+        int total_names = TRAPNUM + SIZE(halu_trapnames),
+            nameidx = rn2_on_display_rng(total_names + 1);
+
+        if (nameidx == total_names) {
+            boolean fem = Upolyd ? u.mfemale : flags.female;
+
+            /* inspired by "tourist trap" */
+            copynchars(roletrap,
+                       rn2(3) ? ((fem && g.urole.name.f) ? g.urole.name.f
+                                                         : g.urole.name.m)
+                              : rank_of(u.ulevel, Role_switch, fem),
+                       (int) (sizeof roletrap - sizeof " trap"));
+            Strcat(roletrap, " trap");
+            return lcase(roletrap);
+        } else if (nameidx >= TRAPNUM) {
+            nameidx -= TRAPNUM;
+            return halu_trapnames[nameidx];
+        } /* else use an actual trap type */
+        if (nameidx != NO_TRAP)
+            ttyp = nameidx;
+    }
+    return defsyms[trap_to_defsym(ttyp)].explanation;
 }
 
 /*trap.c*/