]> granicus.if.org Git - nethack/commitdiff
readobjnam() tidying
authorPatR <rankin@nethack.org>
Thu, 9 Jan 2020 02:01:04 +0000 (18:01 -0800)
committerPatR <rankin@nethack.org>
Thu, 9 Jan 2020 02:01:04 +0000 (18:01 -0800)
Move wizard mode wishing for traps and terrain from readobjnam() to a
separate routine.

src/objnam.c

index 874c66cbec4c9111ba902ff8990c8121f783b43b..fa3baf442f85d85c51d1d83debbdfb12c6cb17ae 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 objnam.c        $NHDT-Date: 1578532901 2020/01/09 01:21:41 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.284 $ */
+/* NetHack 3.7 objnam.c        $NHDT-Date: 1578535246 2020/01/09 02:00:46 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.285 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2011. */
 /* NetHack may be freely redistributed.  See license for details. */
 #define NUMOBUF 12
 
 static char *FDECL(strprepend, (char *, const char *));
-static short FDECL(rnd_otyp_by_wpnskill, (SCHAR_P));
-static short FDECL(rnd_otyp_by_namedesc, (const char *, CHAR_P, int));
-static boolean FDECL(wishymatch, (const char *, const char *, BOOLEAN_P));
 static char *NDECL(nextobuf);
 static void FDECL(releaseobuf, (char *));
+static char *FDECL(xname_flags, (struct obj *, unsigned));
 static char *FDECL(minimal_xname, (struct obj *));
 static void FDECL(add_erosion_words, (struct obj *, char *));
 static char *FDECL(doname_base, (struct obj *obj, unsigned));
 static boolean FDECL(singplur_lookup, (char *, char *, BOOLEAN_P,
-                                           const char *const *));
+                                       const char *const *));
 static char *FDECL(singplur_compound, (char *));
-static char *FDECL(xname_flags, (struct obj *, unsigned));
 static boolean FDECL(badman, (const char *, BOOLEAN_P));
+static boolean FDECL(wishymatch, (const char *, const char *, BOOLEAN_P));
+static short FDECL(rnd_otyp_by_wpnskill, (SCHAR_P));
+static short FDECL(rnd_otyp_by_namedesc, (const char *, CHAR_P, int));
+static struct obj *FDECL(wizterrainwish, (char *, char *, int, int));
 
 struct Jitem {
     int item;
@@ -2944,6 +2945,169 @@ char oclass;
     return (int) rnd_otyp_by_namedesc("shiny", oclass, 0);
 }
 
