mimic feedback tuning

When a mimic in door form is hit by a wand of locking or wand of
opening or corresponding spell, bring it out of concealment like
was recently done for being zapped while in chest form.  And give
some feedback rather than just changing the mimic's form to 'm'.

Give more detailed feedback when bumping into a mimic while moving.
This commit is contained in:
PatR
2024-12-02 11:37:04 -08:00
parent 86679ebddb
commit 1301234039
3 changed files with 47 additions and 30 deletions

View File

@@ -3350,6 +3350,7 @@ extern boolean mhitm_knockback(struct monst *, struct monst *,struct attack *,
extern int passive(struct monst *, struct obj *, boolean, boolean, uchar,
boolean) NONNULLARG1;
extern void passive_obj(struct monst *, struct obj *, struct attack *) NONNULLARG1;
extern void that_is_a_mimic(struct monst *, boolean) NONNULLARG1;
extern void stumble_onto_mimic(struct monst *) NONNULLARG1;
extern int flash_hits_mon(struct monst *, struct obj *) NONNULLARG12;
extern void light_hits_gremlin(struct monst *, int) NONNULLARG1;

View File

@@ -6032,20 +6032,17 @@ passive_obj(
DISABLE_WARNING_FORMAT_NONLITERAL
/* Note: caller must ascertain mtmp is mimicking... */
/* used by stuble_onto_mimic() and bhitm() cases WAN_LOCKING, WAN_OPENING */
void
stumble_onto_mimic(struct monst *mtmp)
that_is_a_mimic(
struct monst *mtmp, /* a hidden mimic (nonnull) */
boolean reveal_it) /* True: remove its disguise */
{
static char generic[] = "a monster";
char fmt[QBUFSZ];
char fmtbuf[BUFSZ];
const char *what = NULL;
Strcpy(fmt, "Wait! That's %s!");
if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK)
/* must be adjacent; attack via polearm could be from farther away */
&& m_next2u(mtmp))
set_ustuck(mtmp);
Strcpy(fmtbuf, "Wait! That's %s!");
if (Blind) {
if (!Blind_telepat)
what = generic; /* with default fmt */
@@ -6055,11 +6052,9 @@ stumble_onto_mimic(struct monst *mtmp)
int glyph = levl[u.ux + u.dx][u.uy + u.dy].glyph;
if (glyph_is_cmap(glyph)) {
Sprintf(fmt, "%s %s actually is %%s!",
is_cmap_stairs(glyph) ? "Those" : "That",
defsyms[mtmp->mappearance].explanation);
/* BUG: this will misclassify a paralyzed mimic as sleeping */
what = x_monnam(mtmp, ARTICLE_A, "sleeping", 0, FALSE);
/* note: defsyms[stairs] yields singular "staircase {up|down}" */
Snprintf(fmtbuf, sizeof fmtbuf, "That %s actually is %%s!",
defsyms[mtmp->mappearance].explanation);
} else if (glyph_is_object(glyph)) {
boolean fakeobj;
const char *otmp_name;
@@ -6068,9 +6063,9 @@ stumble_onto_mimic(struct monst *mtmp)
fakeobj = object_from_map(glyph, mtmp->mx, mtmp->my, &otmp);
otmp_name = (otmp && otmp->otyp != STRANGE_OBJECT)
? simpleonames(otmp) : "strange object";
Sprintf(fmt, "%s %s %s %%s!",
otmp && is_plural(otmp) ? "Those" : "That",
otmp_name, otmp ? otense(otmp, "are") : "is");
Snprintf(fmtbuf, sizeof fmtbuf, "%s %s %s %%s!",
(otmp && is_plural(otmp)) ? "Those" : "That",
otmp_name, otmp ? otense(otmp, "are") : "is");
if (fakeobj && otmp) {
otmp->where = OBJ_FREE; /* object_from_map set to OBJ_FLOOR */
dealloc_obj(otmp);
@@ -6090,8 +6085,25 @@ stumble_onto_mimic(struct monst *mtmp)
else
what = a_monnam(mtmp);
}
if (what)
pline(fmt, what);
pline(fmtbuf, what);
if (reveal_it)
seemimic(mtmp);
}
RESTORE_WARNING_FORMAT_NONLITERAL
/* Note: caller must ascertain mtmp is mimicking... */
void
stumble_onto_mimic(struct monst *mtmp)
{
that_is_a_mimic(mtmp, TRUE);
if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK)
/* must be adjacent; attack via polearm could be from farther away */
&& m_next2u(mtmp))
set_ustuck(mtmp);
wakeup(mtmp, FALSE); /* clears mimicking */
/* if hero is blind, wakeup() won't display the monster even though
@@ -6101,8 +6113,6 @@ stumble_onto_mimic(struct monst *mtmp)
map_invisible(mtmp->mx, mtmp->my);
}
RESTORE_WARNING_FORMAT_NONLITERAL
staticfn void
nohandglow(struct monst *mon)
{

View File

@@ -167,6 +167,15 @@ bhitm(struct monst *mtmp, struct obj *otmp)
struct obj *obj;
boolean disguised_mimic = (mtmp->data->mlet == S_MIMIC
&& M_AP_TYPE(mtmp) != M_AP_NOTHING);
/* box_or_door(): mimic appearances that have locks */
#define box_or_door(monst) \
((M_AP_TYPE(monst) == M_AP_OBJECT \
&& ((monst)->mappearance == CHEST \
|| (monst)->mappearance == LARGE_BOX)) \
|| (M_AP_TYPE(monst) == M_AP_FURNITURE \
/* is_cmap_door() tests S_symbol values, and */ \
/* mon->mappearance for furniture contains one of those */ \
&& is_cmap_door((monst)->mappearance)))
if (engulfing_u(mtmp))
reveal_invis = FALSE;
@@ -355,10 +364,8 @@ bhitm(struct monst *mtmp, struct obj *otmp)
}
case WAN_LOCKING:
case SPE_WIZARD_LOCK:
/* can't use Is_box() here */
if (disguised_mimic && (is_obj_mappear(mtmp, CHEST)
|| is_obj_mappear(mtmp, LARGE_BOX)))
seemimic(mtmp);
if (disguised_mimic && box_or_door(mtmp))
that_is_a_mimic(mtmp, TRUE); /*seemimic()*/
wake = closeholdingtrap(mtmp, &learn_it);
break;
case WAN_PROBING:
@@ -369,9 +376,8 @@ bhitm(struct monst *mtmp, struct obj *otmp)
break;
case WAN_OPENING:
case SPE_KNOCK:
if (disguised_mimic && (is_obj_mappear(mtmp, CHEST)
|| is_obj_mappear(mtmp, LARGE_BOX)))
seemimic(mtmp);
if (disguised_mimic && box_or_door(mtmp))
that_is_a_mimic(mtmp, TRUE); /*seemimic()*/
wake = FALSE; /* don't want immediate counterattack */
if (mtmp == u.ustuck) {
/* zapping either holder/holdee or self [zapyourself()] will
@@ -541,6 +547,7 @@ bhitm(struct monst *mtmp, struct obj *otmp)
if (learn_it)
learnwand(otmp);
return ret;
#undef box_or_door
}
/* hero is held by a monster or engulfed or holding a monster and has zapped
@@ -1768,10 +1775,9 @@ poly_obj(struct obj *obj, int id)
/* Keep chest/box traps and poisoned ammo if we may */
if (obj->otrapped && Is_box(otmp))
otmp->otrapped = TRUE;
otmp->otrapped = 1;
if (obj->opoisoned && is_poisonable(otmp))
otmp->opoisoned = TRUE;
otmp->opoisoned = 1;
if (id == STRANGE_OBJECT && obj->otyp == CORPSE) {
/* turn crocodile corpses into shoes */