autodescribe for #terrain

Requested during beta-testing however long ago:  want a way to
look at specific map locations while #terrain is showing them
without monsters and/or objects and/or traps being displayed in
the way.  The post-3.6.0 autodescribe feature for getpos() made
this pretty easy to achieve, although the lookat() aspect felt
more like trail-and-error than careful design.

Instead of putting up a --More-- prompt, ask the player to pick
a location with the cursor.  Moving the cursor gives the terse
description for every location traversed.  Actually picking a
spot just ends #terrain and goes back to normal play.
This commit is contained in:
PatR
2016-05-12 18:57:10 -07:00
parent 088c47a427
commit dccc818801
6 changed files with 149 additions and 94 deletions

View File

@@ -1226,13 +1226,26 @@ doterrain(VOID_ARGS)
free((genericptr_t) sel);
switch (which) {
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;
case 1: /* known map */
reveal_terrain(0, TER_MAP);
break;
case 2: /* known map with known traps */
reveal_terrain(0, TER_MAP | TER_TRP);
break;
case 3: /* known map with known traps and objects */
reveal_terrain(0, TER_MAP | TER_TRP | TER_OBJ);
break;
case 4: /* full map */
reveal_terrain(1, TER_MAP);
break;
case 5: /* map internals */
wiz_map_levltyp();
break;
case 6: /* internal details */
wiz_levltyp_legend();
break;
default:
break;
}
return 0; /* no time elapses */
}

View File

@@ -1524,10 +1524,12 @@ int which_subset; /* when not full, whether to suppress objs and/or traps */
unsigned save_swallowed;
struct monst *mtmp;
struct trap *t;
coord pos;
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 */
/* 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 */
save_swallowed = u.uswallow;
iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
@@ -1605,11 +1607,8 @@ int which_subset; /* when not full, whether to suppress objs and/or traps */
show_glyph(x, y, glyph);
}
/* [TODO: highlight hero's location somehow] */
u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
iflags.save_uinwater = iflags.save_uburied = 0;
if (save_swallowed)
u.uswallow = 1;
/* hero's location is not highlighted, but getpos() starts with
cursor there, and after moving it anywhere '@' moves it back */
flush_screen(1);
if (full) {
Strcpy(buf, "underlying terrain");
@@ -1627,7 +1626,20 @@ int which_subset; /* when not full, whether to suppress objs and/or traps */
(keep_traps || keep_objs) ? "," : "");
}
pline("Showing %s only...", buf);
display_nhwindow(WIN_MAP, TRUE); /* give "--More--" prompt */
/* 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;
docrt(); /* redraw the screen, restoring regular map */
if (Underwater)
under_water(2);

View File

