diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 47f0e8f98..8ad6b90d6 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -153,6 +153,8 @@ barbarian and samurai can achieve basic in their special spell's skill scalpel and tsurugi can now split puddings; bashing with darts or arrows can't jumping while punished could leave ball and chain in the wrong place improve Deaf message handling for the minetown watch and shops +issues with Warning when you're adjacent to an undetected hider; clearly you + are aware a monster is present so this causes you to search it out Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index a15251e2c..9b88f9fa2 100644 --- a/include/extern.h +++ b/include/extern.h @@ -256,6 +256,7 @@ E int NDECL(findit); E int NDECL(openit); E boolean FDECL(detecting, (void (*)(int, int, genericptr))); E void FDECL(find_trap, (struct trap *)); +E void NDECL(warnreveal); E int FDECL(dosearch0, (int)); E int NDECL(dosearch); E void NDECL(sokoban_detect); @@ -333,6 +334,7 @@ E int FDECL(zapdir_to_glyph, (int, int, int)); E int FDECL(glyph_at, (XCHAR_P, XCHAR_P)); E void NDECL(set_wall_state); E void FDECL(unset_seenv, (struct rm *, int, int, int, int)); +E int FDECL(warning_of, (struct monst *)); /* ### do.c ### */ diff --git a/src/allmain.c b/src/allmain.c index 737dcf0d5..4aef642c5 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -308,6 +308,8 @@ boolean resuming; if (Searching && multi >= 0) (void) dosearch0(1); + if (Warning) + warnreveal(); dosounds(); do_storms(); gethungry(); diff --git a/src/detect.c b/src/detect.c index c29ad83eb..e2214d20d 100644 --- a/src/detect.c +++ b/src/detect.c @@ -20,6 +20,7 @@ STATIC_DCL int FDECL(detect_obj_traps, (struct obj *, BOOLEAN_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_DCL int FDECL(mfind0, (struct monst *, BOOLEAN_P)); /* Recursively search obj for an object in class oclass and return 1st found */ @@ -1311,6 +1312,57 @@ struct trap *trap; } } +STATIC_OVL int +mfind0(mtmp, via_warning) +struct monst *mtmp; +boolean via_warning; +{ + xchar x = mtmp->mx, + y = mtmp->my; + + if (via_warning && !warning_of(mtmp)) + return -1; + + if (mtmp->m_ap_type) { + seemimic(mtmp); + find: + exercise(A_WIS, TRUE); + if (!canspotmon(mtmp)) { + if (glyph_is_invisible(levl[x][y].glyph)) { + /* found invisible monster in a square + * which already has an 'I' in it. + * Logically, this should still take + * time and lead to a return(1), but + * if we did that the player would keep + * finding the same monster every turn. + */ + return -1; + } else { + You_feel("an unseen monster!"); + map_invisible(x, y); + } + } else if (!sensemon(mtmp)) + You("find %s.", mtmp->mtame + ? y_monnam(mtmp) + : a_monnam(mtmp)); + return 1; + } + if (!canspotmon(mtmp)) { + if (mtmp->mundetected + && (is_hider(mtmp->data) + || mtmp->data->mlet == S_EEL)) + if (via_warning) { + Your("warning senses cause you to take a second %s.", + Blind ? "to check nearby" : "look close by"); + display_nhwindow(WIN_MESSAGE, FALSE); /* flush messages */ + } + mtmp->mundetected = 0; + newsym(x, y); + goto find; + } + return 0; +} + int dosearch0(aflag) register int aflag; /* intrinsic autosearch vs explicit searching */ @@ -1368,38 +1420,12 @@ register int aflag; /* intrinsic autosearch vs explicit searching */ } else { /* Be careful not to find anything in an SCORR or SDOOR */ if ((mtmp = m_at(x, y)) != 0 && !aflag) { - if (mtmp->m_ap_type) { - seemimic(mtmp); - find: - exercise(A_WIS, TRUE); - if (!canspotmon(mtmp)) { - if (glyph_is_invisible(levl[x][y].glyph)) { - /* found invisible monster in a square - * which already has an 'I' in it. - * Logically, this should still take - * time and lead to a return(1), but - * if we did that the player would keep - * finding the same monster every turn. - */ - continue; - } else { - You_feel("an unseen monster!"); - map_invisible(x, y); - } - } else if (!sensemon(mtmp)) - You("find %s.", mtmp->mtame - ? y_monnam(mtmp) - : a_monnam(mtmp)); - return 1; - } - if (!canspotmon(mtmp)) { - if (mtmp->mundetected - && (is_hider(mtmp->data) - || mtmp->data->mlet == S_EEL)) - mtmp->mundetected = 0; - newsym(x, y); - goto find; - } + int mfres = mfind0(mtmp, 0); + + if (mfres == -1) + continue; + else if (mfres > 0) + return mfres; } /* see if an invisible monster has moved--if Blind, @@ -1434,6 +1460,25 @@ dosearch() return dosearch0(0); } +void +warnreveal() +{ + xchar x, y; + struct monst *mtmp; + + for (x = u.ux - 1; x < u.ux + 2; x++) + for (y = u.uy - 1; y < u.uy + 2; y++) { + if (!isok(x, y)) + continue; + if (x == u.ux && y == u.uy) + continue; + + if ((mtmp = m_at(x, y)) != 0 + && warning_of(mtmp) && mtmp->mundetected) + (void) mfind0(mtmp, 1); /* via_warning */ + } +} + /* Pre-map the sokoban levels */ void sokoban_detect() diff --git a/src/display.c b/src/display.c index 09fd943eb..b4970378f 100644 --- a/src/display.c +++ b/src/display.c @@ -466,16 +466,10 @@ display_warning(mon) register struct monst *mon; { int x = mon->mx, y = mon->my; - int wl = (int) (mon->m_lev / 4); int glyph; if (mon_warning(mon)) { - if (wl > WARNCOUNT - 1) - wl = WARNCOUNT - 1; - /* 3.4.1: this really ought to be rn2(WARNCOUNT), but value "0" - isn't handled correctly by the what_is routine so avoid it */ - if (Hallucination) - wl = rn1(WARNCOUNT - 1, 1); + int wl = Hallucination ? rn1(WARNCOUNT - 1, 1) : warning_of(mon); glyph = warning_to_glyph(wl); } else if (MATCH_WARN_OF_MON(mon)) { glyph = mon_to_glyph(mon); @@ -486,6 +480,18 @@ register struct monst *mon; show_glyph(x, y, glyph); } +int +warning_of(mon) +struct monst *mon; +{ + int wl = 0, tmp = 0; + if (mon_warning(mon)) { + tmp = (int) (mon->m_lev / 4); /* match display.h */ + wl = (tmp > WARNCOUNT - 1) ? WARNCOUNT - 1 : tmp; + } + return wl; +} + /* * feel_newsym()