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
+2
View File
@@ -349,6 +349,8 @@ extend wizard-mode '#stats' command
quivered, provided the stack isn't already in the quiver slot
during end of game disclosure, the vanquished monsters list can be sorted in
one of several ways by answering 'a' to "disclose vanquished monsters?"
when #terrain is displaying a censored version of the map (no monsters, &c),
moving the cursor will display farlook's brief autodescribe feedback
Platform- and/or Interface-Specific New Features
+10 -2
View File
@@ -186,17 +186,24 @@ struct instance_flags {
int purge_monsters; /* # of dead monsters still on fmon list */
int override_ID; /* true to force full identification of objects */
int suppress_price; /* controls doname() for unpaid objects */
int terrainmode; /* for getpos()'s autodescribe when #terrain is active */
#define TER_MAP 0x01
#define TER_TRP 0x02
#define TER_OBJ 0x04
#define TER_MON 0x08
coord travelcc; /* coordinates for travel_cache */
boolean window_inited; /* true if init_nhwindows() completed */
boolean vision_inited; /* true if vision is ready */
boolean sanity_check; /* run sanity checks */
boolean mon_polycontrol; /* debug: control monster polymorphs */
/* stuff that is related to options and/or user or platform preferences */
/* stuff that is related to options and/or user or platform preferences
*/
unsigned msg_history; /* hint: # of top lines to save */
int getpos_coords; /* show coordinates when getting cursor position */
int menu_headings; /* ATR for menu headings */
int *opt_booldup; /* for duplication of boolean opts in config file */
int *opt_compdup; /* for duplication of compound opts in config file */
int *opt_compdup; /* for duplication of compound opts in conf file */
#ifdef ALTMETA
boolean altmeta; /* Alt-c sends ESC c rather than M-c */
#endif
@@ -275,6 +282,7 @@ struct instance_flags {
boolean vt_tiledata; /* output console codes for tile support in TTY */
#endif
boolean wizweight; /* display weight of everything in wizard mode */
/*
* Window capability support.
*/
+20 -7
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 */
}
+21 -9
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);
+18 -8
View File
@@ -59,17 +59,21 @@ 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.");
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)
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) */
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 :" : "");
@@ -77,13 +81,16 @@ const char *goal;
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;",
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, 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.");
putstr(tmpwin, 0, "");
@@ -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;
if (!iflags.terrainmode) {
pline("Done.");
msg_given = FALSE; /* suppress clear */
}
cx = -1;
cy = 0;
result = 0; /* not -1 */
+18 -8
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,11 +350,11 @@ char *buf, *monbuf;
how |= 4;
if (how)
Sprintf(
eos(buf), " [seen: %s%s%s%s%s]",
Sprintf(eos(buf), " [seen: %s%s%s%s%s]",
(how & 1) ? "infravision" : "",
/* add comma if telep and infrav */
((how & 3) > 2) ? ", " : "", (how & 2) ? "telepathy" : "",
((how & 3) > 2) ? ", " : "",
(how & 2) ? "telepathy" : "",
/* add comma if detect and (infrav or telep or both) */
((how & 7) > 4) ? ", " : "",
(how & 4) ? "monster detection" : "");
@@ -682,12 +684,14 @@ const char **firstmatch;
}
/* Check for monsters */
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));
Sprintf(out_str, "%s%s",
prefix, an(def_monsyms[i].explain));
*firstmatch = def_monsyms[i].explain;
found++;
} else {
@@ -703,17 +707,22 @@ const char **firstmatch;
: (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 */
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)) {
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));
Sprintf(out_str, "%s%s",
prefix, an(def_oc_syms[i].explain));
*firstmatch = def_oc_syms[i].explain;
found++;
} else {
@@ -721,6 +730,7 @@ const char **firstmatch;
}
}
}
}
if (sym == DEF_INVISIBLE) {
if (!found) {