@@ -59,30 +59,37 @@ const char *goal;
putstr(tmpwin, 0, "Use [HJKL] to move the cursor 8 units at a time.");
putstr(tmpwin, 0, "Or enter a background symbol (ex. <).");
putstr(tmpwin, 0, "Use @ to move the cursor on yourself.");
putstr(tmpwin, 0, "Use m or M to move the cursor to next monster.");
putstr(tmpwin, 0, "Use o or O to move the cursor to next object.");
if (getpos_hilitefunc)
putstr(tmpwin, 0, "Use $ to display valid locations.");
putstr(tmpwin, 0, "Use # to toggle automatic description.");
if (iflags.cmdassist) /* assisting the '/' command, I suppose... */
putstr(tmpwin, 0, (iflags.getpos_coords == GPCOORDS_NONE)
? "(Set 'whatis_coord' option to include coordinates with '#' text.)"
if (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0)
putstr(tmpwin, 0, "Use m or M to move the cursor to next monster.");
if (!iflags.terrainmode || (iflags.terrainmode & TER_OBJ) != 0)
putstr(tmpwin, 0, "Use o or O to move the cursor to next object.");
if (!iflags.terrainmode) {
if (getpos_hilitefunc)
putstr(tmpwin, 0, "Use $ to display valid locations.");
putstr(tmpwin, 0, "Use # to toggle automatic description.");
if (iflags.cmdassist) /* assisting the '/' command, I suppose... */
putstr(tmpwin, 0,
(iflags.getpos_coords == GPCOORDS_NONE)
? "(Set 'whatis_coord' option to include coordinates with '#' text.)"
: "(Reset 'whatis_coord' option to omit coordinates from '#' text.)");
/* disgusting hack; the alternate selection characters work for any
getpos call, but they only matter for dowhatis (and doquickwhatis) */
doing_what_is = (goal == what_is_an_unknown_object);
Sprintf(sbuf, "Type a .%s when you are at the right place.",
doing_what_is ? " or , or ; or :" : "");
putstr(tmpwin, 0, sbuf);
if (doing_what_is) {
putstr(tmpwin, 0,
" : describe current spot, show 'more info', move to another spot.");
Sprintf(sbuf, " . describe current spot,%s move to another spot;",
flags.help ? " prompt if 'more info'," : "");
/* disgusting hack; the alternate selection characters work for any
getpos call, but only matter for dowhatis (and doquickwhatis) */
doing_what_is = (goal == what_is_an_unknown_object);
Sprintf(sbuf, "Type a .%s when you are at the right place.",
doing_what_is ? " or , or ; or :" : "");
putstr(tmpwin, 0, sbuf);
putstr(tmpwin, 0, " , describe current spot, move to another spot;");
putstr(tmpwin, 0,
" ; describe current spot, stop looking at things;");
if (doing_what_is) {
putstr(tmpwin, 0,
" : describe current spot, show 'more info', move to another spot.");
Sprintf(sbuf,
" . describe current spot,%s move to another spot;",
flags.help ? " prompt if 'more info'," : "");
putstr(tmpwin, 0, sbuf);
putstr(tmpwin, 0,
" , describe current spot, move to another spot;");
putstr(tmpwin, 0,
" ; describe current spot, stop looking at things;");
}
}
if (!force)
putstr(tmpwin, 0, "Type Space or Escape when you're done.");
@@ -446,7 +453,7 @@ const char *goal;
hi_x = (pass == 1 && ty == hi_y) ? cx : COLNO - 1;
for (tx = lo_x; tx <= hi_x; tx++) {
/* look at dungeon feature, not at
* user-visible glyph */
user-visible glyph */
k = back_to_glyph(tx, ty);
/* uninteresting background glyph */
if (glyph_is_cmap(k)
@@ -460,9 +467,10 @@ const char *goal;
}
if (glyph_is_cmap(k)
&& matching[glyph_to_cmap(k)]
&& levl[tx][ty].seenv
&& (!IS_WALL(levl[tx][ty].typ))
&& (levl[tx][ty].typ != SDOOR)
&& (levl[tx][ty].seenv
|| iflags.terrainmode)
&& !IS_WALL(levl[tx][ty].typ)
&& levl[tx][ty].typ != SDOOR
&& glyph_to_cmap(k) != S_room
&& glyph_to_cmap(k) != S_corr
&& glyph_to_cmap(k) != S_litcorr) {
@@ -495,8 +503,10 @@ const char *goal;
} /* !quitchars */
if (force)
goto nxtc;
pline("Done.");
msg_given = FALSE; /* suppress clear */
if (!iflags.terrainmode) {
pline("Done.");
msg_given = FALSE; /* suppress clear */
}
cx = -1;
cy = 0;
result = 0; /* not -1 */

View File

@@ -166,7 +166,8 @@ struct obj **obj_p;
otmp->corpsenm = MCORPSENM(mtmp);
}
/* if located at adjacent spot, mark it as having been seen up close */
if (otmp && distu(x, y) <= 2 && !Blind && !Hallucination)
if (otmp && distu(x, y) <= 2 && !Blind && !Hallucination
&& !iflags.terrainmode)
otmp->dknown = 1;
*obj_p = otmp;
@@ -323,7 +324,8 @@ char *buf, *monbuf;
buf[0] = monbuf[0] = '\0';
glyph = glyph_at(x, y);
if (u.ux == x && u.uy == y && canspotself()) {
if (u.ux == x && u.uy == y && canspotself()
&& (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0)) {
/* fill in buf[] */
(void) self_lookat(buf);
@@ -348,14 +350,14 @@ char *buf, *monbuf;
how |= 4;
if (how)
Sprintf(
eos(buf), " [seen: %s%s%s%s%s]",
(how & 1) ? "infravision" : "",
/* add comma if telep and infrav */
((how & 3) > 2) ? ", " : "", (how & 2) ? "telepathy" : "",
/* add comma if detect and (infrav or telep or both) */
((how & 7) > 4) ? ", " : "",
(how & 4) ? "monster detection" : "");
Sprintf(eos(buf), " [seen: %s%s%s%s%s]",
(how & 1) ? "infravision" : "",
/* add comma if telep and infrav */
((how & 3) > 2) ? ", " : "",
(how & 2) ? "telepathy" : "",
/* add comma if detect and (infrav or telep or both) */
((how & 7) > 4) ? ", " : "",
(how & 4) ? "monster detection" : "");
}
} else if (u.uswallow) {
/* all locations when swallowed other than the hero are the monster */
@@ -682,42 +684,50 @@ const char **firstmatch;
}
/* Check for monsters */
for (i = 0; i < MAXMCLASSES; i++) {
if (sym == (looked ? showsyms[i + SYM_OFF_M] : def_monsyms[i].sym)
&& def_monsyms[i].explain) {
need_to_look = TRUE;
if (!found) {
Sprintf(out_str, "%s%s", prefix, an(def_monsyms[i].explain));
*firstmatch = def_monsyms[i].explain;
found++;
} else {
found += append_str(out_str, an(def_monsyms[i].explain));
if (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0) {
for (i = 0; i < MAXMCLASSES; i++) {
if (sym == (looked ? showsyms[i + SYM_OFF_M] : def_monsyms[i].sym)
&& def_monsyms[i].explain) {
need_to_look = TRUE;
if (!found) {
Sprintf(out_str, "%s%s",
prefix, an(def_monsyms[i].explain));
*firstmatch = def_monsyms[i].explain;
found++;
} else {
found += append_str(out_str, an(def_monsyms[i].explain));
}
}
}
/* handle '@' as a special case if it refers to you and you're
playing a character which isn't normally displayed by that
symbol; firstmatch is assumed to already be set for '@' */
if ((looked ? (sym == showsyms[S_HUMAN + SYM_OFF_M]
&& cc.x == u.ux && cc.y == u.uy)
: (sym == def_monsyms[S_HUMAN].sym && !flags.showrace))
&& !(Race_if(PM_HUMAN) || Race_if(PM_ELF)) && !Upolyd)
found += append_str(out_str, "you"); /* tack on "or you" */
}
/* handle '@' as a special case if it refers to you and you're
playing a character which isn't normally displayed by that
symbol; firstmatch is assumed to already be set for '@' */
if ((looked ? (sym == showsyms[S_HUMAN + SYM_OFF_M]
&& cc.x == u.ux && cc.y == u.uy)
: (sym == def_monsyms[S_HUMAN].sym && !flags.showrace))
&& !(Race_if(PM_HUMAN) || Race_if(PM_ELF)) && !Upolyd)
found += append_str(out_str, "you"); /* tack on "or you" */
/* Now check for objects */
for (i = 1; i < MAXOCLASSES; i++) {
if (sym == (looked ? showsyms[i + SYM_OFF_O] : def_oc_syms[i].sym)) {
need_to_look = TRUE;
if (looked && i == VENOM_CLASS) {
skipped_venom++;
continue;
}
if (!found) {
Sprintf(out_str, "%s%s", prefix, an(def_oc_syms[i].explain));
*firstmatch = def_oc_syms[i].explain;
found++;
} else {
found += append_str(out_str, an(def_oc_syms[i].explain));
if (!iflags.terrainmode || (iflags.terrainmode & TER_OBJ) != 0) {
for (i = 1; i < MAXOCLASSES; i++) {
if (sym == (looked ? showsyms[i + SYM_OFF_O]
: def_oc_syms[i].sym)
|| (looked && i == ROCK_CLASS && glyph_is_statue(glyph))) {
need_to_look = TRUE;
if (looked && i == VENOM_CLASS) {
skipped_venom++;
continue;
}
if (!found) {
Sprintf(out_str, "%s%s",
prefix, an(def_oc_syms[i].explain));
*firstmatch = def_oc_syms[i].explain;
found++;
} else {
found += append_str(out_str, an(def_oc_syms[i].explain));
}
}
}
}