]> granicus.if.org Git - nethack/commitdiff
<Someone> wrote:
authornethack.allison <nethack.allison>
Sun, 2 Nov 2003 17:59:22 +0000 (17:59 +0000)
committernethack.allison <nethack.allison>
Sun, 2 Nov 2003 17:59:22 +0000 (17:59 +0000)
> The new ^V wizmode menu is nice, but it is rather misleading; most of
> the levels it lists are "you can't get there from here". Would it be
> possible either to make it only list levels that can be reached
> directly, or alternatively to allow you to reach the ones you
> ordinarily couldn't (maybe by forcefully changing u.uz.dnum to yoink
> you into the right branch, and even summarily issuing you with an
> Amulet if you ask to teleport to the endgame).[...]; being able to bamf
> quickly to Minetown from DL 1, for example, would be damn useful in > testing stuff.

Allow fairly free roaming of the dungeon via the wizard mode teleport menu.

include/extern.h
src/cmd.c
src/dungeon.c
src/teleport.c

index 2728b2f4e6c94412f4e3344aec585a11f11593e7..883aa35674f6a74c724f22428977a7677bb6d2c3 100644 (file)
@@ -507,7 +507,7 @@ E boolean FDECL(Invocation_lev, (d_level *));
 E xchar NDECL(level_difficulty);
 E schar FDECL(lev_by_name, (const char *));
 #ifdef WIZARD
-E schar FDECL(print_dungeon, (BOOLEAN_P));
+E schar FDECL(print_dungeon, (BOOLEAN_P,schar *,xchar *));
 #endif
 
 /* ### eat.c ### */
index 41f08652b48d4c9887d60febad1f603ff55706c3..98cab5587d53c69e3f3bcf64bed5dd2339fc3371 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -549,7 +549,7 @@ wiz_genesis()
 STATIC_PTR int
 wiz_where()
 {
-       if (wizard) (void) print_dungeon(FALSE);
+       if (wizard) (void) print_dungeon(FALSE, (schar *)0, (xchar *)0);
        else        pline("Unavailable command '^O'.");
        return 0;
 }
index 81ae23b119259b19e9abdbc48b64ab6650b7cb2a..a4c93d9ce3715d42133d67cc97732c79940e2371 100644 (file)
@@ -27,6 +27,14 @@ int n_dgns;                          /* number of dungeons (used here,  */
                                        /*   and mklev.c)                  */
 static branch *branches = (branch *) 0;        /* dungeon branch list             */
 
+struct lchoice {
+       int idx;
+       schar lev[MAXLINFO];
+       schar playerlev[MAXLINFO];
+       xchar dgn[MAXLINFO];
+       char menuletter;
+};
+
 static void FDECL(Fread, (genericptr_t, int, int, dlb *));
 STATIC_DCL xchar FDECL(dname_to_dnum, (const char *));
 STATIC_DCL int FDECL(find_branch, (const char *, struct proto_dungeon *));
@@ -42,7 +50,7 @@ STATIC_DCL xchar FDECL(pick_level, (boolean *, int));
 STATIC_DCL boolean FDECL(place_level, (int, struct proto_dungeon *));
 #ifdef WIZARD
 STATIC_DCL const char *FDECL(br_string, (int));
-STATIC_DCL void FDECL(print_branch, (winid, int, int, int, BOOLEAN_P, char *));
+STATIC_DCL void FDECL(print_branch, (winid, int, int, int, BOOLEAN_P, struct lchoice *));
 #endif
 
 #ifdef DEBUG
@@ -1515,13 +1523,13 @@ br_string(type)
 
 /* Print all child branches between the lower and upper bounds. */
 STATIC_OVL void
-print_branch(win, dnum, lower_bound, upper_bound, bymenu, menuletter)
+print_branch(win, dnum, lower_bound, upper_bound, bymenu, lchoices)
     winid win;
     int   dnum;
     int   lower_bound;
     int   upper_bound;
     boolean bymenu;
