mirror of
https://codeberg.org/noisytoot/notnotdnethack.git
synced 2025-05-15 20:15:04 +01:00
Merge pull request #2220 from RikerW/patch-terrain-command
Add terrain command
This commit is contained in:
commit
1ed6ac28ca
6 changed files with 486 additions and 101 deletions
|
@ -397,6 +397,7 @@ E void FDECL(find_trap, (struct trap *));
|
|||
E int FDECL(dosearch0, (int));
|
||||
E int NDECL(dosearch);
|
||||
E void NDECL(sokoban_detect);
|
||||
E int NDECL(doterrain);
|
||||
|
||||
/* ### dig.c ### */
|
||||
|
||||
|
@ -2173,6 +2174,7 @@ E char *FDECL(dowhatdoes_core,(CHAR_P, char *));
|
|||
E int NDECL(dohelp);
|
||||
E int NDECL(dohistory);
|
||||
E boolean FDECL(checkfile, (char *,struct permonst *,BOOLEAN_P,BOOLEAN_P, winid*));
|
||||
E char *FDECL(do_look_letter, (glyph_t, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P, coord, char *, const char *));
|
||||
|
||||
/* ### pcmain.c ### */
|
||||
|
||||
|
|
|
@ -374,6 +374,12 @@ struct instance_flags {
|
|||
int statuslines;
|
||||
|
||||
int pokedex; /* default monster stats to show in the pokedex */
|
||||
|
||||
boolean save_uinwater; /* tracks if we're actually buried etc. for #terrain*/
|
||||
boolean save_uburied;
|
||||
boolean save_uswallow;
|
||||
|
||||
boolean autodescribe;
|
||||
/*
|
||||
* Window capability support.
|
||||
*/
|
||||
|
|
|
@ -2470,9 +2470,10 @@ struct ext_func_tab extcmdlist[] = {
|
|||
{"style", "switch fighting style", dofightingform, !IFBURIED, AUTOCOMPLETE},
|
||||
{"sit", "sit down", dosit, !IFBURIED, AUTOCOMPLETE},
|
||||
{"swim", "swim under water", dodeepswim, !IFBURIED, AUTOCOMPLETE},
|
||||
{"turn", "turn undead", doturn, IFBURIED, AUTOCOMPLETE},
|
||||
{"terrain", "display level terrain", doterrain, IFBURIED, AUTOCOMPLETE },
|
||||
{"tip", "empty a container", dotip, IFBURIED, AUTOCOMPLETE},
|
||||
{"twoweapon", "toggle two-weapon combat", dotwoweapon, !IFBURIED, AUTOCOMPLETE},
|
||||
{"turn", "turn undead", doturn, IFBURIED, AUTOCOMPLETE},
|
||||
{"unseeinvis", "forget suspected invisible creatures", doclearinvissyms, IFBURIED, AUTOCOMPLETE},
|
||||
{"untrap", "untrap something", dountrap, !IFBURIED, AUTOCOMPLETE},
|
||||
{"unmaintain", "stop maintaining a spell", dounmaintain, IFBURIED, AUTOCOMPLETE},
|
||||
|
|
300
src/detect.c
300
src/detect.c
|
@ -19,6 +19,12 @@ STATIC_DCL void FDECL(sense_trap, (struct trap *,XCHAR_P,XCHAR_P,int));
|
|||
STATIC_DCL void FDECL(show_map_spot, (int,int));
|
||||
STATIC_PTR void FDECL(findone,(int,int,genericptr_t));
|
||||
STATIC_PTR void FDECL(openone,(int,int,genericptr_t));
|
||||
STATIC_PTR boolean unconstrain_map(void);
|
||||
STATIC_PTR void reconstrain_map(void);
|
||||
STATIC_PTR void map_redisplay(void);
|
||||
STATIC_PTR void browse_map(const char *);
|
||||
STATIC_PTR int reveal_terrain_getglyph(int, int, unsigned, int, unsigned);
|
||||
STATIC_PTR void reveal_terrain(int);
|
||||
|
||||
/* Recursively search obj for an object in class oclass and return 1st found */
|
||||
struct obj *
|
||||
|
@ -1720,5 +1726,299 @@ sokoban_detect()
|
|||
}
|
||||
}
|
||||
|
||||
/* bring hero out from underwater or underground or being engulfed;
|
||||
return True iff any change occurred */
|
||||
static boolean
|
||||
unconstrain_map(void)
|
||||
{
|
||||
boolean res = u.uinwater || u.uburied || u.uswallow;
|
||||
|
||||
/* bring Underwater, buried, or swallowed hero to normal map;
|
||||
bypass set_uinwater() */
|
||||
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 void
|
||||
reconstrain_map(void)
|
||||
{
|
||||
/* if was in water and taken out, put back; bypass set_uinwater() */
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
map_redisplay(void)
|
||||
{
|
||||
reconstrain_map();
|
||||
docrt(); /* redraw the screen to remove unseen traps from the map */
|
||||
if (Underwater)
|
||||
under_water(2);
|
||||
if (u.uburied)
|
||||
under_ground(2);
|
||||
}
|
||||
|
||||
#define TER_MAP 0x01
|
||||
#define TER_TRP 0x02
|
||||
#define TER_OBJ 0x04
|
||||
#define TER_MON 0x08
|
||||
#define TER_FULL 0x10 /* explore|wizard mode view full map */
|
||||
#define TER_DETECT 0x20 /* detect_foo magic rather than #terrain */
|
||||
|
||||
static int
|
||||
reveal_terrain_getglyph(
|
||||
int x, int y,
|
||||
unsigned swallowed,
|
||||
int default_glyph,
|
||||
unsigned which_subset)
|
||||
{
|
||||
int glyph, levl_glyph;
|
||||
uchar seenv;
|
||||
boolean keep_traps = (which_subset & TER_TRP) != 0,
|
||||
keep_objs = (which_subset & TER_OBJ) != 0,
|
||||
keep_mons = (which_subset & TER_MON) != 0,
|
||||
full = (which_subset & TER_FULL) != 0;
|
||||
struct monst *mtmp;
|
||||
struct trap *t;
|
||||
|
||||
/* 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 */
|
||||
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 {
|
||||
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 = !swallowed ? glyph_at(x, y) : levl_glyph;
|
||||
if (keep_mons && (u.ux == x && u.uy == y) && 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 (levl[x][y].styp == 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 {
|
||||
struct rm save_spot;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* An exception is wall_info which can be recalculated and
|
||||
* needs to be. Otherwise back_to_glyph() -> wall_angle()
|
||||
* might issue an impossible() for it if it is currently
|
||||
* doormask==D_OPEN for an open door remembered as a wall.
|
||||
*/
|
||||
save_spot = levl[x][y];
|
||||
levl[x][y].typ = levl[x][y].styp;
|
||||
glyph = back_to_glyph(x, y);
|
||||
levl[x][y] = save_spot;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* FIXME: dirty hack */
|
||||
if (glyph == cmap_to_glyph(S_drkroom))
|
||||
glyph = cmap_to_glyph(S_litroom);
|
||||
else if (glyph == cmap_to_glyph(S_litcorr))
|
||||
glyph = cmap_to_glyph(S_corr);
|
||||
return glyph;
|
||||
}
|
||||
|
||||
/* use getpos()'s 'autodescribe' to view whatever is currently shown on map */
|
||||
static void
|
||||
browse_map(const char *ter_explain)
|
||||
{
|
||||
coord dummy_pos; /* don't care whether player actually picks a spot */
|
||||
boolean adescribe = iflags.autodescribe; /* preserve previous autodescribe state */
|
||||
|
||||
dummy_pos.x = u.ux, dummy_pos.y = u.uy; /* starting spot for getpos() */
|
||||
iflags.autodescribe = TRUE;
|
||||
(void) getpos(&dummy_pos, FALSE, ter_explain);
|
||||
iflags.autodescribe = adescribe;
|
||||
}
|
||||
|
||||
void
|
||||
reveal_terrain(which_subset)
|
||||
int which_subset; /* TER_TRP | TER_OBJ | TER_MON | TER_FULL */
|
||||
{
|
||||
/* 'full' overrides impairment and implies no-traps, no-objs, no-mons */
|
||||
boolean full = (which_subset & TER_FULL) != 0; /* show whole map */
|
||||
|
||||
if ((Hallucination || Stunned || Confusion) && !full) {
|
||||
You("are too disoriented for this.");
|
||||
} else {
|
||||
int x, y;
|
||||
int glyph, default_glyph;
|
||||
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() */
|
||||
|
||||
if (unconstrain_map())
|
||||
docrt();
|
||||
default_glyph = cmap_to_glyph(level.flags.arboreal ? S_tree : S_stone);
|
||||
|
||||
for (x = 1; x < COLNO; x++)
|
||||
for (y = 0; y < ROWNO; y++) {
|
||||
glyph = reveal_terrain_getglyph(x,y, swallowed,
|
||||
default_glyph, which_subset);
|
||||
show_glyph(x, y, glyph);
|
||||
}
|
||||
|
||||
/* 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");
|
||||
} 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);
|
||||
|
||||
/* allow player to move cursor around and get autodescribe feedback
|
||||
based on what is visible now rather than what is on 'real' map */
|
||||
which_subset |= TER_MAP; /* guarantee non-zero */
|
||||
browse_map("anything of interest");
|
||||
|
||||
map_redisplay();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* #terrain command -- show known map, inspired by crawl's '|' command */
|
||||
int
|
||||
doterrain(void)
|
||||
{
|
||||
winid men;
|
||||
menu_item *sel;
|
||||
anything any;
|
||||
int n;
|
||||
int which;
|
||||
int clr = 0;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
start_menu(men);
|
||||
any.a_void = 0;
|
||||
|
||||
|
||||
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);
|
||||
end_menu(men, "View which?");
|
||||
|
||||
if (discover || wizard){
|
||||
any.a_int = 4;
|
||||
add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
|
||||
"full map without monsters, objects, and traps",
|
||||
MENU_UNSELECTED);
|
||||
}
|
||||
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 <space>|<enter>;
|
||||
* 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: /* known map */
|
||||
reveal_terrain(TER_MAP);
|
||||
break;
|
||||
case 2: /* known map with known traps */
|
||||
reveal_terrain(TER_MAP | TER_TRP);
|
||||
break;
|
||||
case 3: /* known map with known traps and objects */
|
||||
reveal_terrain(TER_MAP | TER_TRP | TER_OBJ);
|
||||
break;
|
||||
case 4: /* full map */
|
||||
reveal_terrain(TER_MAP | TER_FULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0; /* no time elapses */
|
||||
}
|
||||
|
||||
#undef TER_MAP
|
||||
#undef TER_TRP
|
||||
#undef TER_OBJ
|
||||
#undef TER_MON
|
||||
#undef TER_FULL
|
||||
#undef TER_DETECT
|
||||
|
||||
/*detect.c*/
|
||||
|
|
|
@ -136,6 +136,56 @@ getpos_prevmon()
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
auto_describe(int cx, int cy)
|
||||
{
|
||||
coord cc;
|
||||
int sym = 0, glyph;
|
||||
char tmpbuf[BUFSZ], out_str[LONGBUFSZ];
|
||||
out_str[0] = 0;
|
||||
const char *firstmatch = "unknown";
|
||||
boolean force_defsyms;
|
||||
|
||||
cc.x = cx;
|
||||
cc.y = cy;
|
||||
|
||||
glyph = glyph_at(cc.x,cc.y);
|
||||
if (glyph_is_cmap(glyph)) {
|
||||
if (iflags.UTF8graphics) {
|
||||
/* Temporary workaround as NetHack can't yet
|
||||
* display UTF-8 glyphs on the topline */
|
||||
force_defsyms = TRUE;
|
||||
sym = defsyms[glyph_to_cmap(glyph)].sym;
|
||||
} else {
|
||||
sym = showsyms[glyph_to_cmap(glyph)];
|
||||
}
|
||||
} else if (glyph_is_trap(glyph)) {
|
||||
sym = showsyms[trap_to_defsym(glyph_to_trap(glyph))];
|
||||
} else if (glyph_is_object(glyph)) {
|
||||
sym = oc_syms[(int)objects[glyph_to_obj(glyph)].oc_class];
|
||||
if (sym == '`' && iflags.bouldersym && ((int)glyph_to_obj(glyph) == BOULDER || (int)glyph_to_obj(glyph) == MASS_OF_STUFF))
|
||||
sym = iflags.bouldersym;
|
||||
} else if (glyph_is_monster(glyph)) {
|
||||
/* takes care of pets, detected, ridden, and regular mons */
|
||||
sym = monsyms[(int)mons[glyph_to_mon(glyph)].mlet];
|
||||
} else if (glyph_is_swallow(glyph)) {
|
||||
sym = showsyms[glyph_to_swallow(glyph)+S_sw_tl];
|
||||
} else if (glyph_is_invisible(glyph)) {
|
||||
sym = DEF_INVISIBLE;
|
||||
} else if (glyph_is_warning(glyph)) {
|
||||
sym = glyph_to_warning(glyph);
|
||||
sym = warnsyms[sym];
|
||||
} else {
|
||||
impossible("do_look: bad glyph %d at (%d,%d)",
|
||||
glyph, (int)cc.x, (int)cc.y);
|
||||
sym = ' ';
|
||||
}
|
||||
do_look_letter(sym, TRUE, TRUE, force_defsyms, cc, out_str, firstmatch);
|
||||
if (out_str[0]) pline("%s", out_str);
|
||||
else impossible("no out str for do_look_letter on current terrain? sym %d", sym);
|
||||
flush_screen(1);
|
||||
}
|
||||
|
||||
int
|
||||
getpos(cc, force, goal)
|
||||
coord *cc;
|
||||
|
@ -166,6 +216,10 @@ const char *goal;
|
|||
lock_mouse_cursor(TRUE);
|
||||
#endif
|
||||
for (;;) {
|
||||
if (iflags.autodescribe) {
|
||||
auto_describe(cx, cy);
|
||||
curs(WIN_MAP,cx,cy);
|
||||
}
|
||||
c = nh_poskey(&tx, &ty, &sidx);
|
||||
if (c == '\033') {
|
||||
cx = cy = -10;
|
||||
|
|
222
src/pager.c
222
src/pager.c
|
@ -1374,96 +1374,72 @@ STATIC_OVL int
|
|||
do_look(quick)
|
||||
boolean quick; /* use cursor && don't search for "more info" */
|
||||
{
|
||||
char out_str[LONGBUFSZ], look_buf[BUFSZ];
|
||||
char out_str[LONGBUFSZ];
|
||||
out_str[0] = 0;
|
||||
const char *x_str, *firstmatch = 0;
|
||||
struct permonst *pm = 0;
|
||||
struct monst *mtmp = 0;
|
||||
int i, ans = 0;
|
||||
glyph_t sym; /* typed symbol or converted glyph */
|
||||
int found; /* count of matching syms found */
|
||||
coord cc; /* screen pos of unknown glyph */
|
||||
boolean save_verbose; /* saved value of flags.verbose */
|
||||
boolean from_screen; /* question from the screen */
|
||||
boolean force_defsyms; /* force using glyphs from defsyms[].sym */
|
||||
boolean need_to_look; /* need to get explan. from glyph */
|
||||
boolean hit_trap; /* true if found trap explanation */
|
||||
boolean hit_cloud; /* true if found cloud explanation */
|
||||
int skipped_venom; /* non-zero if we ignored "splash of venom" */
|
||||
int hallu_obj; /* non-zero if found hallucinable object */
|
||||
short otyp = STRANGE_OBJECT; /* to pass to artifact_name */
|
||||
int oartifact; /* to pass to artifact_name */
|
||||
static const char *mon_interior = "the interior of a monster";
|
||||
int i, ans = 0;
|
||||
coord cc; /* screen pos of unknown glyph */
|
||||
boolean force_defsyms = FALSE; /* force using glyphs from defsyms[].sym */
|
||||
|
||||
force_defsyms = FALSE;
|
||||
if (quick) {
|
||||
from_screen = TRUE; /* yes, we want to use the cursor */
|
||||
from_screen = TRUE; /* yes, we want to use the cursor */
|
||||
} else {
|
||||
i = ynq("Specify unknown object by cursor?");
|
||||
if (i == 'q') return MOVE_CANCELLED;
|
||||
from_screen = (i == 'y');
|
||||
i = ynq("Specify unknown object by cursor?");
|
||||
if (i == 'q') return MOVE_CANCELLED;
|
||||
from_screen = (i == 'y');
|
||||
}
|
||||
|
||||
if (from_screen) {
|
||||
cc.x = u.ux;
|
||||
cc.y = u.uy;
|
||||
sym = 0; /* gcc -Wall lint */
|
||||
} else {
|
||||
getlin("Specify what? (type the word)", out_str);
|
||||
if (out_str[0] == '\0' || out_str[0] == '\033')
|
||||
return MOVE_CANCELLED;
|
||||
sym = 0;
|
||||
} else {
|
||||
getlin("Specify what? (type the word)", out_str);
|
||||
if (out_str[0] == '\0' || out_str[0] == '\033')
|
||||
return MOVE_CANCELLED;
|
||||
|
||||
if (out_str[1]) { /* user typed in a complete string */
|
||||
winid datawin = create_nhwindow(NHW_MENU);
|
||||
// check if they specified a monster
|
||||
int mntmp = NON_PM;
|
||||
if ((mntmp = name_to_mon(out_str)) >= LOW_PM && !is_horror(&mons[mntmp])) {
|
||||
char temp_buf[LONGBUFSZ];
|
||||
strcat(out_str, "\n");
|
||||
temp_buf[0] = '\0';
|
||||
/* create a temporary mtmp to describe */
|
||||
struct monst fake_mon = {0};
|
||||
set_mon_data(&fake_mon, mntmp);
|
||||
get_description_of_monster_type(&fake_mon, temp_buf);
|
||||
(void)strncat(out_str, temp_buf, LONGBUFSZ - strlen(out_str) - 1);
|
||||
pm = &mons[mntmp];
|
||||
char * temp_print;
|
||||
temp_print = strtok(out_str, "\n");
|
||||
while (temp_print != NULL)
|
||||
{
|
||||
putstr(datawin, 0, temp_print);
|
||||
temp_print = strtok(NULL, "\n");
|
||||
if (out_str[1]) { /* user typed in a complete string */
|
||||
winid datawin = create_nhwindow(NHW_MENU);
|
||||
// check if they specified a monster
|
||||
int mntmp = NON_PM;
|
||||
if ((mntmp = name_to_mon(out_str)) >= LOW_PM && !is_horror(&mons[mntmp])) {
|
||||
char temp_buf[LONGBUFSZ];
|
||||
strcat(out_str, "\n");
|
||||
temp_buf[0] = '\0';
|
||||
/* create a temporary mtmp to describe */
|
||||
struct monst fake_mon = {0};
|
||||
set_mon_data(&fake_mon, mntmp);
|
||||
get_description_of_monster_type(&fake_mon, temp_buf);
|
||||
(void)strncat(out_str, temp_buf, LONGBUFSZ - strlen(out_str) - 1);
|
||||
pm = &mons[mntmp];
|
||||
char * temp_print;
|
||||
temp_print = strtok(out_str, "\n");
|
||||
while (temp_print != NULL)
|
||||
{
|
||||
putstr(datawin, 0, temp_print);
|
||||
temp_print = strtok(NULL, "\n");
|
||||
}
|
||||
}
|
||||
// check if they specified an artifact
|
||||
else if ((x_str = artifact_name(out_str, &otyp, &oartifact))) {
|
||||
putstr(datawin, 0, x_str);
|
||||
describe_item(NULL, otyp, oartifact, &datawin);
|
||||
}
|
||||
// check encyclopedia
|
||||
if(checkfile(out_str, pm, (mntmp==NON_PM && otyp==STRANGE_OBJECT), TRUE, &datawin) || mntmp != NON_PM || otyp != STRANGE_OBJECT)
|
||||
display_nhwindow(datawin, TRUE);
|
||||
destroy_nhwindow(datawin);
|
||||
return MOVE_CANCELLED;
|
||||
}
|
||||
// check if they specified an artifact
|
||||
else if ((x_str = artifact_name(out_str, &otyp, &oartifact))) {
|
||||
putstr(datawin, 0, x_str);
|
||||
describe_item(NULL, otyp, oartifact, &datawin);
|
||||
}
|
||||
// check encyclopedia
|
||||
if(checkfile(out_str, pm, (mntmp==NON_PM && otyp==STRANGE_OBJECT), TRUE, &datawin) || mntmp != NON_PM || otyp != STRANGE_OBJECT)
|
||||
display_nhwindow(datawin, TRUE);
|
||||
destroy_nhwindow(datawin);
|
||||
return MOVE_CANCELLED;
|
||||
}
|
||||
sym = out_str[0];
|
||||
sym = out_str[0];
|
||||
}
|
||||
|
||||
/* Save the verbose flag, we change it later. */
|
||||
save_verbose = flags.verbose;
|
||||
flags.verbose = flags.verbose && !quick;
|
||||
/*
|
||||
* The user typed one letter, or we're identifying from the screen.
|
||||
*/
|
||||
do {
|
||||
/* Reset some variables. */
|
||||
need_to_look = FALSE;
|
||||
pm = (struct permonst *)0;
|
||||
skipped_venom = 0;
|
||||
hallu_obj = 0;
|
||||
found = 0;
|
||||
out_str[0] = '\0';
|
||||
|
||||
if (from_screen) {
|
||||
cc.x = u.ux;
|
||||
cc.y = u.uy;
|
||||
int glyph; /* glyph at selected position */
|
||||
|
||||
if (flags.verbose)
|
||||
|
@ -1474,8 +1450,7 @@ do_look(quick)
|
|||
|
||||
ans = getpos(&cc, quick, what_is_an_unknown_object);
|
||||
if (ans < 0 || cc.x < 0) {
|
||||
flags.verbose = save_verbose;
|
||||
return MOVE_CANCELLED; /* done */
|
||||
return MOVE_CANCELLED; /* done */
|
||||
}
|
||||
flags.verbose = FALSE; /* only print long question once */
|
||||
|
||||
|
@ -1513,6 +1488,74 @@ do_look(quick)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The user typed one letter, or we're identifying from the screen.
|
||||
*/
|
||||
do_look_letter(sym, from_screen, quick, force_defsyms, cc, out_str, firstmatch);
|
||||
|
||||
/* Finally, print out our explanation. */
|
||||
if (out_str[0]) {
|
||||
winid datawin = create_nhwindow(NHW_MENU);
|
||||
char * temp_print;
|
||||
temp_print = strtok(out_str, "\n");
|
||||
while (temp_print != NULL)
|
||||
{
|
||||
putstr(datawin, 0, temp_print);
|
||||
temp_print = strtok(NULL, "\n");
|
||||
}
|
||||
/* check the data file for information about this thing */
|
||||
if (ans != LOOK_QUICK && ans != LOOK_ONCE &&
|
||||
(ans == LOOK_VERBOSE || (flags.help && !quick))) {
|
||||
char temp_buf[BUFSZ];
|
||||
Strcpy(temp_buf, level.flags.lethe //lethe
|
||||
&& !strcmp(firstmatch, "water")?
|
||||
"lethe" : firstmatch);
|
||||
(void)checkfile(temp_buf, pm, FALSE, (boolean)(ans == LOOK_VERBOSE), &datawin);
|
||||
}
|
||||
display_nhwindow(datawin, TRUE);
|
||||
destroy_nhwindow(datawin);
|
||||
} else {
|
||||
pline("I've never heard of such things.");
|
||||
}
|
||||
return MOVE_CANCELLED;
|
||||
}
|
||||
|
||||
char*
|
||||
do_look_letter(sym, from_screen, quick, force_defsyms, cc, out_str, firstmatch)
|
||||
glyph_t sym;
|
||||
boolean from_screen;
|
||||
boolean quick;
|
||||
boolean force_defsyms;
|
||||
coord cc;
|
||||
char* out_str;
|
||||
const char* firstmatch;
|
||||
{
|
||||
char look_buf[BUFSZ];
|
||||
const char *x_str = 0;
|
||||
struct permonst *pm = 0;
|
||||
struct monst *mtmp = 0;
|
||||
int i, ans = 0;
|
||||
int found; /* count of matching syms found */
|
||||
boolean save_verbose; /* saved value of flags.verbose */
|
||||
boolean need_to_look; /* need to get explan. from glyph */
|
||||
boolean hit_trap; /* true if found trap explanation */
|
||||
boolean hit_cloud; /* true if found cloud explanation */
|
||||
int skipped_venom; /* non-zero if we ignored "splash of venom" */
|
||||
int hallu_obj; /* non-zero if found hallucinable object */
|
||||
short otyp = STRANGE_OBJECT; /* to pass to artifact_name */
|
||||
static const char *mon_interior = "the interior of a monster";
|
||||
|
||||
save_verbose = flags.verbose;
|
||||
flags.verbose = flags.verbose && !quick;
|
||||
|
||||
do {
|
||||
/* Reset some variables. */
|
||||
need_to_look = FALSE;
|
||||
pm = (struct permonst *)0;
|
||||
skipped_venom = 0;
|
||||
hallu_obj = 0;
|
||||
found = 0;
|
||||
out_str[0] = '\0';
|
||||
/*
|
||||
* Check all the possibilities, saving all explanations in a buffer.
|
||||
* When all have been checked then the string is printed.
|
||||
|
@ -1726,37 +1769,16 @@ do_look(quick)
|
|||
}
|
||||
}
|
||||
|
||||
/* Finally, print out our explanation. */
|
||||
/* Finally, return our explanation. */
|
||||
if (found) {
|
||||
winid datawin = create_nhwindow(NHW_MENU);
|
||||
char * temp_print;
|
||||
temp_print = strtok(out_str, "\n");
|
||||
while (temp_print != NULL)
|
||||
{
|
||||
putstr(datawin, 0, temp_print);
|
||||
temp_print = strtok(NULL, "\n");
|
||||
}
|
||||
/* check the data file for information about this thing */
|
||||
if (found == 1 && ans != LOOK_QUICK && ans != LOOK_ONCE &&
|
||||
(ans == LOOK_VERBOSE || (flags.help && !quick))) {
|
||||
char temp_buf[BUFSZ];
|
||||
Strcpy(temp_buf, level.flags.lethe //lethe
|
||||
&& !strcmp(firstmatch, "water")?
|
||||
"lethe" : firstmatch);
|
||||
(void)checkfile(temp_buf, pm, FALSE, (boolean)(ans == LOOK_VERBOSE), &datawin);
|
||||
}
|
||||
display_nhwindow(datawin, TRUE);
|
||||
destroy_nhwindow(datawin);
|
||||
} else {
|
||||
pline("I've never heard of such things.");
|
||||
return out_str;
|
||||
}
|
||||
|
||||
} while (from_screen && !quick && ans != LOOK_ONCE);
|
||||
|
||||
flags.verbose = save_verbose;
|
||||
return MOVE_CANCELLED;
|
||||
}
|
||||
flags.verbose = save_verbose;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
append(char * buf, int condition, char * text, boolean many)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue