Accessibility: Show a message when monster is spotted
Adds a new boolean option, spot_monsters. If on, every time the hero notices a monster which was out of sight before, a message is given. Combine with accessiblemsg to get the monster location: (3north): You see a newt. Breaks saves and bones.
This commit is contained in:
@@ -4650,6 +4650,8 @@ Allow sounds to be emitted from an integrated sound library (default on).
|
||||
Display a sparkly effect when a monster (including yourself) is hit by an
|
||||
attack to which it is resistant (default on).
|
||||
Persistent.
|
||||
.lp spot_monsters
|
||||
Show a message when hero notices a monster (default is off).
|
||||
.lp standout
|
||||
Boldface monsters and \(lq\fB\-\-More\-\-\fP\(rq (default off).
|
||||
Persistent.
|
||||
@@ -5938,6 +5940,8 @@ Rogue-like commands.
|
||||
Prevent walking into water or lava.
|
||||
.lp accessiblemsg
|
||||
Adds direction or location information to messages.
|
||||
.lp spot_monsters
|
||||
Shows a message when hero notices a monster; combine with accessiblemsg.
|
||||
.lp autodescribe
|
||||
Automatically describe the terrain under the cursor when targeting.
|
||||
.lp mention_walls
|
||||
|
||||
@@ -5092,6 +5092,9 @@ Allow sounds to be emitted from an integrated sound library (default on).
|
||||
Display a sparkly effect when a monster (including yourself) is hit by an
|
||||
attack to which it is resistant (default on). Persistent.
|
||||
%.lp
|
||||
\item[\ib{spot\verb+_+monsters}]
|
||||
Show a message when hero notices a monster (default is off).
|
||||
%.lp
|
||||
\item[\ib{standout}]
|
||||
Boldface monsters and ``{\tt --More--}'' (default off). Persistent.
|
||||
%.lp
|
||||
@@ -6535,6 +6538,9 @@ Prevent walking into water or lava.
|
||||
\item[\ib{accessiblemsg}]
|
||||
Adds direction or location information to messages.
|
||||
%.lp
|
||||
\item[\ib{spot\verb+_+monsters}]
|
||||
Shows a message when hero notices a monster; combine with accessiblemsg.
|
||||
%.lp
|
||||
\item[\ib{autodescribe}]
|
||||
Automatically describe the terrain under the cursor when targeting.
|
||||
%.lp
|
||||
|
||||
@@ -1074,6 +1074,8 @@ extern boolean test_move(coordxy, coordxy, coordxy, coordxy, int);
|
||||
extern int wiz_debug_cmd_traveldisplay(void);
|
||||
#endif
|
||||
extern boolean u_rooted(void);
|
||||
extern void notice_mon(struct monst *) NONNULLARG1;
|
||||
extern void notice_all_mons(boolean);
|
||||
extern void impact_disturbs_zombies(struct obj *, boolean) NONNULLARG1;
|
||||
extern void disturb_buried_zombies(coordxy, coordxy);
|
||||
extern boolean u_maybe_impaired(void);
|
||||
|
||||
@@ -191,8 +191,20 @@ struct debug_flags {
|
||||
struct accessibility_data {
|
||||
boolean accessiblemsg; /* use msg_loc for plined messages */
|
||||
coord msg_loc; /* accessiblemsg: location */
|
||||
boolean mon_notices; /* msg when hero notices a monster */
|
||||
int mon_notices_blocked; /* temp disable mon_notices */
|
||||
};
|
||||
|
||||
/* Use notice_mon_off() / notice_mon_on() to temporarily disable
|
||||
noticing the monsters in the vision code - perhaps the game
|
||||
needs to output some other messages in between.
|
||||
Call notice_all_mons() afterwards to catch up. */
|
||||
#define notice_mon_off() do { a11y.mon_notices_blocked++; } while(0)
|
||||
#define notice_mon_on() do { if (--a11y.mon_notices_blocked < 0) { \
|
||||
impossible("mon_notices_blocked<0"); \
|
||||
a11y.mon_notices_blocked = 0; \
|
||||
} } while(0)
|
||||
|
||||
/*
|
||||
* Stuff that really isn't option or platform related and does not
|
||||
* get saved and restored. They are set and cleared during the game
|
||||
|
||||
@@ -160,6 +160,8 @@ struct monst {
|
||||
Bitfield(mtemplit, 1); /* temporarily seen; only valid during bhit() */
|
||||
Bitfield(meverseen, 1); /* mon has been seen at some point */
|
||||
|
||||
Bitfield(mspotted, 1); /* mon is currently seen by hero */
|
||||
|
||||
#define MAX_NUM_WORMS 32 /* should be 2^(wormno bitfield size) */
|
||||
|
||||
unsigned long mstrategy; /* for monsters with mflag3: current strategy */
|
||||
|
||||
@@ -654,6 +654,9 @@ static int optfn_##a(int, int, boolean, char *, char *);
|
||||
NHOPTB(sparkle, Map, 0, opt_out, set_in_game,
|
||||
On, Yes, No, No, NoAlias, &flags.sparkle, Term_False,
|
||||
"display sparkly effect when resisting magic")
|
||||
NHOPTB(spot_monsters, Advanced, 0, opt_in, set_in_game,
|
||||
Off, Yes, No, No, NoAlias, &a11y.mon_notices, Term_False,
|
||||
"message when hero spots a monster")
|
||||
NHOPTB(splash_screen, Advanced, 0, opt_out, set_in_config,
|
||||
On, Yes, No, No, NoAlias, &iflags.wc_splash_screen, Term_False,
|
||||
(char *)0)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Incrementing EDITLEVEL can be used to force invalidation of old bones
|
||||
* and save files.
|
||||
*/
|
||||
#define EDITLEVEL 96
|
||||
#define EDITLEVEL 97
|
||||
|
||||
/*
|
||||
* Development status possibilities.
|
||||
|
||||
@@ -705,6 +705,8 @@ newgame(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* make sure welcome messages are given before noticing monsters */
|
||||
notice_mon_off();
|
||||
disp.botlx = TRUE;
|
||||
gc.context.ident = 1;
|
||||
gc.context.warnlevel = 1;
|
||||
@@ -765,6 +767,8 @@ newgame(void)
|
||||
|
||||
/* Success! */
|
||||
welcome(TRUE);
|
||||
notice_mon_on(); /* now we can notice monsters */
|
||||
notice_all_mons(TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
3
src/do.c
3
src/do.c
@@ -1807,6 +1807,7 @@ goto_level(
|
||||
/* Reset the screen. */
|
||||
vision_reset(); /* reset the blockages */
|
||||
reset_glyphmap(gm_levelchange);
|
||||
notice_mon_off(); /* not noticing monsters yet! */
|
||||
docrt(); /* does a full vision recalc */
|
||||
flush_screen(-1);
|
||||
|
||||
@@ -1923,6 +1924,8 @@ goto_level(
|
||||
#ifdef INSURANCE
|
||||
save_currentstate();
|
||||
#endif
|
||||
notice_mon_on();
|
||||
notice_all_mons(TRUE);
|
||||
|
||||
print_level_annotation();
|
||||
/* give room entrance message, if any */
|
||||
|
||||
75
src/hack.c
75
src/hack.c
@@ -12,6 +12,7 @@ static int moverock(void);
|
||||
static void dosinkfall(void);
|
||||
static boolean findtravelpath(int);
|
||||
static boolean trapmove(coordxy, coordxy, struct trap *);
|
||||
static int QSORTCALLBACK notice_mons_cmp(const genericptr, const genericptr);
|
||||
static schar u_simple_floortyp(coordxy, coordxy);
|
||||
static boolean swim_move_danger(coordxy, coordxy);
|
||||
static boolean domove_bump_mon(struct monst *, int) NONNULLARG1;
|
||||
@@ -1601,6 +1602,80 @@ u_rooted(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
notice_mon(struct monst *mtmp)
|
||||
{
|
||||
if (a11y.mon_notices && !a11y.mon_notices_blocked) {
|
||||
boolean spot = canspotmon(mtmp)
|
||||
&& !(is_hider(mtmp->data)
|
||||
&& (mtmp->mundetected
|
||||
|| M_AP_TYPE(mtmp) == M_AP_FURNITURE
|
||||
|| M_AP_TYPE(mtmp) == M_AP_OBJECT));
|
||||
|
||||
if (spot && !mtmp->mspotted && !DEADMONSTER(mtmp)) {
|
||||
mtmp->mspotted = TRUE;
|
||||
set_msg_xy(mtmp->mx, mtmp->my);
|
||||
You("%s %s.", canseemon(mtmp) ? "see" : "notice",
|
||||
x_monnam(mtmp,
|
||||
mtmp->mtame ? ARTICLE_YOUR
|
||||
: (!has_mgivenname(mtmp)
|
||||
&& !type_is_pname(mtmp->data)) ? ARTICLE_A
|
||||
: ARTICLE_NONE,
|
||||
(mtmp->mpeaceful && !mtmp->mtame) ? "peaceful" : 0,
|
||||
has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE));
|
||||
} else if (!spot) {
|
||||
mtmp->mspotted = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int QSORTCALLBACK
|
||||
notice_mons_cmp(const genericptr ptr1, const genericptr ptr2)
|
||||
{
|
||||
const struct monst *m1 = *(const struct monst **) ptr1,
|
||||
*m2 = *(const struct monst **) ptr2;
|
||||
|
||||
return (distu(m1->mx, m1->my) - distu(m2->mx, m2->my));
|
||||
}
|
||||
|
||||
void
|
||||
notice_all_mons(boolean reset)
|
||||
{
|
||||
if (a11y.mon_notices && !a11y.mon_notices_blocked) {
|
||||
struct monst *mtmp;
|
||||
struct monst **arr = NULL;
|
||||
int i = 0, cnt = 0;
|
||||
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
|
||||
if (canspotmon(mtmp))
|
||||
cnt++;
|
||||
else if (reset)
|
||||
mtmp->mspotted = FALSE;
|
||||
|
||||
if (!cnt)
|
||||
return;
|
||||
|
||||
arr = (struct monst **) alloc(cnt * sizeof(struct monst *));
|
||||
|
||||
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (!canspotmon(mtmp))
|
||||
mtmp->mspotted = FALSE;
|
||||
else if (!DEADMONSTER(mtmp) && i < cnt)
|
||||
arr[i++] = mtmp;
|
||||
}
|
||||
|
||||
if (i) {
|
||||
qsort((genericptr_t) arr, (size_t) i, sizeof *arr, notice_mons_cmp);
|
||||
|
||||
for (i = 0; i < cnt; i++)
|
||||
notice_mon(arr[i]);
|
||||
}
|
||||
|
||||
free(arr);
|
||||
}
|
||||
}
|
||||
|
||||
/* maybe disturb buried zombies when an object is dropped or thrown nearby */
|
||||
void
|
||||
impact_disturbs_zombies(struct obj *obj, boolean violent)
|
||||
|
||||
@@ -1307,6 +1307,8 @@ postmov(
|
||||
boolean canseeit = cansee(mtmp->mx, mtmp->my),
|
||||
didseeit = canseeit;
|
||||
|
||||
notice_mon(mtmp);
|
||||
|
||||
if (mmoved == MMOVE_MOVED) {
|
||||
nix = mtmp->mx, niy = mtmp->my;
|
||||
/* sequencing issue: when monster movement decides that a
|
||||
|
||||
@@ -513,6 +513,7 @@ teleds(coordxy nux, coordxy nuy, int teleds_flags)
|
||||
see_monsters();
|
||||
gv.vision_full_recalc = 1;
|
||||
nomul(0);
|
||||
notice_mon_off();
|
||||
vision_recalc(0); /* vision before effects */
|
||||
|
||||
/* this used to take place sooner, but if a --More-- prompt was issued
|
||||
@@ -542,6 +543,8 @@ teleds(coordxy nux, coordxy nuy, int teleds_flags)
|
||||
/* possible shop entry message comes after guard's shrill whistle */
|
||||
spoteffects(TRUE);
|
||||
invocation_message();
|
||||
notice_mon_on();
|
||||
notice_all_mons(TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -837,6 +837,8 @@ vision_recalc(int control)
|
||||
/* Set the new min and max pointers. */
|
||||
gv.viz_rmin = next_rmin;
|
||||
gv.viz_rmax = next_rmax;
|
||||
|
||||
notice_all_mons(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user