-    char *menuletter;
+    struct lchoice *lchoices;
 {
     branch *br;
     char buf[BUFSZ];
@@ -1536,14 +1544,16 @@ print_branch(win, dnum, lower_bound, upper_bound, bymenu, menuletter)
                    dungeons[br->end2.dnum].dname,
                    depth(&br->end1));
            if (bymenu) {
-               schar lev = depth(&br->end1);
+               lchoices->lev[lchoices->idx] = br->end1.dlevel;
+               lchoices->dgn[lchoices->idx] = br->end1.dnum;
+               lchoices->playerlev[lchoices->idx] = depth(&br->end1);
                any.a_void = 0;
-               if (lev >= 0) any.a_schar = lev + 1;
-               else any.a_schar = lev;
-               add_menu(win, NO_GLYPH, &any, *menuletter,
+               any.a_int = lchoices->idx + 1;
+               add_menu(win, NO_GLYPH, &any, lchoices->menuletter,
                                0, ATR_NONE, buf, MENU_UNSELECTED);
-               if (*menuletter == 'z') *menuletter = 'A';
-               else *menuletter += 1;
+               if (lchoices->menuletter == 'z') lchoices->menuletter = 'A';
+               else lchoices->menuletter++;
+               lchoices->idx++;
            } else
                putstr(win, 0, buf);
        }
@@ -1551,9 +1561,11 @@ print_branch(win, dnum, lower_bound, upper_bound, bymenu, menuletter)
 }
 
 /* Print available dungeon information. */
-schar
-print_dungeon(bymenu)
+boolean
+print_dungeon(bymenu, rlev, rdgn)
 boolean bymenu;
+schar *rlev;
+xchar *rdgn;
 {
     int     i, last_level, nlev;
     char    buf[BUFSZ];
@@ -1561,13 +1573,14 @@ boolean bymenu;
     s_level *slev;
     dungeon *dptr;
     branch  *br;
-
     anything any;
-    char mlet;
+    struct lchoice lchoices;
+
     winid   win = create_nhwindow(NHW_MENU);
     if (bymenu) {
        start_menu(win);
-       mlet = 'a';
+       lchoices.idx = 0;
+       lchoices.menuletter = 'a';
     }
 
     for (i = 0, dptr = dungeons; i < n_dgns; i++, dptr++) {
@@ -1600,37 +1613,42 @@ boolean bymenu;
            if (slev->dlevel.dnum != i) continue;
 
            /* print any branches before this level */
-           print_branch(win, i, last_level, slev->dlevel.dlevel, bymenu, &mlet);
+           print_branch(win, i, last_level, slev->dlevel.dlevel, bymenu, &lchoices);
 
            Sprintf(buf, "   %s: %d", slev->proto, depth(&slev->dlevel));
            if (Is_stronghold(&slev->dlevel))
                Sprintf(eos(buf), " (tune %s)", tune);
            if (bymenu) {
-               schar lev = depth(&slev->dlevel);
+               /* If other floating branches are added, this will need to change */
+               if (i != knox_level.dnum) {
+                       lchoices.lev[lchoices.idx] = slev->dlevel.dlevel;
+                       lchoices.dgn[lchoices.idx] = i;
+               } else {
+                       lchoices.lev[lchoices.idx] = depth(&slev->dlevel);
+                       lchoices.dgn[lchoices.idx] = 0;
+               }
+               lchoices.playerlev[lchoices.idx] = depth(&slev->dlevel);
                any.a_void = 0;
-               if (lev >= 0) any.a_schar = lev + 1;
-               else any.a_schar = lev;
-               add_menu(win, NO_GLYPH, &any, mlet, 0, ATR_NONE, buf, MENU_UNSELECTED);
-               if (mlet == 'z') mlet = 'A';
-               else mlet++;
+               any.a_int = lchoices.idx + 1;
+               add_menu(win, NO_GLYPH, &any, lchoices.menuletter,
+                               0, ATR_NONE, buf, MENU_UNSELECTED);
+               if (lchoices.menuletter == 'z') lchoices.menuletter = 'A';
+               else lchoices.menuletter++;
+               lchoices.idx++;
            } else
                putstr(win, 0, buf);
 
            last_level = slev->dlevel.dlevel;
        }
        /* print branches after the last special level */
-       print_branch(win, i, last_level, MAXLEVEL, bymenu, &mlet);
+       print_branch(win, i, last_level, MAXLEVEL, bymenu, &lchoices);
     }
 
     /* Print out floating branches (if any). */
     for (first = TRUE, br = branches; br; br = br->next) {
        if (br->end1.dnum == n_dgns) {
            if (first) {
-               if (bymenu) {
-                   any.a_void = 0;
-                   add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
-                               "Floating branches", MENU_UNSELECTED);
-               } else {
+               if (!bymenu) {
                    putstr(win, 0, "");
                    putstr(win, 0, "Floating branches");
                }
@@ -1638,32 +1656,28 @@ boolean bymenu;
            }
            Sprintf(buf, "   %s to %s",
                        br_string(br->type), dungeons[br->end2.dnum].dname);
-           if (bymenu) {
-               schar lev = lev_by_name(dungeons[br->end2.dnum].dname);
-               any.a_void = 0;
-               if (lev >= 0) any.a_schar = lev + 1;
-               else any.a_schar = lev;
-               add_menu(win, NO_GLYPH, &any, mlet, 0, ATR_NONE, buf, MENU_UNSELECTED);
-               if (mlet == 'z') mlet = 'A';
-               else mlet++;
-           } else
+           if (!bymenu)
                putstr(win, 0, buf);
        }
     }
     if (bymenu) {
        int n;
        menu_item *selected;
-       schar lev = 0;
+       int idx;
 
        end_menu(win, "Level teleport to where:");
        n = select_menu(win, PICK_ONE, &selected);
        destroy_nhwindow(win);
        if (n > 0) {
-               lev = selected[0].item.a_schar;
-               if (lev > 0) lev--;
+               idx = selected[0].item.a_int - 1;
                free((genericptr_t)selected);
+               if (rlev && rdgn) {
+                       *rlev = lchoices.lev[idx];
+                       *rdgn = lchoices.dgn[idx];
+                       return lchoices.playerlev[idx];
+               }
        }
-       return lev;
+       return 0;
     }
 
     /* I hate searching for the invocation pos while debugging. -dean */