+/* in wizard mode, readobjnam() can accept wishes for traps and terrain */
+static struct obj *
+wizterrainwish(bp, p, locked, trapped)
+char *bp, *p;
+int locked, trapped;
+{
+    struct rm *lev;
+    boolean madeterrain = FALSE, badterrain = FALSE;
+    int trap, x = u.ux, y = u.uy;
+
+    for (trap = NO_TRAP + 1; trap < TRAPNUM; trap++) {
+        struct trap *t;
+        const char *tname;
+
+        tname = trapname(trap, TRUE);
+        if (strncmpi(tname, bp, strlen(tname)))
+            continue;
+        /* found it; avoid stupid mistakes */
+        if (is_hole(trap) && !Can_fall_thru(&u.uz))
+            trap = ROCKTRAP;
+        if ((t = maketrap(x, y, trap)) != 0) {
+            trap = t->ttyp;
+            tname = trapname(trap, TRUE);
+            pline("%s%s.", An(tname),
+                  (trap != MAGIC_PORTAL) ? "" : " to nowhere");
+        } else
+            pline("Creation of %s failed.", an(tname));
+        return (struct obj *) &cg.zeroobj;
+    }
+
+    /* furniture and terrain (use at your own risk; can clobber stairs
+       or place furniture on existing traps which shouldn't be allowed) */
+    lev = &levl[x][y];
+    p = eos(bp);
+    if (!BSTRCMPI(bp, p - 8, "fountain")) {
+        lev->typ = FOUNTAIN;
+        g.level.flags.nfountains++;
+        if (!strncmpi(bp, "magic ", 6))
+            lev->blessedftn = 1;
+        pline("A %sfountain.", lev->blessedftn ? "magic " : "");
+        madeterrain = TRUE;
+    } else if (!BSTRCMPI(bp, p - 6, "throne")) {
+        lev->typ = THRONE;
+        pline("A throne.");
+        madeterrain = TRUE;
+    } else if (!BSTRCMPI(bp, p - 4, "sink")) {
+        lev->typ = SINK;
+        g.level.flags.nsinks++;
+        pline("A sink.");
+        madeterrain = TRUE;
+
+    /* ("water" matches "potion of water" rather than terrain) */
+    } else if (!BSTRCMPI(bp, p - 4, "pool")
+               || !BSTRCMPI(bp, p - 4, "moat")) {
+        lev->typ = !BSTRCMPI(bp, p - 4, "pool") ? POOL : MOAT;
+        del_engr_at(x, y);
+        pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
+        /* Must manually make kelp! */
+        water_damage_chain(g.level.objects[x][y], TRUE);
+        madeterrain = TRUE;
+
+    /* also matches "molten lava" */
+    } else if (!BSTRCMPI(bp, p - 4, "lava")) {
+        lev->typ = LAVAPOOL;
+        del_engr_at(x, y);
+        pline("A pool of molten lava.");
+        if (!(Levitation || Flying))
+            pooleffects(FALSE);
+        madeterrain = TRUE;
+    } else if (!BSTRCMPI(bp, p - 5, "altar")) {
+        aligntyp al;
+
+        lev->typ = ALTAR;
+        if (!strncmpi(bp, "chaotic ", 8))
+            al = A_CHAOTIC;
+        else if (!strncmpi(bp, "neutral ", 8))
+            al = A_NEUTRAL;
+        else if (!strncmpi(bp, "lawful ", 7))
+            al = A_LAWFUL;
+        else if (!strncmpi(bp, "unaligned ", 10))
+            al = A_NONE;
+        else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
+            al = !rn2(6) ? A_NONE : (rn2((int) A_LAWFUL + 2) - 1);
+        lev->altarmask = Align2amask(al);
+        pline("%s altar.", An(align_str(al)));
+        madeterrain = TRUE;
+    } else if (!BSTRCMPI(bp, p - 5, "grave")
+               || !BSTRCMPI(bp, p - 9, "headstone")) {
+        make_grave(x, y, (char *) 0);
+        pline("%s.", IS_GRAVE(lev->typ) ? "A grave"
+                                        : "Can't place a grave here");
+        madeterrain = TRUE;
+    } else if (!BSTRCMPI(bp, p - 4, "tree")) {
+        lev->typ = TREE;
+        pline("A tree.");
+        block_point(x, y);
+        madeterrain = TRUE;
+    } else if (!BSTRCMPI(bp, p - 4, "bars")) {
+        lev->typ = IRONBARS;
+        pline("Iron bars.");
+        madeterrain = TRUE;
+    } else if (!BSTRCMPI(bp, p - 11, "secret door")) {
+        if (lev->typ == DOOR
+            || (IS_WALL(lev->typ) && lev->typ != DBWALL)) {
+            lev->typ = SDOOR;
+            lev->wall_info = 0;
+            /* lev->horizontal stays as-is */
+            /* no special handling for rogue level is necessary;
+               exposing a secret door there yields a doorless doorway */
+#if 0   /*
+         * Can't do this; secret doors want both doormask and
+         * wall_info but those both overload rm.flags which makes
+         * D_CLOSED conflict with WM_MASK.  However, converting
+         * secret door to regular door sets D_CLOSED iff D_LOCKED
+         * isn't specified so the alternate code suffices.
+         */
+            lev->doormask = locked ? D_LOCKED : D_CLOSED;
+#else
+            /* cvt_sdoor_to_door() will change D_NODOOR to D_CLOSED */
+            lev->doormask = locked ? D_LOCKED : D_NODOOR;
+#endif
+            if (trapped)
+                lev->doormask |= D_TRAPPED;
+            block_point(x, y);
+            pline("Secret door.");
+            madeterrain = TRUE;
+        } else {
+            pline("Secret door requires door or wall location.");
+            badterrain = TRUE;
+        }
+    } else if (!BSTRCMPI(bp, p - 15, "secret corridor")) {
+        if (lev->typ == CORR) {
+            lev->typ = SCORR;
+            block_point(x, y);
+            pline("Secret corridor.");
+            madeterrain = TRUE;
+        } else {
+            pline("Secret corridor requires corridor location.");
+            badterrain = TRUE;
+        }
+    }
+
+    if (madeterrain) {
+        feel_newsym(x, y); /* map the spot where the wish occurred */
+        /* hero started at <x,y> but might not be there anymore (create
+           lava, decline to die, and get teleported away to safety) */
+        if (u.uinwater && !is_pool(u.ux, u.uy)) {
+            u.uinwater = 0; /* leave the water */
+            docrt();
+            g.vision_full_recalc = 1;
+        } else if (u.utrap && u.utraptype == TT_LAVA
+                   && !is_lava(u.ux, u.uy)) {
+            reset_utrap(FALSE);
+        }
+    }
+    if (madeterrain || badterrain) {
+        /* cast 'const' away; caller won't modify this */
+        return (struct obj *) &cg.zeroobj;
+    }
+
+    return (struct obj *) 0;
+}
+
 /*
  * Return something wished for.  Specifying a null pointer for
  * the user request string results in a random object.  Otherwise,
@@ -3732,160 +3896,10 @@ struct obj *no_wish;
      */
  wiztrap:
     if (wizard && !g.program_state.wizkit_wishing) {
-        struct rm *lev;
-        boolean madeterrain = FALSE, badterrain = FALSE;
-        int trap, x = u.ux, y = u.uy;
-
-        for (trap = NO_TRAP + 1; trap < TRAPNUM; trap++) {
-            struct trap *t;
-            const char *tname;
-
-            tname = trapname(trap, TRUE);
-            if (strncmpi(tname, bp, strlen(tname)))
-                continue;
-            /* found it; avoid stupid mistakes */
-            if (is_hole(trap) && !Can_fall_thru(&u.uz))
-                trap = ROCKTRAP;
-            if ((t = maketrap(x, y, trap)) != 0) {
-                trap = t->ttyp;
-                tname = trapname(trap, TRUE);
-                pline("%s%s.", An(tname),
-                      (trap != MAGIC_PORTAL) ? "" : " to nowhere");
-            } else
-                pline("Creation of %s failed.", an(tname));
-            return (struct obj *) &cg.zeroobj;
-        }
-
-        /* furniture and terrain (use at your own risk; can clobber stairs
-           or place furniture on existing traps which shouldn't be allowed) */
-        lev = &levl[x][y];
-        p = eos(bp);
-        if (!BSTRCMPI(bp, p - 8, "fountain")) {
-            lev->typ = FOUNTAIN;
-            g.level.flags.nfountains++;
-            if (!strncmpi(bp, "magic ", 6))
-                lev->blessedftn = 1;
-            pline("A %sfountain.", lev->blessedftn ? "magic " : "");
-            madeterrain = TRUE;
-        } else if (!BSTRCMPI(bp, p - 6, "throne")) {
-            lev->typ = THRONE;
-            pline("A throne.");
-            madeterrain = TRUE;
-        } else if (!BSTRCMPI(bp, p - 4, "sink")) {
-            lev->typ = SINK;
-            g.level.flags.nsinks++;
-            pline("A sink.");
-            madeterrain = TRUE;
-
-        /* ("water" matches "potion of water" rather than terrain) */
-        } else if (!BSTRCMPI(bp, p - 4, "pool")
-                   || !BSTRCMPI(bp, p - 4, "moat")) {
-            lev->typ = !BSTRCMPI(bp, p - 4, "pool") ? POOL : MOAT;
-            del_engr_at(x, y);
-            pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
-            /* Must manually make kelp! */
-            water_damage_chain(g.level.objects[x][y], TRUE);
-            madeterrain = TRUE;
-
-        /* also matches "molten lava" */
-        } else if (!BSTRCMPI(bp, p - 4, "lava")) {
-            lev->typ = LAVAPOOL;
-            del_engr_at(x, y);
-            pline("A pool of molten lava.");
-            if (!(Levitation || Flying))
-                pooleffects(FALSE);
-            madeterrain = TRUE;
-        } else if (!BSTRCMPI(bp, p - 5, "altar")) {
-            aligntyp al;
-
-            lev->typ = ALTAR;
-            if (!strncmpi(bp, "chaotic ", 8))
-                al = A_CHAOTIC;
-            else if (!strncmpi(bp, "neutral ", 8))
-                al = A_NEUTRAL;
-            else if (!strncmpi(bp, "lawful ", 7))
-                al = A_LAWFUL;
-            else if (!strncmpi(bp, "unaligned ", 10))
-                al = A_NONE;
-            else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
-                al = !rn2(6) ? A_NONE : (rn2((int) A_LAWFUL + 2) - 1);
-            lev->altarmask = Align2amask(al);
-            pline("%s altar.", An(align_str(al)));
-            madeterrain = TRUE;
-        } else if (!BSTRCMPI(bp, p - 5, "grave")
-                   || !BSTRCMPI(bp, p - 9, "headstone")) {
-            make_grave(x, y, (char *) 0);
-            pline("%s.", IS_GRAVE(lev->typ) ? "A grave"
-                                            : "Can't place a grave here");
-            madeterrain = TRUE;
-        } else if (!BSTRCMPI(bp, p - 4, "tree")) {
-            lev->typ = TREE;
-            pline("A tree.");
-            block_point(x, y);
-            madeterrain = TRUE;
-        } else if (!BSTRCMPI(bp, p - 4, "bars")) {
-            lev->typ = IRONBARS;
-            pline("Iron bars.");
-            madeterrain = TRUE;
-        } else if (!BSTRCMPI(bp, p - 11, "secret door")) {
-            if (lev->typ == DOOR
-                || (IS_WALL(lev->typ) && lev->typ != DBWALL)) {
-                lev->typ = SDOOR;
-                lev->wall_info = 0;
-                /* lev->horizontal stays as-is */
-                /* no special handling for rogue level is necessary;
-                   exposing a secret door there yields a doorless doorway */
-#if 0       /*
-             * Can't do this; secret doors want both doormask and
-             * wall_info but those both overload rm.flags which makes
-             * D_CLOSED conflict with WM_MASK.  However, converting
-             * secret door to regular door sets D_CLOSED iff D_LOCKED
-             * isn't specified so the alternate code suffices.
-             */
-                lev->doormask = locked ? D_LOCKED : D_CLOSED;
-#else
-                /* cvt_sdoor_to_door() will change D_NODOOR to D_CLOSED */
-                lev->doormask = locked ? D_LOCKED : D_NODOOR;
-#endif
-                if (trapped)
-                    lev->doormask |= D_TRAPPED;
-                block_point(x, y);
-                pline("Secret door.");
-                madeterrain = TRUE;
-            } else {
-                pline("Secret door requires door or wall location.");
-                badterrain = TRUE;
-            }
-        } else if (!BSTRCMPI(bp, p - 15, "secret corridor")) {
-            if (lev->typ == CORR) {
-                lev->typ = SCORR;
-                block_point(x, y);
-                pline("Secret corridor.");
-                madeterrain = TRUE;
-            } else {
-                pline("Secret corridor requires corridor location.");
-                badterrain = TRUE;
-            }
-        }
-
-        if (madeterrain) {
-            feel_newsym(x, y); /* map the spot where the wish occurred */
-            /* hero started at <x,y> but might not be there anymore (create
-               lava, decline to die, and get teleported away to safety) */
-            if (u.uinwater && !is_pool(u.ux, u.uy)) {
-                u.uinwater = 0; /* leave the water */
-                docrt();
-                g.vision_full_recalc = 1;
-            } else if (u.utrap && u.utraptype == TT_LAVA
-                       && !is_lava(u.ux, u.uy)) {
-                reset_utrap(FALSE);
-            }
-        }
-        if (madeterrain || badterrain) {
-            /* cast 'const' away; caller won't modify this */
-            return (struct obj *) &cg.zeroobj;
-        }
-    } /* end of wizard mode traps and terrain */
+        /* [inline code moved to separate routine to unclutter readobjnam] */
+        if ((otmp = wizterrainwish(bp, p, locked, trapped)) != 0)
+            return otmp;
+    }
 
     if (!oclass && !typ) {
         if (!strncmpi(bp, "polearm", 7)) {