diff --git a/include/extern.h b/include/extern.h index 78120c82a..09d2d6b3a 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1431998729 2015/05/19 01:25:29 $ $NHDT-Branch: master $:$NHDT-Revision: 1.492 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1432249760 2015/05/21 23:09:20 $ $NHDT-Branch: master $:$NHDT-Revision: 1.493 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -260,7 +260,7 @@ E void FDECL(find_trap, (struct trap *)); E int FDECL(dosearch0, (int)); E int NDECL(dosearch); E void NDECL(sokoban_detect); -E void FDECL(reveal_terrain, (BOOLEAN_P)); +E void FDECL(reveal_terrain, (int,int)); /* ### dig.c ### */ diff --git a/src/cmd.c b/src/cmd.c index e90f97bad..b32e4f7d7 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1431192758 2015/05/09 17:32:38 $ $NHDT-Branch: master $:$NHDT-Revision: 1.190 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1432249761 2015/05/21 23:09:21 $ $NHDT-Branch: master $:$NHDT-Revision: 1.191 $ */ /* NetHack 3.6 cmd.c $Date: 2013/03/16 01:44:28 $ $Revision: 1.162 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1109,76 +1109,78 @@ wiz_rumor_check(VOID_ARGS) return 0; } -/* #terrain command */ +/* #terrain command -- show known map, inspired by crawl's '|' command */ STATIC_PTR int doterrain(VOID_ARGS) { - int which = 1; /* show known map, ala crawl's '|' command */ + winid men; + menu_item *sel; + anything any; + int n; + int which; + /* + * normal play: choose between known map without mons, obj, and traps + * (to see underlying terrain only), or + * known map without mons and objs (to see traps under mons and objs), or + * known map without mons (to see objects under monsters); + * explore mode: normal choices plus full map (w/o mons, objs, traps); + * wizard mode: normal and explore choices plus + * a dump of the internal levl[][].typ codes w/ level flags, or + * a legend for the levl[][].typ codes dump + */ + men = create_nhwindow(NHW_MENU); + any = zeroany; + any.a_int = 1; + add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE, + "known map without monsters, objects, and traps", + MENU_SELECTED); + any.a_int = 2; + add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE, + "known map without monsters and objects", + MENU_UNSELECTED); + any.a_int = 3; + add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE, + "known map without monsters", + MENU_UNSELECTED); if (discover || wizard) { - /* explore mode #terrain: choose between known map and full map; - wizard mode #terrain: choose between known map, full map, - a dump of the internal levl[][].typ codes w/ level flags, - and a legend for the levl[][].typ codes */ - winid men; - menu_item *sel; - anything any; - int n; - - men = create_nhwindow(NHW_MENU); - any = zeroany; - any.a_int = 1; - add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE, - "known map without monsters, objects, and traps", - MENU_SELECTED); - any.a_int = 2; + any.a_int = 4; add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE, "full map without monsters, objects, and traps", MENU_UNSELECTED); if (wizard) { - any.a_int = 3; + any.a_int = 5; add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE, "internal levl[][].typ codes in base-36", MENU_UNSELECTED); - any.a_int = 4; + any.a_int = 6; add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE, - "legend of base-36 levl[][].typ codes", MENU_UNSELECTED); + "legend of base-36 levl[][].typ codes", + MENU_UNSELECTED); } - end_menu(men, "View which?"); + } + end_menu(men, "View which?"); - n = select_menu(men, PICK_ONE, &sel); - destroy_nhwindow(men); - /* - * n < 0: player used ESC to cancel; - * n == 0: preselected entry was explicitly chosen and got toggled - * off; - * n == 1: preselected entry was implicitly chosen via - * |; - * n == 2: another entry was explicitly chosen, so skip preselected - * one - */ - which = (n < 0) ? -1 : (n == 0) ? 1 : sel[0].item.a_int; - if (n > 1 && which == 1) - which = sel[1].item.a_int; - if (n > 0) - free((genericptr_t) sel); - } /* discover || wizard */ + n = select_menu(men, PICK_ONE, &sel); + destroy_nhwindow(men); + /* + * n < 0: player used ESC to cancel; + * n == 0: preselected entry was explicitly chosen and got toggled off; + * n == 1: preselected entry was implicitly chosen via |; + * n == 2: another entry was explicitly chosen, so skip preselected one. + */ + which = (n < 0) ? -1 : (n == 0) ? 1 : sel[0].item.a_int; + if (n > 1 && which == 1) which = sel[1].item.a_int; + if (n > 0) free((genericptr_t)sel); switch (which) { - case 1: - reveal_terrain(FALSE); - break; /* known map */ - case 2: - reveal_terrain(TRUE); - break; /* full map */ - case 3: - wiz_map_levltyp(); - break; /* map internals */ - case 4: - wiz_levltyp_legend(); - break; /* internal details */ - default: - break; + case 1: reveal_terrain(0, 0); break; /* known map */ + case 2: reveal_terrain(0, 1); break; /* known map with traps */ + case 3: reveal_terrain(0, 1|2); break; /* known map w/ traps & objs */ + case 4: reveal_terrain(1, 0); break; /* full map */ + case 5: wiz_map_levltyp(); break; /* map internals */ + case 6: wiz_levltyp_legend(); break; /* internal details */ + default: break; } return 0; /* no time elapses */ } diff --git a/src/detect.c b/src/detect.c index c7d434341..716f2724f 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 detect.c $NHDT-Date: 1431472031 2015/05/12 23:07:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.56 $ */ +/* NetHack 3.6 detect.c $NHDT-Date: 1432252377 2015/05/21 23:52:57 $ $NHDT-Branch: master $:$NHDT-Revision: 1.57 $ */ /* NetHack 3.6 detect.c $Date: 2012/04/16 02:05:40 $ $Revision: 1.47 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1469,50 +1469,113 @@ sokoban_detect() /* idea from crawl; show known portion of map without any monsters, objects, or traps occluding the view of the underlying terrain */ void -reveal_terrain(full) -boolean full; /* wizard|explore modes allow player to request full map */ +reveal_terrain(full, which_subset) +int full; /* wizard|explore modes allow player to request full map */ +int which_subset; /* when not full, whether to suppress objs and/or traps */ { - int x, y, glyph, S_stone_glyph; - uchar seenv; - unsigned save_swallowed; - struct monst *mtmp; - if ((Hallucination || Stunned || Confusion) && !full) { You("are too disoriented for this."); } else { + int x, y, glyph, levl_glyph, default_glyph; + uchar seenv; + unsigned save_swallowed; + struct monst *mtmp; + struct trap *t; + char buf[BUFSZ]; + boolean keep_traps = (which_subset & 1) !=0, + keep_objs = (which_subset & 2) != 0, + keep_mons = (which_subset & 4) != 0; /* actually always 0 */ + save_swallowed = u.uswallow; iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied; u.uinwater = u.uburied = 0; u.uswallow = 0; - S_stone_glyph = cmap_to_glyph(S_stone); - /* rewrite the map, displaying map background for seen spots - (all spots seen if 'full') and stone everywhere else */ + default_glyph = cmap_to_glyph(level.flags.arboreal ? S_tree : S_stone); + /* for 'full', show the actual terrain for the entire level, + otherwise what the hero remembers for seen locations with + monsters, objects, and/or traps removed as caller dictates */ for (x = 1; x < COLNO; x++) for (y = 0; y < ROWNO; y++) { - seenv = levl[x][y].seenv; + seenv = (full || level.flags.hero_memory) + ? levl[x][y].seenv : cansee(x, y) ? SVALL : 0; if (full) { levl[x][y].seenv = SVALL; glyph = back_to_glyph(x, y); levl[x][y].seenv = seenv; } else { - if (!level.flags.hero_memory && !cansee(x, y)) - seenv = 0; - glyph = seenv ? back_to_glyph(x, y) : S_stone_glyph; - /* need to show mimic-as-furniture so that #terrain can't - be used to spot mimics, but this is only approximate; - mimic might have moved and hid here after the player - last saw this spot as some other type of terrain */ - if (seenv && (mtmp = m_at(x, y)) != 0 - && mtmp->m_ap_type == M_AP_FURNITURE) - glyph = cmap_to_glyph(mtmp->mappearance); + levl_glyph = level.flags.hero_memory ? levl[x][y].glyph + : seenv ? back_to_glyph(x, y) : default_glyph; + /* glyph_at() returns the displayed glyph, which might + be a monster. levl[][].glyph contains the remembered + glyph, which will never be a monster (unless it is + the invisible monster glyph, which is handled like + an object, replacing any object or trap at its spot) */ + glyph = !save_swallowed ? glyph_at(x, y) : levl_glyph; + if (keep_mons && x == u.ux && y == u.uy && save_swallowed) + glyph = mon_to_glyph(u.ustuck); + else if (((glyph_is_monster(glyph) + || glyph_is_warning(glyph)) && !keep_mons) + || glyph_is_swallow(glyph)) + glyph = levl_glyph; + if (((glyph_is_object(glyph) && !keep_objs) + || glyph_is_invisible(glyph)) + && keep_traps && !covers_traps(x, y)) { + if ((t = t_at(x, y)) != 0 && t->tseen) + glyph = trap_to_glyph(t); + } + if ((glyph_is_object(glyph) && !keep_objs) + || (glyph_is_trap(glyph) && !keep_traps) + || glyph_is_invisible(glyph)) { + if (!seenv) { + glyph = default_glyph; + } else if (lastseentyp[x][y] == levl[x][y].typ) { + glyph = back_to_glyph(x, y); + } else { + /* look for a mimic here posing as furniture; + if we don't find one, we'll have to fake it */ + if ((mtmp = m_at(x, y)) != 0 + && mtmp->m_ap_type == M_AP_FURNITURE) { + glyph = cmap_to_glyph(mtmp->mappearance); + } else { + /* we have a topology type but we want a + screen symbol in order to derive a glyph; + some screen symbols need the flags field + of levl[][] in addition to the type + (to disambiguate STAIRS to S_upstair or + S_dnstair, for example; current flags + might not be intended for remembered + type, but we've got no other choice) */ + schar save_typ = levl[x][y].typ; + + levl[x][y].typ = lastseentyp[x][y]; + glyph = back_to_glyph(x, y); + levl[x][y].typ = save_typ; + } + } + } } show_glyph(x, y, glyph); } /* [TODO: highlight hero's location somehow] */ u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied; - u.uswallow = save_swallowed; + if (save_swallowed) u.uswallow = 1; flush_screen(1); - pline("Showing underlying terrain only..."); + if (full) { + Strcpy(buf, "underlying terrain"); + } else { + Strcpy(buf, "known terrain"); + if (keep_traps) + Sprintf(eos(buf), "%s traps", + (keep_objs || keep_mons) ? "," : " and"); + if (keep_objs) + Sprintf(eos(buf), "%s%s objects", + (keep_traps || keep_mons) ? "," : "", + keep_mons ? "" : " and"); + if (keep_mons) + Sprintf(eos(buf), "%s and monsters", + (keep_traps || keep_objs) ? "," : ""); + } + pline("Showing %s only...", buf); display_nhwindow(WIN_MAP, TRUE); /* give "--More--" prompt */ docrt(); /* redraw the screen, restoring regular map */ if (Underwater)