From 168572fd0d4aee9e157420b8beabf8bb5c3d1ef8 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 21 May 2015 16:53:46 -0700 Subject: [PATCH] #terrain update Make the post-3.4.3 '#terrain' command be more versatile by allowing the player to choose between floor-only, floor+traps, and floor+traps+objects so that it is possible to view known traps covered by objects or monsters and remembered objects covered by monsters. The extra explore mode and wizard mode choices aren't affected. --- include/extern.h | 4 +- src/cmd.c | 110 +++++++++++++++++++++++----------------------- src/detect.c | 111 +++++++++++++++++++++++++++++++++++++---------- 3 files changed, 145 insertions(+), 80 deletions(-) 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)