extern boolean known; /* from read.c */
+STATIC_DCL boolean NDECL(unconstrain_map);
+STATIC_DCL void NDECL(reconstrain_map);
+STATIC_DCL void FDECL(browse_map, (int, const char *));
+STATIC_DCL void FDECL(map_monst, (struct monst *, BOOLEAN_P));
STATIC_DCL void FDECL(do_dknown_of, (struct obj *));
STATIC_DCL boolean FDECL(check_map_spot, (int, int, CHAR_P, unsigned));
STATIC_DCL boolean FDECL(clear_stale_map, (CHAR_P, unsigned));
STATIC_PTR void FDECL(openone, (int, int, genericptr_t));
STATIC_DCL int FDECL(mfind0, (struct monst *, BOOLEAN_P));
+/* bring hero out from underwater or underground or being engulfed;
+ return True iff any change occurred */
+STATIC_OVL boolean
+unconstrain_map()
+{
+ boolean res = u.uinwater || u.uburied || u.uswallow;
+
+ /* bring Underwater, buried, or swallowed hero to normal map */
+ iflags.save_uinwater = u.uinwater, u.uinwater = 0;
+ iflags.save_uburied = u.uburied, u.uburied = 0;
+ iflags.save_uswallow = u.uswallow, u.uswallow = 0;
+
+ return res;
+}
+
+/* put hero back underwater or underground or engulfed */
+STATIC_OVL void
+reconstrain_map()
+{
+ u.uinwater = iflags.save_uinwater, iflags.save_uinwater = 0;
+ u.uburied = iflags.save_uburied, iflags.save_uburied = 0;
+ u.uswallow = iflags.save_uswallow, iflags.save_uswallow = 0;
+}
+
+/* use getpos()'s 'autodescribe' to view whatever is currently shown on map */
+STATIC_DCL void
+browse_map(ter_typ, ter_explain)
+int ter_typ;
+const char *ter_explain;
+{
+ coord dummy_pos; /* don't care whether player actually picks a spot */
+
+ dummy_pos.x = u.ux, dummy_pos.y = u.uy; /* starting spot for getpos() */
+ iflags.autodescribe = TRUE;
+ iflags.terrainmode = ter_typ;
+ getpos(&dummy_pos, FALSE, ter_explain);
+ iflags.terrainmode = 0;
+ /* leave iflags.autodescribe 'on' even if previously 'off' */
+}
+
+/* extracted from monster_detection() so can be shared by do_vicinity_map() */
+STATIC_DCL void
+map_monst(mtmp, showtail)
+struct monst *mtmp;
+boolean showtail;
+{
+ if (def_monsyms[(int) mtmp->data->mlet].sym == ' ')
+ show_glyph(mtmp->mx, mtmp->my, detected_mon_to_glyph(mtmp));
+ else
+ show_glyph(mtmp->mx, mtmp->my,
+ mtmp->mtame ? pet_to_glyph(mtmp) : mon_to_glyph(mtmp));
+
+ if (showtail && mtmp->data == &mons[PM_LONG_WORM])
+ detect_wsegs(mtmp, 0);
+}
+
/* this is checking whether a trap symbol represents a trapped chest,
not whether a trapped chest is actually present */
boolean
int ttyp;
int x, y;
{
+ struct monst *mtmp;
+ struct obj *otmp;
+
if (!glyph_is_trap(glyph_at(x, y)))
return FALSE;
if (ttyp != BEAR_TRAP || (Hallucination && rn2(20)))
return FALSE;
- /* presence of any trappable container will do */
- return (sobj_at(CHEST, x, y) || sobj_at(LARGE_BOX, x, y)) ? TRUE : FALSE;
+
+ /*
+ * TODO? We should check containers recursively like the trap
+ * detecting routine does. Chests and large boxes do not nest in
+ * themselves or each other, but could be contained inside statues.
+ *
+ * For farlook, we should also check for buried containers, but
+ * for '^' command to examine adjacent trap glyph, we shouldn't.
+ */
+
+ /* on map, presence of any trappable container will do */
+ if (sobj_at(CHEST, x, y) || sobj_at(LARGE_BOX, x, y))
+ return TRUE;
+ /* in inventory, we need to find one which is actually trapped */
+ if (x == u.ux && y == u.uy) {
+ for (otmp = invent; otmp; otmp = otmp->nobj)
+ if (Is_box(otmp) && otmp->otrapped)
+ return TRUE;
+ if (u.usteed) { /* steed isn't on map so won't be found by m_at() */
+ for (otmp = u.usteed->minvent; otmp; otmp = otmp->nobj)
+ if (Is_box(otmp) && otmp->otrapped)
+ return TRUE;
+ }
+ }
+ if ((mtmp = m_at(x, y)) != 0)
+ for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
+ if (Is_box(otmp) && otmp->otrapped)
+ return TRUE;
+ return FALSE;
}
/* this is checking whether a trap symbol represents a trapped door,
{
register struct obj *obj;
register struct monst *mtmp;
- struct obj *temp;
- boolean stale;
+ struct obj gold, *temp = 0;
+ boolean stale, ugold = FALSE, steedgold = FALSE;
+ int ter_typ = TER_DETECT | TER_OBJ;
- known = stale =
- clear_stale_map(COIN_CLASS, (unsigned) (sobj->blessed ? GOLD : 0));
+ known = stale = clear_stale_map(COIN_CLASS,
+ (unsigned) (sobj->blessed ? GOLD : 0));
/* look for gold carried by monsters (might be in a container) */
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp))
continue; /* probably not needed in this case but... */
if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
- known = TRUE;
- goto outgoldmap; /* skip further searching */
+ if (mtmp == u.usteed) {
+ steedgold = TRUE;
+ } else {
+ known = TRUE;
+ goto outgoldmap; /* skip further searching */
+ }
} else {
for (obj = mtmp->minvent; obj; obj = obj->nobj)
- if (sobj->blessed && o_material(obj, GOLD)) {
- known = TRUE;
- goto outgoldmap;
- } else if (o_in(obj, COIN_CLASS)) {
- known = TRUE;
- goto outgoldmap; /* skip further searching */
+ if ((sobj->blessed && o_material(obj, GOLD))
+ || o_in(obj, COIN_CLASS)) {
+ if (mtmp == u.usteed) {
+ steedgold = TRUE;
+ } else {
+ known = TRUE;
+ goto outgoldmap; /* skip further searching */
+ }
}
}
}
if (sobj) {
char buf[BUFSZ];
- if (youmonst.data == &mons[PM_GOLD_GOLEM]) {
+ if (youmonst.data == &mons[PM_GOLD_GOLEM])
Sprintf(buf, "You feel like a million %s!", currency(2L));
- } else if (hidden_gold() || money_cnt(invent))
+ else if (money_cnt(invent) || hidden_gold())
Strcpy(buf,
"You feel worried about your future financial situation.");
+ else if (steedgold)
+ Sprintf(buf, "You feel interested in %s financial situation.",
+ s_suffix(x_monnam(u.usteed,
+ u.usteed->mtame ? ARTICLE_YOUR
+ : ARTICLE_THE,
+ (char *) 0,
+ SUPPRESS_SADDLE, FALSE)));
else
Strcpy(buf, "You feel materially poor.");
+
strange_feeling(sobj, buf);
}
return 1;
outgoldmap:
cls();
- iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
- u.uinwater = u.uburied = 0;
+ (void) unconstrain_map();
/* Discover gold locations. */
for (obj = fobj; obj; obj = obj->nobj) {
if (sobj->blessed && (temp = o_material(obj, GOLD)) != 0) {
}
map_object(temp, 1);
}
+ if (temp && temp->ox == u.ux && temp->oy == u.uy)
+ ugold = TRUE;
}
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp))
continue; /* probably overkill here */
+ temp = 0;
if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
- struct obj gold;
-
gold = zeroobj; /* ensure oextra is cleared too */
gold.otyp = GOLD_PIECE;
gold.quan = (long) rnd(10); /* usually more than 1 */
gold.ox = mtmp->mx;
gold.oy = mtmp->my;
map_object(&gold, 1);
+ temp = &gold;
} else {
for (obj = mtmp->minvent; obj; obj = obj->nobj)
if (sobj->blessed && (temp = o_material(obj, GOLD)) != 0) {
break;
}
}
+ if (temp && temp->ox == u.ux && temp->oy == u.uy)
+ ugold = TRUE;
+ }
+ if (!ugold) {
+ newsym(u.ux, u.uy);
+ ter_typ |= TER_MON; /* so autodescribe will recognize hero */
}
- newsym(u.ux, u.uy);
- u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
- iflags.save_uinwater = iflags.save_uburied = 0;
You_feel("very greedy, and sense gold!");
exercise(A_WIS, TRUE);
- display_nhwindow(WIN_MAP, TRUE);
+
+ browse_map(ter_typ, "gold");
+
+ reconstrain_map();
docrt();
if (Underwater)
under_water(2);
const char *what = confused ? something : "food";
stale = clear_stale_map(oclass, 0);
+ if (u.usteed) /* some situations leave steed with stale coordinates */
+ u.usteed->mx = u.ux, u.usteed->my = u.uy;
for (obj = fobj; obj; obj = obj->nobj)
if (o_in(obj, oclass)) {
else
ct++;
}
- for (mtmp = fmon; mtmp && !ct; mtmp = mtmp->nmon) {
- /* no DEADMONSTER(mtmp) check needed since dmons never have inventory
- */
+ for (mtmp = fmon; mtmp && (!ct || !ctu); mtmp = mtmp->nmon) {
+ /* no DEADMONSTER(mtmp) check needed -- dmons never have inventory */
for (obj = mtmp->minvent; obj; obj = obj->nobj)
if (o_in(obj, oclass)) {
- ct++;
+ if (mtmp->mx == u.ux && mtmp->my == u.uy)
+ ctu++; /* steed or an engulfer with inventory */
+ else
+ ct++;
break;
}
}
}
} else if (sobj) {
char buf[BUFSZ];
+
Sprintf(buf, "Your %s twitches%s.", body_part(NOSE),
(sobj->blessed && !u.uedibility)
? " then starts to tingle"
}
} else {
struct obj *temp;
+ int ter_typ = TER_DETECT | TER_OBJ;
+
known = TRUE;
cls();
- iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
- u.uinwater = u.uburied = 0;
+ (void) unconstrain_map();
for (obj = fobj; obj; obj = obj->nobj)
if ((temp = o_in(obj, oclass)) != 0) {
if (temp != obj) {
map_object(temp, 1);
}
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
- /* no DEADMONSTER(mtmp) check needed since dmons never have
- * inventory */
+ /* no DEADMONSTER() check needed -- dmons never have inventory */
for (obj = mtmp->minvent; obj; obj = obj->nobj)
if ((temp = o_in(obj, oclass)) != 0) {
temp->ox = mtmp->mx;
map_object(temp, 1);
break; /* skip rest of this monster's inventory */
}
- newsym(u.ux, u.uy);
- u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
- iflags.save_uinwater = iflags.save_uburied = 0;
+ if (!ctu) {
+ newsym(u.ux, u.uy);
+ ter_typ |= TER_MON; /* for autodescribe of self */
+ }
if (sobj) {
if (sobj->blessed) {
Your("%s %s to tingle and you smell %s.", body_part(NOSE),
Your("%s tingles and you smell %s.", body_part(NOSE), what);
} else
You("sense %s.", what);
- display_nhwindow(WIN_MAP, TRUE);
exercise(A_WIS, TRUE);
+
+ browse_map(ter_typ, "food");
+
+ reconstrain_map();
docrt();
if (Underwater)
under_water(2);
int ct = 0, ctu = 0;
register struct obj *obj, *otmp = (struct obj *) 0;
register struct monst *mtmp;
- int sym, boulder = 0;
+ int sym, boulder = 0, ter_typ = TER_DETECT | TER_OBJ;
if (class < 0 || class >= MAXOCLASSES) {
impossible("object_detect: illegal class %d", class);
do_dknown_of(obj);
}
+ if (u.usteed)
+ u.usteed->mx = u.ux, u.usteed->my = u.uy;
+
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp))
continue;
cls();
- iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
- u.uinwater = u.uburied = 0;
+ (void) unconstrain_map();
/*
* Map all buried objects first.
*/
map_object(&gold, 1);
}
}
-
- newsym(u.ux, u.uy);
- u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
- iflags.save_uinwater = iflags.save_uburied = 0;
+ if (!glyph_is_object(glyph_at(u.ux, u.uy))) {
+ newsym(u.ux, u.uy);
+ ter_typ |= TER_MON;
+ }
You("detect the %s of %s.", ct ? "presence" : "absence", stuff);
- display_nhwindow(WIN_MAP, TRUE);
- /*
- * What are we going to do when the hero does an object detect while blind
- * and the detected object covers a known pool?
- */
+
+ if (!ct)
+ display_nhwindow(WIN_MAP, TRUE);
+ else
+ browse_map(ter_typ, "object");
+
+ reconstrain_map();
docrt(); /* this will correctly reset vision */
if (Underwater)
under_water(2);
: "You feel threatened.");
return 1;
} else {
- boolean woken = FALSE;
+ boolean unconstrained, woken = FALSE;
+ unsigned swallowed = u.uswallow; /* before unconstrain_map() */
cls();
+ unconstrained = unconstrain_map();
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp))
continue;
if (!mclass || mtmp->data->mlet == mclass
|| (mtmp->data == &mons[PM_LONG_WORM]
&& mclass == S_WORM_TAIL))
- if (mtmp->mx > 0) {
- if (mclass && def_monsyms[mclass].sym == ' ')
- show_glyph(mtmp->mx, mtmp->my,
- detected_mon_to_glyph(mtmp));
- else
- show_glyph(mtmp->mx, mtmp->my,
- mtmp->mtame ? pet_to_glyph(mtmp) : mon_to_glyph(mtmp));
- /* don't be stingy - display entire worm */
- if (mtmp->data == &mons[PM_LONG_WORM])
- detect_wsegs(mtmp, 0);
- }
+ map_monst(mtmp, TRUE);
+
if (otmp && otmp->cursed
&& (mtmp->msleeping || !mtmp->mcanmove)) {
mtmp->msleeping = mtmp->mfrozen = 0;
woken = TRUE;
}
}
- display_self();
+ if (!swallowed)
+ display_self();
You("sense the presence of monsters.");
if (woken)
pline("Monsters sense the presence of you.");
- display_nhwindow(WIN_MAP, TRUE);
- docrt();
+
+ if ((otmp && otmp->blessed) && !unconstrained) {
+ /* persistent detection--just show updated map */
+ display_nhwindow(WIN_MAP, TRUE);
+ } else {
+ /* one-shot detection--allow player to move cursor around and
+ get autodescribe feedback */
+ EDetect_monsters |= I_SPECIAL;
+ browse_map(TER_DETECT | TER_MON, "monster of interest");
+ EDetect_monsters &= ~I_SPECIAL;
+ }
+
+ reconstrain_map();
+ docrt(); /* redraw the screen to remove unseen monsters from map */
if (Underwater)
under_water(2);
if (u.uburied)
} else if (trap) {
map_trap(trap, 1);
trap->tseen = 1;
- } else {
+ } else { /* trapped door or trapped chest */
struct trap temp_trap; /* fake trap */
(void) memset((genericptr_t) &temp_trap, 0, sizeof temp_trap);
xchar x, y;
int result = OTRAP_NONE;
+ /*
+ * TODO? Display locations of unarmed land mine and beartrap objects.
+ * If so, should they be displayed as objects or as traps?
+ */
+
for (otmp = objlist; otmp; otmp = otmp->nobj) {
if (Is_box(otmp) && otmp->otrapped
&& get_obj_location(otmp, &x, &y, BURIED_TOO | CONTAINED_TOO)) {
{
register struct trap *ttmp;
struct monst *mon;
- int door, glyph, tr;
+ int door, glyph, tr, ter_typ = TER_DETECT | TER_TRP;
int cursed_src = sobj && sobj->cursed;
boolean found = FALSE;
coord cc;
+ if (u.usteed)
+ u.usteed->mx = u.ux, u.usteed->my = u.uy;
+
/* floor/ceiling traps */
for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
if (ttmp->tx != u.ux || ttmp->ty != u.uy)
outtrapmap:
cls();
- iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
- u.uinwater = u.uburied = 0;
-
+ (void) unconstrain_map();
/* show chest traps first, so that subsequent floor trap display
will override if both types are present at the same location */
(void) detect_obj_traps(fobj, TRUE, cursed_src);
/* redisplay hero unless sense_trap() revealed something at <ux,uy> */
glyph = glyph_at(u.ux, u.uy);
- if (!(glyph_is_trap(glyph) || glyph_is_object(glyph)))
+ if (!(glyph_is_trap(glyph) || glyph_is_object(glyph))) {
newsym(u.ux, u.uy);
- u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
- iflags.save_uinwater = iflags.save_uburied = 0;
-
+ ter_typ |= TER_MON; /* for autodescribe at <u.ux,u.uy> */
+ }
You_feel("%s.", cursed_src ? "very greedy" : "entrapped");
- /* wait for user to respond, then reset map display to normal */
- display_nhwindow(WIN_MAP, TRUE);
- docrt();
+
+ browse_map(ter_typ, "trap of interest");
+
+ reconstrain_map();
+ docrt(); /* redraw the screen to remove unseen traps from the map */
if (Underwater)
under_water(2);
if (u.uburied)
do_mapping()
{
register int zx, zy;
+ boolean unconstrained;
- iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
- u.uinwater = u.uburied = 0;
+ unconstrained = unconstrain_map();
for (zx = 1; zx < COLNO; zx++)
for (zy = 0; zy < ROWNO; zy++)
show_map_spot(zx, zy);
- u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
- iflags.save_uinwater = iflags.save_uburied = 0;
- if (!level.flags.hero_memory || Underwater) {
+
+ if (!level.flags.hero_memory || unconstrained) {
flush_screen(1); /* flush temp screen */
- display_nhwindow(WIN_MAP, TRUE); /* wait */
+ /* browse_map() instead of display_nhwindow(WIN_MAP, TRUE) */
+ browse_map(TER_DETECT | TER_MAP | TER_TRP | TER_OBJ,
+ "anything of interest");
docrt();
}
+ reconstrain_map();
exercise(A_WIS, TRUE);
}
+/* clairvoyance */
void
-do_vicinity_map()
+do_vicinity_map(sobj)
+struct obj *sobj; /* scroll--actually fake spellbook--object */
{
register int zx, zy;
- int lo_y = (u.uy - 5 < 0 ? 0 : u.uy - 5),
- hi_y = (u.uy + 6 > ROWNO ? ROWNO : u.uy + 6),
- lo_x = (u.ux - 9 < 1 ? 1 : u.ux - 9), /* avoid column 0 */
- hi_x = (u.ux + 10 > COLNO ? COLNO : u.ux + 10);
-
- for (zx = lo_x; zx < hi_x; zx++)
- for (zy = lo_y; zy < hi_y; zy++)
+ struct monst *mtmp;
+ boolean unconstrained, refresh = FALSE, mdetected = FALSE,
+ extended = (sobj && sobj->blessed);
+ int lo_y = ((u.uy - 5 < 0) ? 0 : u.uy - 5),
+ hi_y = ((u.uy + 6 >= ROWNO) ? ROWNO - 1 : u.uy + 6),
+ lo_x = ((u.ux - 9 < 1) ? 1 : u.ux - 9), /* avoid column 0 */
+ hi_x = ((u.ux + 10 >= COLNO) ? COLNO - 1 : u.ux + 10),
+ ter_typ = TER_DETECT | TER_MAP | TER_TRP | TER_OBJ;
+
+ unconstrained = unconstrain_map();
+ for (zx = lo_x; zx <= hi_x; zx++)
+ for (zy = lo_y; zy <= hi_y; zy++) {
show_map_spot(zx, zy);
- if (!level.flags.hero_memory || Underwater) {
+ if (extended && (mtmp = m_at(zx, zy)) != 0
+ && mtmp->mx == zx && mtmp->my == zy) { /* skip worm tails */
+ int oldglyph = glyph_at(zx, zy);
+
+ map_monst(mtmp, FALSE);
+ if (glyph_at(zx, zy) != oldglyph)
+ mdetected = TRUE;
+ }
+ }
+
+ if (!level.flags.hero_memory || unconstrained || mdetected) {
flush_screen(1); /* flush temp screen */
- display_nhwindow(WIN_MAP, TRUE); /* wait */
- docrt();
+ if (extended || glyph_is_monster(glyph_at(u.ux, u.uy)))
+ ter_typ |= TER_MON;
+ if (extended)
+ EDetect_monsters |= I_SPECIAL;
+ browse_map(ter_typ, "anything of interest");
+ EDetect_monsters &= ~I_SPECIAL;
+ refresh = TRUE;
}
+ reconstrain_map();
+ if (refresh)
+ docrt();
}
/* convert a secret door into a normal door */
exercise(A_WIS, TRUE);
if (!canspotmon(mtmp)) {
if (glyph_is_invisible(levl[x][y].glyph)) {
- /* found invisible monster in a square
- * which already has an 'I' in it.
- * Logically, this should still take
- * time and lead to a return(1), but
- * if we did that the player would keep
- * finding the same monster every turn.
+ /* Found invisible monster in a square which already has
+ * an 'I' in it. Logically, this should still take time
+ * and lead to a return 1, but if we did that the player
+ * would keep finding the same monster every turn.
*/
return -1;
} else {
map_invisible(x, y);
}
} else if (!sensemon(mtmp))
- You("find %s.", mtmp->mtame
- ? y_monnam(mtmp)
- : a_monnam(mtmp));
+ You("find %s.",
+ mtmp->mtame ? y_monnam(mtmp) : a_monnam(mtmp));
return 1;
}
if (!canspotmon(mtmp)) {
if (mtmp->mundetected
- && (is_hider(mtmp->data)
- || mtmp->data->mlet == S_EEL))
+ && (is_hider(mtmp->data) || mtmp->data->mlet == S_EEL))
if (via_warning) {
Your("warning senses cause you to take a second %s.",
- Blind ? "to check nearby" : "look close by");
+ Blind ? "to check nearby" : "look close by");
display_nhwindow(WIN_MESSAGE, FALSE); /* flush messages */
}
mtmp->mundetected = 0;
register int aflag; /* intrinsic autosearch vs explicit searching */
{
#ifdef GCC_BUG
- /* some versions of gcc seriously muck up nested loops. if you get strange
- crashes while searching in a version compiled with gcc, try putting
- #define GCC_BUG in *conf.h (or adding -DGCC_BUG to CFLAGS in the
- makefile).
+ /* Some old versions of gcc seriously muck up nested loops. If you get
+ * strange crashes while searching in a version compiled with gcc, try
+ * putting #define GCC_BUG in *conf.h (or adding -DGCC_BUG to CFLAGS in
+ * the makefile).
*/
volatile xchar x, y;
#else
} else {
int x, y, glyph, levl_glyph, default_glyph;
uchar seenv;
- unsigned save_swallowed;
struct monst *mtmp;
struct trap *t;
- coord pos;
char buf[BUFSZ];
/* there is a TER_MAP bit too; we always show map regardless of it */
boolean keep_traps = (which_subset & TER_TRP) !=0,
keep_objs = (which_subset & TER_OBJ) != 0,
keep_mons = (which_subset & TER_MON) != 0; /* not used */
+ unsigned swallowed = u.uswallow; /* before unconstrain_map() */
- save_swallowed = u.uswallow;
- iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
- u.uinwater = u.uburied = 0;
- u.uswallow = 0;
- if (iflags.save_uinwater || iflags.save_uburied)
+ if (unconstrain_map())
docrt();
default_glyph = cmap_to_glyph(level.flags.arboreal ? S_tree : S_stone);
/* for 'full', show the actual terrain for the entire level,
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 = !swallowed ? glyph_at(x, y) : levl_glyph;
+ if (keep_mons && x == u.ux && y == u.uy && swallowed)
glyph = mon_to_glyph(u.ustuck);
else if (((glyph_is_monster(glyph)
|| glyph_is_warning(glyph)) && !keep_mons)
/* allow player to move cursor around and get autodescribe feedback
based on what is visible now rather than what is on 'real' map */
- pos.x = u.ux, pos.y = u.uy;
- iflags.autodescribe = TRUE;
- iflags.terrainmode = which_subset | TER_MAP; /* guaranteed non-zero */
- getpos(&pos, FALSE, "anything of interest");
- iflags.terrainmode = 0;
- /* leave iflags.autodescribe 'on' even if it was previously 'off' */
-
- u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
- iflags.save_uinwater = iflags.save_uburied = 0;
- if (save_swallowed)
- u.uswallow = 1;
+ which_subset |= TER_MAP; /* guarantee non-zero */
+ browse_map(which_subset, "anything of interest");
+
+ reconstrain_map();
docrt(); /* redraw the screen, restoring regular map */
if (Underwater)
under_water(2);
mons[u.umonnum].mname, plname);
if (u.usteed)
Sprintf(eos(outbuf), ", mounted on %s", y_monnam(u.usteed));
+ if (u.uundetected || (Upolyd && youmonst.m_ap_type))
+ mhidden_description(&youmonst, FALSE, eos(outbuf));
return outbuf;
}
/* describe a hidden monster; used for look_at during extended monster
- detection and for probing */
+ detection and for probing; also when looking at self */
void
mhidden_description(mon, altmon, outbuf)
struct monst *mon;
char *outbuf;
{
struct obj *otmp;
- boolean fakeobj;
- int x = mon->mx, y = mon->my, glyph = levl[x][y].glyph;
+ boolean fakeobj, isyou = (mon == &youmonst);
+ int x = isyou ? u.ux : mon->mx, y = isyou ? u.uy : mon->my,
+ glyph = (level.flags.hero_memory && !isyou) ? levl[x][y].glyph
+ : glyph_at(x, y);
*outbuf = '\0';
if (mon->m_ap_type == M_AP_FURNITURE
if (altmon)
Sprintf(outbuf, ", masquerading as %s",
an(mons[mon->mappearance].mname));
- } else if (mon->mundetected) {
+ } else if (isyou ? u.uundetected : mon->mundetected) {
Strcpy(outbuf, ", hiding");
if (hides_under(mon->data)) {
Strcat(outbuf, " under ");
{
boolean fakeobj = FALSE;
struct monst *mtmp;
- struct obj *otmp = vobj_at(x, y);
+ struct obj *otmp;
int glyphotyp = glyph_to_obj(glyph);
*obj_p = (struct obj *) 0;
+ /* TODO: check inside containers in case glyph came from detection */
+ if ((otmp = sobj_at(glyphotyp, x, y)) == 0)
+ for (otmp = level.buriedobjlist; otmp; otmp = otmp->nobj)
+ if (otmp->ox == x && otmp->oy == y && otmp->otyp == glyphotyp)
+ break;
+
/* there might be a mimic here posing as an object */
mtmp = m_at(x, y);
if (mtmp && is_obj_mappear(mtmp, (unsigned) glyphotyp))
} else
Strcpy(buf, something); /* sanity precaution */
- if (levl[x][y].typ == STONE || levl[x][y].typ == SCORR)
+ if (otmp && otmp->where == OBJ_BURIED)
+ Strcat(buf, " (buried)");
+ else if (levl[x][y].typ == STONE || levl[x][y].typ == SCORR)
Strcat(buf, " embedded in stone");
else if (IS_WALL(levl[x][y].typ) || levl[x][y].typ == SDOOR)
Strcat(buf, " embedded in a wall");
? "peaceful "
: "",
name);
- if (u.ustuck == mtmp)
- Strcat(buf, (Upolyd && sticks(youmonst.data))
- ? ", being held" : ", holding you");
+ if (u.ustuck == mtmp) {
+ if (u.uswallow || iflags.save_uswallow) /* monster detection */
+ Strcat(buf, is_animal(mtmp->data)
+ ? ", swallowing you" : ", engulfing you");
+ else
+ Strcat(buf, (Upolyd && sticks(youmonst.data))
+ ? ", being held" : ", holding you");
+ }
if (mtmp->mleashed)
Strcat(buf, ", leashed to you");
buf[0] = monbuf[0] = '\0';
glyph = glyph_at(x, y);
if (u.ux == x && u.uy == y && canspotself()
+ && !(iflags.save_uswallow && glyph == mon_to_glyph(u.ustuck))
&& (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0)) {
/* fill in buf[] */
(void) self_lookat(buf);
(even if you could also see yourself via other means).
Sensing self while blind or swallowed is treated as if it
were by normal vision (cf canseeself()). */
- if ((Invisible || u.uundetected) && !Blind && !u.uswallow) {
+ if ((Invisible || u.uundetected) && !Blind
+ && !(u.uswallow || iflags.save_uswallow)) {
unsigned how = 0;
if (Infravision)
* submerged will always both be False and skip this code.)
*/
x_str = 0;
- if (looked && (u.uswallow || submerged) && distu(cc.x, cc.y) > 2) {
+ if (!looked) {
+ ; /* skip special handling */
+ } else if (((u.uswallow || submerged) && distu(cc.x, cc.y) > 2)
+ /* detection showing some category, so mostly background */
+ || ((iflags.terrainmode & (TER_DETECT | TER_MAP)) == TER_DETECT
+ && glyph == cmap_to_glyph(S_stone))) {
x_str = unreconnoitered;
need_to_look = FALSE;
- } else if (looked && u.uswallow && is_swallow_sym(sym)) {
+ } else if (is_swallow_sym(sym)) {
x_str = mon_interior;
need_to_look = TRUE; /* for specific monster type */
}
if (quick) {
from_screen = TRUE; /* yes, we want to use the cursor */
i = 'y';
- }
-
- if (i != 'y') {
+ } else {
menu_item *pick_list = (menu_item *) 0;
winid win;
anything any;