github issue #1299 - sleeping mimics
Issue reported by elunna: sleeping mimics can grab the hero, and zapping a concealed mimic with a wand of sleep describes the target as a mimic but doesn't bring it out of concealment. The grab-when-asleep case is reasonable. It's a reflexive counter- attack by a magical creature. And the mimic wakes up in the process. But the mimic wasn't being brought out of concealment. Do that. Unconceal mimics hit by wand of sleep unless already sleeping. Fixes #1299
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 mhitm.c $NHDT-Date: 1698939796 2023/11/02 15:43:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.244 $ */
|
||||
/* NetHack 3.7 mhitm.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.253 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2011. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1209,6 +1209,12 @@ paralyze_monst(struct monst *mon, int amt)
|
||||
int
|
||||
sleep_monst(struct monst *mon, int amt, int how)
|
||||
{
|
||||
/* reveal mimic unless already asleep or paralyzed (won't be 'busy') */
|
||||
if (how >= 0 && !mon->msleeping && !mon->mfrozen
|
||||
&& mon->data->mlet == S_MIMIC && (M_AP_TYPE(mon) == M_AP_FURNITURE
|
||||
|| M_AP_TYPE(mon) == M_AP_OBJECT))
|
||||
seemimic(mon);
|
||||
|
||||
if (resists_sleep(mon) || defended(mon, AD_SLEE)
|
||||
|| (how >= 0 && resist(mon, (char) how, 0, NOTELL))) {
|
||||
shieldeff(mon->mx, mon->my);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 objnam.c $NHDT-Date: 1711809641 2024/03/30 14:40:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.427 $ */
|
||||
/* NetHack 3.7 objnam.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.439 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2011. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -2475,7 +2475,7 @@ static const char wrpsym[] = { WAND_CLASS, RING_CLASS, POTION_CLASS,
|
||||
|
||||
/* return form of the verb (input plural) if xname(otmp) were the subject */
|
||||
char *
|
||||
otense(struct obj* otmp,const char * verb)
|
||||
otense(struct obj *otmp, const char *verb)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
|
||||
13
src/pager.c
13
src/pager.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 pager.c $NHDT-Date: 1724094301 2024/08/19 19:05:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.279 $ */
|
||||
/* NetHack 3.7 pager.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.282 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2018. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -280,7 +280,10 @@ mhidden_description(
|
||||
|
||||
/* extracted from lookat(); also used by namefloorobj() */
|
||||
boolean
|
||||
object_from_map(int glyph, coordxy x, coordxy y, struct obj **obj_p)
|
||||
object_from_map(
|
||||
int glyph,
|
||||
coordxy x, coordxy y,
|
||||
struct obj **obj_p)
|
||||
{
|
||||
boolean fakeobj = FALSE, mimic_obj = FALSE;
|
||||
struct monst *mtmp;
|
||||
@@ -305,8 +308,10 @@ object_from_map(int glyph, coordxy x, coordxy y, struct obj **obj_p)
|
||||
if (!otmp || otmp->otyp != glyphotyp) {
|
||||
/* this used to exclude STRANGE_OBJECT; now caller deals with it */
|
||||
otmp = mksobj(glyphotyp, FALSE, FALSE);
|
||||
if (!otmp)
|
||||
return FALSE;
|
||||
/* even though we pass False for mksobj()'s 'init' arg, corpse-rot,
|
||||
egg-hatch, and figurine-transform timers get initialized */
|
||||
if (otmp->timed)
|
||||
obj_stop_timers(otmp);
|
||||
fakeobj = TRUE;
|
||||
if (otmp->oclass == COIN_CLASS)
|
||||
otmp->quan = 2L; /* to force pluralization */
|
||||
|
||||
40
src/uhitm.c
40
src/uhitm.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 uhitm.c $NHDT-Date: 1713334817 2024/04/17 06:20:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.444 $ */
|
||||
/* NetHack 3.7 uhitm.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.451 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -6030,8 +6030,11 @@ DISABLE_WARNING_FORMAT_NONLITERAL
|
||||
void
|
||||
stumble_onto_mimic(struct monst *mtmp)
|
||||
{
|
||||
const char *fmt = "Wait! That's %s!", *generic = "a monster", *what = 0;
|
||||
static char generic[] = "a monster";
|
||||
char fmt[QBUFSZ];
|
||||
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))
|
||||
@@ -6045,16 +6048,39 @@ stumble_onto_mimic(struct monst *mtmp)
|
||||
} else {
|
||||
int glyph = levl[u.ux + u.dx][u.uy + u.dy].glyph;
|
||||
|
||||
if (glyph_is_cmap(glyph) && (glyph_to_cmap(glyph) == S_hcdoor
|
||||
|| glyph_to_cmap(glyph) == S_vcdoor))
|
||||
fmt = "The door actually was %s!";
|
||||
else if (glyph_is_object(glyph) && glyph_to_obj(glyph) == GOLD_PIECE)
|
||||
fmt = "That gold was %s!";
|
||||
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);
|
||||
} else if (glyph_is_object(glyph)) {
|
||||
boolean fakeobj;
|
||||
const char *otmp_name;
|
||||
struct obj *otmp = NULL;
|
||||
|
||||
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");
|
||||
if (fakeobj && otmp) {
|
||||
otmp->where = OBJ_FREE; /* object_from_map set to OBJ_FLOOR */
|
||||
dealloc_obj(otmp);
|
||||
}
|
||||
}
|
||||
|
||||
/* cloned Wiz starts out mimicking some other monster and
|
||||
might make himself invisible before being revealed */
|
||||
if (mtmp->minvis && !See_invisible)
|
||||
what = generic;
|
||||
else if (mtmp->data->mlet == S_MIMIC
|
||||
&& (M_AP_TYPE(mtmp) == M_AP_OBJECT
|
||||
|| M_AP_TYPE(mtmp) == M_AP_FURNITURE)
|
||||
&& (mtmp->msleeping || mtmp->mfrozen))
|
||||
/* BUG: this will misclassify a paralyzed mimic as sleeping */
|
||||
what = x_monnam(mtmp, ARTICLE_A, "sleeping", 0, FALSE);
|
||||
else
|
||||
what = a_monnam(mtmp);
|
||||
}
|
||||
|
||||
38
src/zap.c
38
src/zap.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 zap.c $NHDT-Date: 1723946858 2024/08/18 02:07:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.542 $ */
|
||||
/* NetHack 3.7 zap.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.551 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -148,7 +148,11 @@ learnwand(struct obj *obj)
|
||||
}
|
||||
}
|
||||
|
||||
/* Routines for IMMEDIATE wands and spells. */
|
||||
/*
|
||||
* Routines for IMMEDIATE wands and spells.
|
||||
* Also RAY or NODIR for wands that are being broken rather than zapped.
|
||||
*/
|
||||
|
||||
/* bhitm: monster mtmp was hit by the effect of wand or spell otmp */
|
||||
int
|
||||
bhitm(struct monst *mtmp, struct obj *otmp)
|
||||
@@ -350,6 +354,10 @@ 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);
|
||||
wake = closeholdingtrap(mtmp, &learn_it);
|
||||
break;
|
||||
case WAN_PROBING:
|
||||
@@ -360,6 +368,9 @@ 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);
|
||||
wake = FALSE; /* don't want immediate counterattack */
|
||||
if (mtmp == u.ustuck) {
|
||||
/* zapping either holder/holdee or self [zapyourself()] will
|
||||
@@ -450,7 +461,8 @@ bhitm(struct monst *mtmp, struct obj *otmp)
|
||||
break;
|
||||
case WAN_SLEEP: /* (broken wand) */
|
||||
/* [wakeup() doesn't rouse victims of temporary sleep,
|
||||
so it's okay to leave `wake' set to TRUE here] */
|
||||
so it's okay to leave `wake' set to TRUE here;
|
||||
revealing concealed mimic is handled by sleep_monst()] */
|
||||
reveal_invis = TRUE;
|
||||
if (sleep_monst(mtmp, d(1 + otmp->spe, 12), WAND_CLASS))
|
||||
slept_monst(mtmp);
|
||||
@@ -458,6 +470,8 @@ bhitm(struct monst *mtmp, struct obj *otmp)
|
||||
learn_it = TRUE;
|
||||
break;
|
||||
case SPE_STONE_TO_FLESH:
|
||||
/* FIXME: mimics disguished as stone furniture or stone object
|
||||
should be taken out of concealment. */
|
||||
if (monsndx(mtmp->data) == PM_STONE_GOLEM) {
|
||||
char *name = Monnam(mtmp);
|
||||
|
||||
@@ -3491,7 +3505,8 @@ exclam(int force)
|
||||
}
|
||||
|
||||
void
|
||||
hit(const char *str, /* zap text or missile name */
|
||||
hit(
|
||||
const char *str, /* zap text or missile name */
|
||||
struct monst *mtmp, /* target; for missile, might be hero */
|
||||
const char *force) /* usually either "." or "!" via exclam() */
|
||||
{
|
||||
@@ -3500,11 +3515,8 @@ hit(const char *str, /* zap text or missile name */
|
||||
&& (cansee(gb.bhitpos.x, gb.bhitpos.y)
|
||||
|| canspotmon(mtmp) || engulfing_u(mtmp))));
|
||||
|
||||
if (!verbosely)
|
||||
pline("%s %s it.", The(str), vtense(str, "hit"));
|
||||
else
|
||||
pline("%s %s %s%s", The(str), vtense(str, "hit"),
|
||||
mon_nam(mtmp), force);
|
||||
pline("%s %s %s%s", The(str), vtense(str, "hit"),
|
||||
verbosely ? mon_nam(mtmp) : "it", force);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4209,7 +4221,8 @@ zhitm(
|
||||
tmp += destroy_items(mon, AD_COLD, orig_dmg);
|
||||
break;
|
||||
case ZT_SLEEP:
|
||||
/* possibly resistance and shield effect handled by sleep_monst() */
|
||||
/* resistance and shield effect and revealing concealed mimic are
|
||||
handled by sleep_monst() */
|
||||
tmp = 0;
|
||||
(void) sleep_monst(mon, d(nd, 25),
|
||||
type == ZT_WAND(ZT_SLEEP) ? WAND_CLASS : '\0');
|
||||
@@ -4576,8 +4589,9 @@ burn_floor_objects(
|
||||
|
||||
/* will zap/spell/breath attack score a hit against armor class `ac'? */
|
||||
staticfn int
|
||||
zap_hit(int ac,
|
||||
int type) /* either hero cast spell type or 0 */
|
||||
zap_hit(
|
||||
int ac,
|
||||
int type) /* either hero cast spell type or 0 */
|
||||
{
|
||||
int chance = rn2(20);
|
||||
int spell_bonus = type ? spell_hit_bonus(type) : 0;
|
||||
|
||||
Reference in New Issue
Block a user