From: nethack.allison Date: Sun, 2 Nov 2003 17:59:22 +0000 (+0000) Subject: wrote: X-Git-Tag: MOVE2GIT~1613 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e3462e093e810cd4be32bcd499c8d458518a737a;p=nethack wrote: > 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. --- diff --git a/include/extern.h b/include/extern.h index 2728b2f4e..883aa3567 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 ### */ diff --git a/src/cmd.c b/src/cmd.c index 41f08652b..98cab5587 100644 --- 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; } diff --git a/src/dungeon.c b/src/dungeon.c index 81ae23b11..a4c93d9ce 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -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 */ diff --git a/src/teleport.c b/src/teleport.c index 04da50f3d..6627eebe6 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -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);