'/' enhancement
Add new entries to the menu used for the '/' command: describe nearby monsters, describe all shown monsters, describe nearby objects, and describe all shown objects. It makes a text window listing monsters-- or objects--currently displayed on the map, showing lines of X r,c monster-or-object description where 'X' is symbol (monster or object class letter for tty), 'r,c' is row and column separated by comma, and description is similar to what using '/y' or ';' manually would provide (how-seen info is omitted when listing monsters). Originally intended for blind players using screen readers to describe what is displayed, but will probably get used by other players too. The map doesn't use a separate set of glyphs for objects which are the tops of piles, so the information that there are additional objects beneath the ones shown isn't available to '/' and ';'. That feels like a bug to me....
This commit is contained in:
+258
-108
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 pager.c $NHDT-Date: 1433572586 2015/06/06 06:36:26 $ $NHDT-Branch: master $:$NHDT-Revision: 1.77 $ */
|
/* NetHack 3.6 pager.c $NHDT-Date: 1436234837 2015/07/07 02:07:17 $ $NHDT-Branch: master $:$NHDT-Revision: 1.78 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -10,9 +10,13 @@
|
|||||||
|
|
||||||
STATIC_DCL boolean FDECL(is_swallow_sym, (int));
|
STATIC_DCL boolean FDECL(is_swallow_sym, (int));
|
||||||
STATIC_DCL int FDECL(append_str, (char *, const char *));
|
STATIC_DCL int FDECL(append_str, (char *, const char *));
|
||||||
|
STATIC_DCL void FDECL(look_at_object, (char *, int, int, int));
|
||||||
|
STATIC_DCL void FDECL(look_at_monster, (char *, char *,
|
||||||
|
struct monst *, int, int));
|
||||||
STATIC_DCL struct permonst *FDECL(lookat, (int, int, char *, char *));
|
STATIC_DCL struct permonst *FDECL(lookat, (int, int, char *, char *));
|
||||||
STATIC_DCL void FDECL(checkfile,
|
STATIC_DCL void FDECL(checkfile, (char *, struct permonst *,
|
||||||
(char *, struct permonst *, BOOLEAN_P, BOOLEAN_P));
|
BOOLEAN_P, BOOLEAN_P));
|
||||||
|
STATIC_DCL void FDECL(look_all, (BOOLEAN_P,BOOLEAN_P));
|
||||||
STATIC_DCL boolean FDECL(help_menu, (int *));
|
STATIC_DCL boolean FDECL(help_menu, (int *));
|
||||||
#ifdef PORT_HELP
|
#ifdef PORT_HELP
|
||||||
extern void NDECL(port_help);
|
extern void NDECL(port_help);
|
||||||
@@ -112,67 +116,43 @@ struct obj **obj_p;
|
|||||||
return fakeobj; /* when True, caller needs to dealloc *obj_p */
|
return fakeobj; /* when True, caller needs to dealloc *obj_p */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
STATIC_OVL void
|
||||||
* Return the name of the glyph found at (x,y).
|
look_at_object(buf, x, y, glyph)
|
||||||
* If not hallucinating and the glyph is a monster, also monster data.
|
char *buf; /* output buffer */
|
||||||
*/
|
int x, y, glyph;
|
||||||
STATIC_OVL struct permonst *
|
|
||||||
lookat(x, y, buf, monbuf)
|
|
||||||
int x, y;
|
|
||||||
char *buf, *monbuf;
|
|
||||||
{
|
{
|
||||||
register struct monst *mtmp = (struct monst *) 0;
|
struct obj *otmp = 0;
|
||||||
struct permonst *pm = (struct permonst *) 0;
|
boolean fakeobj = object_from_map(glyph, x, y, &otmp);
|
||||||
int glyph;
|
|
||||||
|
|
||||||
buf[0] = monbuf[0] = 0;
|
if (otmp) {
|
||||||
glyph = glyph_at(x, y);
|
Strcpy(buf, (otmp->otyp != STRANGE_OBJECT)
|
||||||
if (u.ux == x && u.uy == y && canspotself()) {
|
? distant_name(otmp, xname)
|
||||||
/* fill in buf[] */
|
: obj_descr[STRANGE_OBJECT].oc_name);
|
||||||
(void) self_lookat(buf);
|
if (fakeobj)
|
||||||
|
dealloc_obj(otmp), otmp = 0;
|
||||||
|
} else
|
||||||
|
Strcpy(buf, something); /* sanity precaution */
|
||||||
|
|
||||||
/* file lookup can't distinguish between "gnomish wizard" monster
|
if (levl[x][y].typ == STONE || levl[x][y].typ == SCORR)
|
||||||
and correspondingly named player character, always picking the
|
Strcat(buf, " embedded in stone");
|
||||||
former; force it to find the general "wizard" entry instead */
|
else if (IS_WALL(levl[x][y].typ) || levl[x][y].typ == SDOOR)
|
||||||
if (Role_if(PM_WIZARD) && Race_if(PM_GNOME) && !Upolyd)
|
Strcat(buf, " embedded in a wall");
|
||||||
pm = &mons[PM_WIZARD];
|
else if (closed_door(x, y))
|
||||||
|
Strcat(buf, " embedded in a door");
|
||||||
|
else if (is_pool(x, y))
|
||||||
|
Strcat(buf, " in water");
|
||||||
|
else if (is_lava(x, y))
|
||||||
|
Strcat(buf, " in molten lava"); /* [can this ever happen?] */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* When you see yourself normally, no explanation is appended
|
STATIC_OVL void
|
||||||
(even if you could also see yourself via other means).
|
look_at_monster(buf, monbuf, mtmp, x, y)
|
||||||
Sensing self while blind or swallowed is treated as if it
|
char *buf, *monbuf; /* buf: output, monbuf: optional output */
|
||||||
were by normal vision (cf canseeself()). */
|
struct monst *mtmp;
|
||||||
if ((Invisible || u.uundetected) && !Blind && !u.uswallow) {
|
int x, y;
|
||||||
unsigned how = 0;
|
{
|
||||||
|
|
||||||
if (Infravision)
|
|
||||||
how |= 1;
|
|
||||||
if (Unblind_telepat)
|
|
||||||
how |= 2;
|
|
||||||
if (Detect_monsters)
|
|
||||||
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" : "");
|
|
||||||
}
|
|
||||||
} else if (u.uswallow) {
|
|
||||||
/* all locations when swallowed other than the hero are the monster */
|
|
||||||
Sprintf(buf, "interior of %s",
|
|
||||||
Blind ? "a monster" : a_monnam(u.ustuck));
|
|
||||||
pm = u.ustuck->data;
|
|
||||||
} else if (glyph_is_monster(glyph)) {
|
|
||||||
bhitpos.x = x;
|
|
||||||
bhitpos.y = y;
|
|
||||||
mtmp = m_at(x, y);
|
|
||||||
if (mtmp) {
|
|
||||||
char *name, monnambuf[BUFSZ];
|
char *name, monnambuf[BUFSZ];
|
||||||
unsigned how_seen;
|
|
||||||
boolean accurate = !Hallucination;
|
boolean accurate = !Hallucination;
|
||||||
|
|
||||||
if (mtmp->data == &mons[PM_COYOTE] && accurate)
|
if (mtmp->data == &mons[PM_COYOTE] && accurate)
|
||||||
@@ -180,20 +160,19 @@ char *buf, *monbuf;
|
|||||||
else
|
else
|
||||||
name = distant_monnam(mtmp, ARTICLE_NONE, monnambuf);
|
name = distant_monnam(mtmp, ARTICLE_NONE, monnambuf);
|
||||||
|
|
||||||
pm = mtmp->data;
|
Sprintf(buf, "%s%s%s",
|
||||||
Sprintf(
|
|
||||||
buf, "%s%s%s",
|
|
||||||
(mtmp->mx != x || mtmp->my != y)
|
(mtmp->mx != x || mtmp->my != y)
|
||||||
? ((mtmp->isshk && accurate) ? "tail of " : "tail of a ")
|
? ((mtmp->isshk && accurate) ? "tail of " : "tail of a ")
|
||||||
: "",
|
: "",
|
||||||
(mtmp->mtame && accurate)
|
(mtmp->mtame && accurate)
|
||||||
? "tame "
|
? "tame "
|
||||||
: (mtmp->mpeaceful && accurate) ? "peaceful " : "",
|
: (mtmp->mpeaceful && accurate)
|
||||||
|
? "peaceful "
|
||||||
|
: "",
|
||||||
name);
|
name);
|
||||||
if (u.ustuck == mtmp)
|
if (u.ustuck == mtmp)
|
||||||
Strcat(buf, (Upolyd && sticks(youmonst.data))
|
Strcat(buf, (Upolyd && sticks(youmonst.data))
|
||||||
? ", being held"
|
? ", being held" : ", holding you");
|
||||||
: ", holding you");
|
|
||||||
if (mtmp->mleashed)
|
if (mtmp->mleashed)
|
||||||
Strcat(buf, ", leashed to you");
|
Strcat(buf, ", leashed to you");
|
||||||
|
|
||||||
@@ -202,14 +181,16 @@ char *buf, *monbuf;
|
|||||||
int tt = t ? t->ttyp : NO_TRAP;
|
int tt = t ? t->ttyp : NO_TRAP;
|
||||||
|
|
||||||
/* newsym lets you know of the trap, so mention it here */
|
/* newsym lets you know of the trap, so mention it here */
|
||||||
if (tt == BEAR_TRAP || tt == PIT || tt == SPIKED_PIT
|
if (tt == BEAR_TRAP || tt == PIT || tt == SPIKED_PIT || tt == WEB)
|
||||||
|| tt == WEB)
|
|
||||||
Sprintf(eos(buf), ", trapped in %s",
|
Sprintf(eos(buf), ", trapped in %s",
|
||||||
an(defsyms[trap_to_defsym(tt)].explanation));
|
an(defsyms[trap_to_defsym(tt)].explanation));
|
||||||
}
|
}
|
||||||
|
|
||||||
how_seen = howmonseen(mtmp);
|
if (monbuf) {
|
||||||
if (how_seen && how_seen != MONSEEN_NORMAL) {
|
unsigned how_seen = howmonseen(mtmp);
|
||||||
|
|
||||||
|
monbuf[0] = '\0';
|
||||||
|
if (how_seen != 0 && how_seen != MONSEEN_NORMAL) {
|
||||||
if (how_seen & MONSEEN_NORMAL) {
|
if (how_seen & MONSEEN_NORMAL) {
|
||||||
Strcat(monbuf, "normal vision");
|
Strcat(monbuf, "normal vision");
|
||||||
how_seen &= ~MONSEEN_NORMAL;
|
how_seen &= ~MONSEEN_NORMAL;
|
||||||
@@ -264,30 +245,72 @@ char *buf, *monbuf;
|
|||||||
Sprintf(eos(monbuf), "(%u)", how_seen);
|
Sprintf(eos(monbuf), "(%u)", how_seen);
|
||||||
}
|
}
|
||||||
} /* seen by something other than normal vision */
|
} /* seen by something other than normal vision */
|
||||||
} /* mtmp */
|
} /* monbuf is non-null */
|
||||||
|
}
|
||||||
|
|
||||||
} else if (glyph_is_object(glyph)) {
|
/*
|
||||||
struct obj *otmp = 0;
|
* Return the name of the glyph found at (x,y).
|
||||||
boolean fakeobj = object_from_map(glyph, x, y, &otmp);
|
* If not hallucinating and the glyph is a monster, also monster data.
|
||||||
|
*/
|
||||||
|
STATIC_OVL struct permonst *
|
||||||
|
lookat(x, y, buf, monbuf)
|
||||||
|
int x, y;
|
||||||
|
char *buf, *monbuf;
|
||||||
|
{
|
||||||
|
register struct monst *mtmp = (struct monst *) 0;
|
||||||
|
struct permonst *pm = (struct permonst *) 0;
|
||||||
|
int glyph;
|
||||||
|
|
||||||
if (otmp) {
|
buf[0] = monbuf[0] = '\0';
|
||||||
Strcpy(buf, (otmp->otyp != STRANGE_OBJECT)
|
glyph = glyph_at(x, y);
|
||||||
? distant_name(otmp, xname)
|
if (u.ux == x && u.uy == y && canspotself()) {
|
||||||
: obj_descr[STRANGE_OBJECT].oc_name);
|
/* fill in buf[] */
|
||||||
if (fakeobj)
|
(void) self_lookat(buf);
|
||||||
dealloc_obj(otmp), otmp = 0;
|
|
||||||
|
/* file lookup can't distinguish between "gnomish wizard" monster
|
||||||
|
and correspondingly named player character, always picking the
|
||||||
|
former; force it to find the general "wizard" entry instead */
|
||||||
|
if (Role_if(PM_WIZARD) && Race_if(PM_GNOME) && !Upolyd)
|
||||||
|
pm = &mons[PM_WIZARD];
|
||||||
|
|
||||||
|
/* When you see yourself normally, no explanation is appended
|
||||||
|
(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) {
|
||||||
|
unsigned how = 0;
|
||||||
|
|
||||||
|
if (Infravision)
|
||||||
|
how |= 1;
|
||||||
|
if (Unblind_telepat)
|
||||||
|
how |= 2;
|
||||||
|
if (Detect_monsters)
|
||||||
|
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" : "");
|
||||||
}
|
}
|
||||||
|
} else if (u.uswallow) {
|
||||||
if (levl[x][y].typ == STONE || levl[x][y].typ == SCORR)
|
/* all locations when swallowed other than the hero are the monster */
|
||||||
Strcat(buf, " embedded in stone");
|
Sprintf(buf, "interior of %s",
|
||||||
else if (IS_WALL(levl[x][y].typ) || levl[x][y].typ == SDOOR)
|
Blind ? "a monster" : a_monnam(u.ustuck));
|
||||||
Strcat(buf, " embedded in a wall");
|
pm = u.ustuck->data;
|
||||||
else if (closed_door(x, y))
|
} else if (glyph_is_monster(glyph)) {
|
||||||
Strcat(buf, " embedded in a door");
|
bhitpos.x = x;
|
||||||
else if (is_pool(x, y))
|
bhitpos.y = y;
|
||||||
Strcat(buf, " in water");
|
if ((mtmp = m_at(x, y)) != 0) {
|
||||||
else if (is_lava(x, y))
|
look_at_monster(buf, monbuf, mtmp, x, y);
|
||||||
Strcat(buf, " in molten lava"); /* [can this ever happen?] */
|
pm = mtmp->data;
|
||||||
|
}
|
||||||
|
} else if (glyph_is_object(glyph)) {
|
||||||
|
look_at_object(buf, x, y, glyph); /* fill in buf[] */
|
||||||
} else if (glyph_is_trap(glyph)) {
|
} else if (glyph_is_trap(glyph)) {
|
||||||
int tnum = what_trap(glyph_to_trap(glyph));
|
int tnum = what_trap(glyph_to_trap(glyph));
|
||||||
Strcpy(buf, defsyms[trap_to_defsym(tnum)].explanation);
|
Strcpy(buf, defsyms[trap_to_defsym(tnum)].explanation);
|
||||||
@@ -758,8 +781,7 @@ do_look(mode, click_cc)
|
|||||||
int mode;
|
int mode;
|
||||||
coord *click_cc;
|
coord *click_cc;
|
||||||
{
|
{
|
||||||
boolean quick =
|
boolean quick = (mode == 1); /* use cursor; don't search for "more info" */
|
||||||
(mode == 1); /* use cursor && don't search for "more info" */
|
|
||||||
boolean clicklook = (mode == 2); /* right mouse-click method */
|
boolean clicklook = (mode == 2); /* right mouse-click method */
|
||||||
char out_str[BUFSZ];
|
char out_str[BUFSZ];
|
||||||
const char *firstmatch = 0;
|
const char *firstmatch = 0;
|
||||||
@@ -781,21 +803,50 @@ coord *click_cc;
|
|||||||
menu_item *pick_list = (menu_item *) 0;
|
menu_item *pick_list = (menu_item *) 0;
|
||||||
winid win;
|
winid win;
|
||||||
anything any;
|
anything any;
|
||||||
|
|
||||||
|
any = zeroany;
|
||||||
win = create_nhwindow(NHW_MENU);
|
win = create_nhwindow(NHW_MENU);
|
||||||
start_menu(win);
|
start_menu(win);
|
||||||
any.a_void = 0;
|
any.a_char = '/';
|
||||||
any.a_char = 'a';
|
/* 'y' and 'n' to keep backwards compatability with previous
|
||||||
/* 'y' and 'n' to keep backwards compat with previous versions */
|
versions: "Specify unknown object by cursor?" */
|
||||||
add_menu(win, NO_GLYPH, &any, 'a', 'y', ATR_NONE,
|
add_menu(win, NO_GLYPH, &any,
|
||||||
|
flags.lootabc ? 0 : any.a_char, 'y', ATR_NONE,
|
||||||
"something on the map", MENU_UNSELECTED);
|
"something on the map", MENU_UNSELECTED);
|
||||||
any.a_void = 0;
|
any.a_char = 'i';
|
||||||
any.a_char = 'b';
|
add_menu(win, NO_GLYPH, &any,
|
||||||
add_menu(win, NO_GLYPH, &any, 'b', 0, ATR_NONE,
|
flags.lootabc ? 0 : any.a_char, 0, ATR_NONE,
|
||||||
"something you're carrying", MENU_UNSELECTED);
|
"something you're carrying", MENU_UNSELECTED);
|
||||||
any.a_void = 0;
|
any.a_char = '?';
|
||||||
any.a_char = 'c';
|
add_menu(win, NO_GLYPH, &any,
|
||||||
add_menu(win, NO_GLYPH, &any, 'c', 'n', ATR_NONE,
|
flags.lootabc ? 0 : any.a_char, 'n', ATR_NONE,
|
||||||
"something else", MENU_UNSELECTED);
|
"something else (by symbol or name)", MENU_UNSELECTED);
|
||||||
|
if (!u.uswallow && !Hallucination) {
|
||||||
|
any = zeroany;
|
||||||
|
add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE,
|
||||||
|
"", MENU_UNSELECTED);
|
||||||
|
/* these options work sensibly for the swallowed case,
|
||||||
|
but there's no reason for the player to use them then;
|
||||||
|
objects work fine when hallucinating, but screen
|
||||||
|
symbol/monster class letter doesn't match up with
|
||||||
|
bogus monster type, so suppress when hallucinating */
|
||||||
|
any.a_char = 'm';
|
||||||
|
add_menu(win, NO_GLYPH, &any,
|
||||||
|
flags.lootabc ? 0 : any.a_char, 0, ATR_NONE,
|
||||||
|
"nearby monsters", MENU_UNSELECTED);
|
||||||
|
any.a_char = 'M';
|
||||||
|
add_menu(win, NO_GLYPH, &any,
|
||||||
|
flags.lootabc ? 0 : any.a_char, 0, ATR_NONE,
|
||||||
|
"all monsters shown on map", MENU_UNSELECTED);
|
||||||
|
any.a_char = 'o';
|
||||||
|
add_menu(win, NO_GLYPH, &any,
|
||||||
|
flags.lootabc ? 0 : any.a_char, 0, ATR_NONE,
|
||||||
|
"nearby objects", MENU_UNSELECTED);
|
||||||
|
any.a_char = 'O';
|
||||||
|
add_menu(win, NO_GLYPH, &any,
|
||||||
|
flags.lootabc ? 0 : any.a_char, 0, ATR_NONE,
|
||||||
|
"all objects shown on map", MENU_UNSELECTED);
|
||||||
|
}
|
||||||
end_menu(win, "What do you want to look at:");
|
end_menu(win, "What do you want to look at:");
|
||||||
if (select_menu(win, PICK_ONE, &pick_list) > 0) {
|
if (select_menu(win, PICK_ONE, &pick_list) > 0) {
|
||||||
i = pick_list->item.a_char;
|
i = pick_list->item.a_char;
|
||||||
@@ -809,17 +860,18 @@ coord *click_cc;
|
|||||||
case 'q':
|
case 'q':
|
||||||
return 0;
|
return 0;
|
||||||
case 'y':
|
case 'y':
|
||||||
case 'a':
|
case '/':
|
||||||
from_screen = TRUE;
|
from_screen = TRUE;
|
||||||
sym = 0;
|
sym = 0;
|
||||||
cc.x = u.ux;
|
cc.x = u.ux;
|
||||||
cc.y = u.uy;
|
cc.y = u.uy;
|
||||||
break;
|
break;
|
||||||
case 'b': {
|
case 'i':
|
||||||
|
{
|
||||||
char invlet;
|
char invlet;
|
||||||
struct obj *invobj;
|
struct obj *invobj;
|
||||||
|
|
||||||
invlet = display_inventory(NULL, TRUE);
|
invlet = display_inventory((const char *) 0, TRUE);
|
||||||
if (!invlet || invlet == '\033')
|
if (!invlet || invlet == '\033')
|
||||||
return 0;
|
return 0;
|
||||||
*out_str = '\0';
|
*out_str = '\0';
|
||||||
@@ -831,8 +883,8 @@ coord *click_cc;
|
|||||||
if (*out_str)
|
if (*out_str)
|
||||||
checkfile(out_str, pm, TRUE, TRUE);
|
checkfile(out_str, pm, TRUE, TRUE);
|
||||||
return 0;
|
return 0;
|
||||||
} break;
|
}
|
||||||
case 'c':
|
case '?':
|
||||||
from_screen = FALSE;
|
from_screen = FALSE;
|
||||||
getlin("Specify what? (type the word)", out_str);
|
getlin("Specify what? (type the word)", out_str);
|
||||||
if (out_str[0] == '\0' || out_str[0] == '\033')
|
if (out_str[0] == '\0' || out_str[0] == '\033')
|
||||||
@@ -844,6 +896,18 @@ coord *click_cc;
|
|||||||
}
|
}
|
||||||
sym = out_str[0];
|
sym = out_str[0];
|
||||||
break;
|
break;
|
||||||
|
case 'm':
|
||||||
|
look_all(TRUE, TRUE); /* list nearby monsters */
|
||||||
|
return 0;
|
||||||
|
case 'M':
|
||||||
|
look_all(FALSE, TRUE); /* list all monsters */
|
||||||
|
return 0;
|
||||||
|
case 'o':
|
||||||
|
look_all(TRUE, FALSE); /* list nearby objects */
|
||||||
|
return 0;
|
||||||
|
case 'O':
|
||||||
|
look_all(FALSE, FALSE); /* list all objects */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
} else { /* clicklook */
|
} else { /* clicklook */
|
||||||
cc.x = click_cc->x;
|
cc.x = click_cc->x;
|
||||||
@@ -909,6 +973,92 @@ coord *click_cc;
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC_OVL void
|
||||||
|
look_all(nearby, do_mons)
|
||||||
|
boolean nearby; /* True => within BOLTLIM, False => entire map */
|
||||||
|
boolean do_mons; /* True => monsters, False => objects */
|
||||||
|
{
|
||||||
|
winid win;
|
||||||
|
int x, y, lo_x, lo_y, hi_x, hi_y, glyph, count = 0;
|
||||||
|
char buf[BUFSZ], outbuf[BUFSZ], coordbuf[12], fmt[12]; /* "%02d,%02d" */
|
||||||
|
|
||||||
|
/* row,column orientation rather than cartesian x,y */
|
||||||
|
Sprintf(fmt, "%%%sd,%%%sd",
|
||||||
|
(ROWNO <= 100) ? "02" : (ROWNO <= 1000) ? "03" : "",
|
||||||
|
(COLNO <= 100) ? "02" : (COLNO <= 1000) ? "03" : "");
|
||||||
|
|
||||||
|
win = create_nhwindow(NHW_TEXT);
|
||||||
|
lo_y = nearby ? max(u.uy - BOLT_LIM, 0) : 0;
|
||||||
|
lo_x = nearby ? max(u.ux - BOLT_LIM, 1) : 1;
|
||||||
|
hi_y = nearby ? min(u.uy + BOLT_LIM, ROWNO - 1) : ROWNO - 1;
|
||||||
|
hi_x = nearby ? min(u.ux + BOLT_LIM, COLNO - 1) : COLNO - 1;
|
||||||
|
for (y = lo_y; y <= hi_y; y++) {
|
||||||
|
for (x = lo_x; x <= hi_x; x++) {
|
||||||
|
buf[0] = '\0';
|
||||||
|
glyph = glyph_at(x, y);
|
||||||
|
if (do_mons) {
|
||||||
|
if (glyph_is_monster(glyph)) {
|
||||||
|
struct monst *mtmp;
|
||||||
|
|
||||||
|
bhitpos.x = x; /* [is this actually necessary?] */
|
||||||
|
bhitpos.y = y;
|
||||||
|
if (x == u.ux && y == u.uy && canspotself()) {
|
||||||
|
(void) self_lookat(buf);
|
||||||
|
++count;
|
||||||
|
} else if ((mtmp = m_at(x, y)) != 0) {
|
||||||
|
look_at_monster(buf, (char *) 0, mtmp, x, y);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
} else if (glyph_is_invisible(glyph)) {
|
||||||
|
/* remembered, unseen, creature */
|
||||||
|
Strcpy(buf, invisexplain);
|
||||||
|
++count;
|
||||||
|
} else if (glyph_is_warning(glyph)) {
|
||||||
|
int warnindx = glyph_to_warning(glyph);
|
||||||
|
|
||||||
|
Strcpy(buf, def_warnsyms[warnindx].explanation);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
} else { /* !do_mons */
|
||||||
|
if (glyph_is_object(glyph)) {
|
||||||
|
look_at_object(buf, x, y, glyph);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*buf) {
|
||||||
|
if (count == 1) {
|
||||||
|
char which[12];
|
||||||
|
|
||||||
|
Strcpy(which, do_mons ? "monsters" : "objects");
|
||||||
|
if (nearby) {
|
||||||
|
Sprintf(coordbuf, fmt, u.uy, u.ux);
|
||||||
|
Sprintf(outbuf, "%s currently shown near %s:",
|
||||||
|
upstart(which), coordbuf);
|
||||||
|
} else
|
||||||
|
Sprintf(outbuf, "All %s currently shown on the map:",
|
||||||
|
which);
|
||||||
|
putstr(win, 0, outbuf);
|
||||||
|
putstr(win, 0, "");
|
||||||
|
}
|
||||||
|
Sprintf(coordbuf, fmt, y, x);
|
||||||
|
/* prefix: "C row,column " */
|
||||||
|
Sprintf(outbuf, "%s %s ", encglyph(glyph), coordbuf);
|
||||||
|
/* guard against potential overflow */
|
||||||
|
buf[sizeof buf - 1 - strlen(outbuf)] = '\0';
|
||||||
|
Strcat(outbuf, buf);
|
||||||
|
putmixed(win, 0, outbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count)
|
||||||
|
display_nhwindow(win, TRUE);
|
||||||
|
else
|
||||||
|
pline("No %s are currently shown %s.",
|
||||||
|
do_mons ? "monsters" : "objects",
|
||||||
|
nearby ? "nearby" : "on the map");
|
||||||
|
destroy_nhwindow(win);
|
||||||
|
}
|
||||||
|
|
||||||
/* the '/' command */
|
/* the '/' command */
|
||||||
int
|
int
|
||||||
dowhatis()
|
dowhatis()
|
||||||
|
|||||||
Reference in New Issue
Block a user