index 04da50f3d0e9bd3130fb3aea73bc4a022c62f684..6627eebe63a4e61ee2b6062bff5c351267950fb9 100644 (file)
@@ -567,6 +567,7 @@ level_tele()
        d_level newlevel;
        const char *escape_by_flying = 0;       /* when surviving dest of -N */
        char buf[BUFSZ];
+       boolean force_dest = FALSE;
 
        if ((u.uhave.amulet || In_endgame(&u.uz) || In_sokoban(&u.uz))
 #ifdef WIZARD
@@ -608,7 +609,29 @@ level_tele()
                }
 #ifdef WIZARD
                if (wizard && !strcmp(buf,"?")) {
-                   newlev = print_dungeon(TRUE);
+                   schar destlev = 0;
+                   xchar destdnum = 0;
+                   if ((newlev = (int)print_dungeon(TRUE, &destlev, &destdnum))) {
+                       char buf[BUFSZ];
+                       newlevel.dnum = destdnum;
+                       newlevel.dlevel = destlev;
+                       if (In_endgame(&newlevel) && !In_endgame(&u.uz)) {
+                               Sprintf(buf,
+                                   "Destination is earth level");
+                               if (!u.uhave.amulet) {
+                                       struct obj *obj;
+                                       obj = mksobj(AMULET_OF_YENDOR,
+                                                       TRUE, FALSE);
+                                       if (obj) {
+                                               obj = addinv(obj);
+                                               Strcat(buf, " with the amulet");
+                                       }
+                               }
+                               assign_level(&newlevel, &earth_level);
+                               pline("%s.", buf);
+                       }
+                       force_dest = TRUE;
+                   } else return;
                } else
 #endif
                if ((newlev = lev_by_name(buf)) == 0) newlev = atoi(buf);
@@ -686,7 +709,7 @@ level_tele()
 
        killer.name[0] = 0;             /* still alive, so far... */
 
-       if (newlev < 0) {
+       if (newlev < 0 && !force_dest) {
                if (*u.ushops0) {
                    /* take unpaid inventory items off of shop bills */
                    in_mklev = TRUE;    /* suppress map update */
@@ -748,6 +771,9 @@ level_tele()
        } else if (u.uz.dnum == medusa_level.dnum &&
            newlev >= dungeons[u.uz.dnum].depth_start +
                                                dunlevs_in_dungeon(&u.uz)) {
+#ifdef WIZARD
+           if (!(wizard && force_dest))
+#endif
            find_hell(&newlevel);
        } else {
            /* if invocation did not yet occur, teleporting into
@@ -770,6 +796,9 @@ level_tele()
             * we must translate newlev to a number relative to the
             * current dungeon.
             */
+#ifdef WIZARD
+           if (!(wizard && force_dest))
+#endif
            get_level(&newlevel, newlev);
        }
        schedule_goto(&newlevel, FALSE, FALSE, 0, (char *)0, (char *)0);